4 ms·
One sad aspect is the ? operator. In the beginning, Rust thought it could get away with explicitly handled return codes, without having support for direct style
by catern 5y ago
One sad aspect is the ? operator. In the beginning, Rust thought it could get away with explicitly handled return codes, without having support for direct style/exceptional error handling. But they've ended up with that in the end. If Rust had just used checked exceptions from the start (or equivalently if they had do-notation) they wouldn't have this lingering syntactic noise. Hindsight is 20/20 though - it would have been hard to convincingly predict that Rust would eventually end up with checked-exceptions-plus-syntactic-noise as its error handling paradigm - the experiment had to be carried out to see that it would end up like this. (Now, of course, exceptions have been thoroughly vindicated, and it would be silly to design a new language with explicitly handled return codes instead of checked exceptions)
- zozbot234 5y ago? is not "syntactic noise". Having an indication in the code of which operations might throw is very useful, and it enables a further simplification of using ordinary variant records as opposed to a special-cased "checked exception" construct.
- catern 5y agoCompare it to unsafe functions. An unsafe function can be called in an unsafe block or an unsafe function. Rust could require annotating each call to an unsafe function, even inside unsafe functions. Why don't we do that? That seems like it's also very useful for the exact same reasons. A proper language needs to allow the programmer to choose between implicit effects and explicit effects on a case-by-case basis. The reason ? is so tragic is because Rust tried to go with explicit effects only, but found that people wanted implicit effects, and ? is the closest that Rust can get. That's why it's syntactic noise: The programmer wants to get rid of it, they don't regard it as informative for this case, but they can't get rid of it. (And checked exceptions can be perfectly well implemented with regular data, you don't need any special cases - in fact, you can do it with the same infrastructure that's already been added in a special-cased form for async/await support...)
- GolDDranks 5y agoDidn't downvote you because I presume you are arguing in good faith, but I have very different opinion about the ? operator, it is one of the best syntactic things in Rust. In my experience, many Rustaceans agree. It's a minimal nuisance, while still being explicit in a good way. Also, being able to call unsafe code inside unsafe functions is now considered a design mistake, and there is ongoing work to revert the default – requiring unsafe blocks even in unsafe functions: https://rust-lang.github.io/rfcs/2585-unsafe-block-in-unsafe-fn.html https://rust-lang.github.io/rfcs/2585-unsafe-block-in-unsafe...
- drran 5y agoBut `foo()?"A context message for a human".bar();` is even better. Currently, we must use anyhow's `foo().context("Message")?.bar()` [1] for that. [1]: https://docs.rs/anyhow/1.0.42/anyhow/trait.Context.html https://docs.rs/anyhow/1.0.42/anyhow/trait.Context.html
- p4lindromica 5y agoThe compiler does have a lint to force being explicit about unsafe in the way you describe. It is an allow by default lint called `unsafe_op_in_unsafe_fn`.
- nightcracker 5y agoYou are completely wrong about ? in my opinion. Between it, built-in load carrying tagged enums (also known as sum types) and the built-in Result and Option types, they essentially solve the exception problem while still being entirely explicit. It's probably my favourite feature of Rust.