6 ms·
The idea that "[u]sing a return as the last line of a function works, but is considered poor style" irks me so much. A lot of what I find appealing about Rust i
by 88e282102ae2e5b 11y ago
The idea that "[u]sing a return as the last line of a function works, but is considered poor style" irks me so much. A lot of what I find appealing about Rust is that it makes so much explicit through its type system, so I don't understand the philosophy behind preferring implicit returns, especially since you could have a scenario where someone hasn't finished writing a function but it still compiles without error.
- pcwalton 11y agoImplicit returns encourage functional style; foo.map(|x| x + 1) is so much nicer than foo.map(|x| { return x + 1; }). Once you have implicit returns in closures, you might as well have them everywhere for consistency.
- veddan 11y agoI think that the "expression-style" return looks good for short and "expression-like" function. Good fn inc(a: u32) -> u32 { a + 1 } fn foo(a: u32, b: u32) -> u32 { let x = a + b; a * x } Bad fn bar(...) -> bool { let mut success = false; let conn = getConnection(); ... if x > y { return false; } else if z < q { success = false; } foo.barify(x, y); ... success } It looks especially bad when the function has multiple early returns, and then the final return looks different.
- Eerie 11y agoSheesh, it's such a little thing. "success" vs "return success;"
- cmrx64 11y agoDoesn't work when you're not returning from a function (ie, EVERY OTHER PLACE a block can appear)
- ewillbefull 11y agoThis could easily be added as a lint to the codebase.
- 88e282102ae2e5b 11y agoWhy "might as well"? Things can be optimal in some places and suboptimal elsewhere.
- lmm 11y agoConsistency is valuable. If some blocks have different rules to other blocks that's a real downside.
- 88e282102ae2e5b 11y agoThat's true, but they're so syntactically different that I can't imagine a scenario where someone is asking whether it's closures or functions that you're supposed to use return statements in.
- Sanddancer 11y agoA foolish consistency is the hobgoblin of little minds. Sometimes a variation in rules allows for more clarity -- one could set their editor to make return a different color, for example, making it easier to glance at program flow. Then again, I'd argue that closures should allow returns too, like they do in C#. I'm an adamant supporter of the explicit camp -- when you have to debug things at 3 in the morning, sometimes that extra little bit of context can make things blindingly obvious.
- pcwalton 11y agoClosures do allow returns in Rust.
- lmm 11y agoI find the way it works in scala very nice - a block is just an expression that evaluates to the last statement in the block, and idiomatic code never uses "return" anywhere. Even e.g. a function definition, you can replace the block with a single expression if it's more convenient. I agree with being explicit but I don't think return actually makes things any more explicit (if you're talking about an editor highlighting, the editor knows which line is the value of the block, with or without a "return") - rather it's just syntactic ceremony. It's surprising how much difference having very low-overhead closures makes - you can make so much of your program simpler, because it's not a problem if a caller needs to make a slight modification to something.
- carterehsmith 11y ago> foo.map(|x| x + 1) is so much nicer than foo.map(|x| { return x + 1; }) "Nicer" is a subjective thing. BTW in the trivial case above one may judge this or that to be nicer, but in a large method, 'return func(a,b,c)' is obvious, whereas looking at 'func(a,b,c)' it is super non-obvious that the value is being returned.
- nbouscal 11y agoIt's not at all non-obvious if you learn the language. It's also not non-obvious if you learn any of the myriad other languages with the same semantics (including popular web languages like Ruby and CoffeeScript).
- jnordwick 11y agocompromise. Make return very short, like a unary colon ":". Then "foo.map(|x| :x+1)" is nice. If that doesn't stand out enough for some people on a line of its own, make your editor render the unary colon line in a very bold color for you.
- eddyb 11y agoThat doesn't solve the fact that blocks and conditional control flow (if/else and match) are expressions and need a way to produce values.
- andresmanz 11y agoThat's what I mean. Why should I even care about stuff like this being "considered poor style" by the creators of Rust? "Poor style" is what doesn't work well for my team and me.
- dragonwriter 11y ago> Why should I even care about stuff like this being "considered poor style" by the creators of Rust? Maybe you are writing code for the Rust standard library, where following the core projects style recommendations would be important for consistency. Maybe you don't want to start from scratch coming up with your own style, and want a decent starting point from which you can vary as your team figures out what does/doesn't work for them. Lots of reasons to have a language project also provide default style recommendations.
- andresmanz 11y agoStyle recommendations are great and if I was writing code for the standard library, I would certainly follow them. But they don't simply recommend their style. "We recommend doing this like that" is very different from "Doing this that way is considered poor style". That sounds like their recommendations were objective facts and you shouldn't do anything else, even if that worked better for you and the majority of other programmers.
- dragonwriter 11y ago> That sounds like their recommendations were objective facts On the one hand, it is an objective fact that it is considered, by the authors, poor style. On the other hand, that it is "considered" anything is an explicit (not merely implicit) statement that it is subjective (and "poor style" -- or good style, for that matter is inherently subjective in any case.) So, characterizing that language as making it sound "like their recommendations are objective facts" seems quite bizarre.
- andresmanz 11y ago
- barosl 11y agoThe most compelling argument I've seen is that you don't explicitly `break` at the final run of a loop, either. An explicit `break` or `return` in the middle of a body can be thought as "abnormal" control flow. Otherwise, normal control flow will take place. As for a function, it would be returning the last expression.