Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
New for loops in Rust (brson.github.com)
41 points by nikomatsakis on April 6, 2012 | hide | past | favorite | 25 comments


I'm going to make a superficial comment and say that "cont" and "ret" are annoying and gratuitous differences. C/C++, Java, Python, JavaScript, and I think Perl/Ruby/Go all use "continue" and "break". It's just pointless to be different in this respect.

A different concept should use different syntax -- and it looks like Rust has several new concepts where they can invent whatever syntax they want. But the same concept should use the same syntax.


> "ret" [is] annoying and gratuitous differences. C/C++, Java, Python, JavaScript, and I think Perl/Ruby/Go all use [...] "break"

`ret` is a non-local return, it's got nothing to do with `break` (which is a local return and the usual" break).

Also, `ret` is in line with the (unfortunate I think) systematic shortening of keywords in Rust: `fn`, `ret`, `mut`, `alt`, ...

And as p4lindromica notes, Ruby's `continue` is called `next`.


I agree. I was noticing that it really read "odd" to me, like someone was trying to be clever and terse. I don't think saving a few keystrokes is worth the decrease in cosmetic appearance/readability. Indeed, I inferred what those keywords meant, but, yuck.


This (my) comment is just noise, but I support the choice of short keywords - it helps in seeing them iconically. It's not the typing, though I think that helps too, but the reading - a long word, you have to /read/. A short sequence of chars is an instantly, right-brain recognized pattern. For that same reason I much prefer '0' to 'NULL' for ptrs in C/C++ to (I'm talking about visually, not type safety).


fwiw, I thought the same when I began work on Rust, but I have since gotten quite used to the shorter keywords. At this point, I can't believe the keywords in other languages are so pointlessly long.

But the truth is that whatever the surface syntax is, one quickly gets used to it. What's more important are the core concepts at work.


ruby uses the next keyword for continue


Ditto for Perl. However Perl uses last instead break.

NB. Since Perl 5.10 it does have continue & break in its given/when (topicalizer) switch block.


C++ and Java iterators use next as well.


Calling next on an iterator and continue in a loop do very different things. C++ iterators use ++ too, but even though ++ and loops are often found together, I would not list ++ and continue as even remotely synonymous.


This looks like a bad design. It means either (a) the semantics of 'ret' inside a lambda function can change depending on the call site (whether it's used inside a for loop or not); (b) that a lambda function passed in from elsewhere can cause your function to return early; or (c) that lambda functions have different syntax rules depending on where they're being defined. All of which seem equally bad!

I hope there's something I've missed. I've been quite impressed by the rest of the language so far & it would be a shame if they got this wrong.


You're missing something. The semantics of `ret` are always consistent: it always returns from out the innermost `fn()` declaration (closures written using the sugared notation `{||...}` do not count as fn declarations, but closures written as `fn() { ... }` do). In cases where this is not possible, a static error is generated.


So what happens if we pass a stack closure containing a ret into another function? For example, what would this code print out:

  fn foo(f: fn()) {
    log(info, "calling f");
    f();
    log(info, "called f");
  }

  fn bar() {
    log(info, "calling foo");
    foo({||
      ret;
    });
    log(info, "called foo");
  }
I'm not clear on whether the ret would return from foo or from bar - or whether it would be a compile error.

BTW thanks for taking the time to reply - I appreciate it!


Tried compiling this myself with a main function that just calls bar(), resulting in a compiler error:

  `ret` in block function


I feel continually obligated to remind people that if there's some aspect of the language that they don't like, they should speak up! :) The devs are always looking for feedback, either on the mailing list, the Github issue tracker, or in #rust on irc.mozilla.org.

That said, perhaps there is something you've missed. I've posted links to the Rust mailing list elsewhere in this thread, could you skim over those and let me know if they address your concerns? Honestly I'm not super-thrilled at this change myself, if only because it makes for loop invocations a bit busier to look at, but I can't say that I fully understand the semantic tradeoffs here.


I wrote up a quick blog post to spell out some of the examples and show how the design aims for a consistent meaning for the `ret` keyword:

http://smallcultfollowing.com/babysteps/blog/2012/04/06/for-...


For anyone who's wondering what the point of all this is, here are the discussions that help to explain the impetus for this change:

https://mail.mozilla.org/pipermail/rust-dev/2012-February/00...

https://mail.mozilla.org/pipermail/rust-dev/2012-March/00149...

https://github.com/mozilla/rust/issues/1619

As far as I remember it has to do with the prior inability to handle non-local returns and the desire to honor Tennent's Correspondence Principle.


Seems a bit...overly complex.

Also, what is the appeal to '::' instead of just '.'

Kill the semicolons with fire


Rust is inspired by C++ which use '::' to access names inside a namespace, here 'vec' and io are module/namespace not object, it's a static lookup.

'.' is still used for object lookup which is dynamic.


Why is there so much sugar?! Can't a keyword just be a keyword?


> Why is there so much sugar?! Can't a keyword just be a keyword?

Statements based on keywords are syntactic sugar. What I'm seeing here in Rust is the complete opposite, building an iteration statement from language built-ins. It does include some sugar in it (and "for" is a special keyword) but the semantics of the construct is based on lambda calculus and other lower level constructs in Rust.

In general, it's better that a language has as little special syntax that cannot be constructed from elementary blocks. The gaps are then bridged by adding a little sugar coating to make programming convenient (for humans) but keeping the core language clear and concise (for interpreters and compilers).

For example, in C, you cannot define your own loop structures and you're stuck with for, do and while (C macros are so crappy that they don't count). Haskell, on the other hand, does not have any special iteration statements in the language core but there's a handful of iteration functions that are regular functions and you are free to define your own. Same thing with Scheme (and other Lisps).


This is more like Splenda, not sugar


My overall impression regarding Rust is that it has an extremely noisy syntax (and I'm a pro {} guy).


> the new for will work on any higher-order function with the appropriate signature

In the end this makes Rust loops look like Ruby loops. May I restate that «widely used programming languages are modified until they resemble Ruby» (https://news.ycombinator.com/item?id=3448277) or CLispScript (https://news.ycombinator.com/item?id=3448826).

What I do not understand of the late "scripting" languages (Dart, Rust) is why they don't just modify Ruby to have a stricter type system and call it done? That or just abandon the scripting mindset and go for more purely functional languages with non-C-like syntaxes like Haskell or OCaml.


Rust is emphatically not a scripting language. It is a systems language with many features drawn from functional languages (e.g. tagged unions for data types, pattern matching, a type class system, type inference) as well as a strong type system with the addition of type states, which are assertions tracked by the compiler. Yes, its syntax is C-like, but I'd assert that it has more in common with OCaml than Dart.

With that in mind, the suggestion that it'd be more worthwhile to strap static types onto Ruby is like looking at engineers designing an aerodynamic, fuel-efficient, high-speed dragster and suggesting they stick a bigger engine in a sedan and call it done. Yes, Rust has adopted a feature superficially similar to Ruby's; that does not mean it wishes to fill the same niche or that Ruby's goals align with Rust's in any significant way.


I didn't downvote you but I guess you are getting some hate for considering rust a scripting language, since it has none of the features traditionally associated with such languages (simple vm or interpreter, dynamic typing, no compile step).

I think you may be confusing it with something else.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: