5 ms·
Well, semicolons have special meaning in Rust. In some contexts, like the last expression in a function or other expression block, if you don't use a semicolon
by JOHN_BONER 12y ago
Well, semicolons have special meaning in Rust. In some contexts, like the last expression in a function or other expression block, if you don't use a semicolon it will return the value that the expression evaluates to. If you do use a semicolon, it won't return that expression's value. This is good, because it lets you avoid writing the "return" keyword all over the place, but it also lets you avoid returning a value with just a single character!
- robert_tweed 12y agoStuff like this is what currently puts me off Rust, in spite of some initial excitement about the potential it has. This is like optimising for the least readable code possible. I imagine it's going to be a nightmare in practise. Developers always seem to be complaining about having to type this or that, when they should be much more concerned with what they have to read! Really, I couldn't care less about typing a few extra characters. I can type pretty fast anyway and usually spend more time thinking than I do typing. What I do care about is being able to tell exactly what some code does by glancing at it, without worrying too much about whether someone wrote = instead of ==. Rust seems to be setting itself up for loads of those kinds of errors by trying to make the syntax terse at the expense of making it readable. I have high hopes for Rust and will reserve judgement until it is stable; from what I've seen it's still in a high state of flux. However for now, I much prefer the KISS approach taken by Go, in spite of a couple of things missing from the language (that will probably get there in the end).
- Dewie 12y ago> Developers always seem to be complaining about having to type this or that, when they should be much more concerned with what they have to read! Or maybe they find terser syntax to be more readable. If verboseness was always more readable, if not necessarily more "writable", than terseness, then no one would have a problem with Java since it has good IDE support, including autocomplete and generation of boilerplate code. But it turns out that it's not just a matter of being lazy typists.
- robert_tweed 12y agoThat is what's known as a straw man argument. Nobody said verbosity always improves readability, just that it's easy to get too terse, just as Java demonstrates it's possible to get too verbose. I'm pretty comfortable writing complex regular expressions, but I don't know many other developers that are and I certainly don't like trying to grok anything longer than about 10-15 characters that I didn't write in the preceding 15 minutes. This is a perfect example of where terseness is fine for simple problems, but it does not scale. I already mentioned Go because it has a pretty terse syntax, but one that is very carefully optimised for readability. One of the things the designers of Go are careful about is not adding too many operators, keywords, or usage rules to the language, which keeps everything nice and simple. Rust OTOH seems to have a metric boatload of operators that work in different ways depending on the specific context. That's a recipe for a ton of cognitive load, which isn't helpful for writing code, but reading suffers even more. I don't yet know enough about Rust to say whether this is as bad as operator overloading in C++. As I said, I will reserve judgement until 1.0 because it's entirely possible things will change drastically before then.
- pcwalton 12y ago> Rust OTOH seems to have a metric boatload of operators that work in different ways depending on the specific context. What operators does Rust have that Go does not? I believe Rust has no more operators than Go.
- robert_tweed 12y agoThis is just my impression based on those tutorials I've looked at so far; I've decided to put off learning it properly until 1.0, whereas I know Go pretty well. IIRC, the move semantics and lifetime annotations were one area that stuck out as pretty heavy on context-specific operators.
- pcwalton 12y agoMove semantics don't have operators; they happen automatically invisible. Lifetime annotations are not part of operators; they're part of types. The only operator is the same as in Go, &.
- sanderjd 12y agoYou should keep an open mind about this until you've written and read a reasonable amount of rust code. Rust isn't the easiest language to write or to grok-at-a-glance, but the semicolon thing is a real red herring. It's a really interesting decision, but it really isn't a big deal in practice. There are always other more at-a-glance clues that you either do or don't want a value.
- chrismorgan 12y agoI came from a primarily-Python background; that the last value in a block is the outcome of the expression seemed to me a gimmick when I first started writing Rust (just under a year ago)—I, as you appear to be doing, only saw it as relevant at the end of a function, thus saving only half a dozen letters. I quickly discovered that it is not a gimmick; the fact that it applies to any expression is marvellously useful in Rust code, with its everything-is-an-expression doctrine. (For a language like Python, without this orientation, it would be just a gimmick.) That the last value in a block is the value of the expression is something that makes a lot of code much more readable, as it frequently obviates the need for additional temporary variables. I was sceptical until I actually used it. Now I’m converted; though I still also like Python’s pure statement-oriented approach in various ways, I prefer Rust’s model.
- comex 12y agoFWIW, I am a big fan of easy to read code (as I frequently need to read other people's code in order to 'audit' it). But like others have said, in real Rust code the ability to mix blocks and expressions does not seem particularly confusing to me, and is used in many places other than the end of a function, in more of a functional style. Here is a representative-ish example: https://github.com/rust-lang/rust/blob/master/src/librustc/middle/typeck/check/regionck.rs#L756 https://github.com/rust-lang/rust/blob/master/src/librustc/m... Personally I think most other things in Rust (namespaces, constant as_slice() unwrap() etc.) are currently too verbose, although I'd say that also impedes readability.
- TheHydroImpulse 12y agolibrustc isn't a very good example of showing, since it's not idiomatic Rust and a mixture of previous iterations.
- bjz_ 12y agoHah, I would caution against looking into the depths of rustc for examples of good examples of rustic code. Many parts of the compiler have changed very little from the original bootstrapping from OCaml, and have only been incrementally updated since then. No doubt it will eventually be cleaned up, but it will be a big effort. I do agree with the rest of your first paragraph though.
- pcwalton 12y ago> This is like optimising for the least readable code possible. I imagine it's going to be a nightmare in practise. We've written hundreds of thousands of lines of Rust and this has never been an issue. The typechecker will catch any misuses of semicolons. > What I do care about is being able to tell exactly what some code does by glancing at it, without worrying too much about whether someone wrote = instead of ==. The typechecker will catch misuses of = versus == as well. So assuming that the code you're looking at passes the typechecker, you don't have to mentally distinguish between = and ==. > However for now, I much prefer the KISS approach taken by Go, in spite of a couple of things missing from the language (that will probably get there in the end). They're different languages. Go does not have memory safety without garbage collection, and will never have it while remaining backwards compatible. But that was an explicit design goal of Rust. That is why Rust has the lifetime and unique pointer support, which allows Rust to support safe low-level programming in a way that wasn't possible before.
- bjz_ 12y agoI thought it was crazy at first, but `;` operator as a statement separator that returns `()`, and an implicit return at the end of a block greatly reduces the need for mutable temporaries and leads to a more functional code style. This is a real win when it comes to code maintenance. I greatly miss it when shifting back to other more statement-driven languages. I would encourage you to try it! > This is like optimising for the least readable code possible. I imagine it's going to be a nightmare in practise. I have pushed a reasonable amount of code to the rust repo, my own libraries, and some to servo, and it has never been an issue, in fact it has been the opposite (proof: https://www.ohloh.net/accounts/bjz https://www.ohloh.net/accounts/bjz and https://github.com/bjz/ https://github.com/bjz/). > What I do care about is being able to tell exactly what some code does by glancing at it, without worrying too much about whether someone wrote = instead of ==. Rust solves this by having assignment expressions always returning `()` from assignment expressions and not having implicit conversions. The issues with `==` vs `=` completely vanish.
- ossreality 12y agoOh fuck me. It's just like people bitching about Go without ever having written a line of it. Rust code is very readable despite this quirk. It's a different language. There are things to learn. Get over it.