4 ms·
I've shown Rust's Result type to folks on occasion because I like it so much. The other aspect I like is the `?` operator, which allows for easier error propaga
by uzername 7y ago
I've shown Rust's Result type to folks on occasion because I like it so much. The other aspect I like is the `?` operator, which allows for easier error propagation.
https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator https://doc.rust-lang.org/book/ch09-02-recoverable-errors-wi...
- 59nadir 7y agoI think propagating null operators, `?`, etc., all become a bit less interesting when you consider that mostly they're just specific implementations of a monadic interface and they could all just be represented like that instead. It doesn't seem sensible to me to try to "fake" monads everywhere and add different operators for different ones when we could just have one interface that describes short-circuiting based on the data type.
- Rusky 7y agoIt's just not that simple: https://twitter.com/withoutboats/status/1027702531361857536?s=19 https://twitter.com/withoutboats/status/1027702531361857536?... Rust doesn't have higher kinded types, every closure has a unique type that implements up to three different traits, and it has imperative control flow structures that don't exist in Haskell, et al. By the time you've solved all these problems, you've moved away from monads to full-blown delimited continuations, one small step away from an effect system. And nobody really knows how to make that work while still providing Rust/C++-like "zero cost abstraction." It might be nice, but it's not at all clear that it would even be "just one interface" anyway.
- 59nadir 7y agoI'm not really talking about what's interesting or cool given a comparatively bad starting position, I'm talking about these language features in their own right. The idea of making special-case operators for what are just monads becomes less interesting in general, regardless where you started. It's certainly neat and practically useful, but it's a symptom more than it's a long-term solution. This wasn't directed at Rust in particular; many languages have these kinds of operators and even more are trying to propose them and I wonder if people just don't see the big picture and/or don't care. You can have a good and productive language without seeing the big picture or maybe realizing too late, but it's not a paragon of good design. It's definitely a design smell to introduce special-cased operators for these things. With that said, I really like Rust and I think it's an excellent language. This particular thing irks me because a lot of the people who'd exalt this kind of feature usually simultaneously argue that monads are somehow not relevant, while not realizing it's contradictory.
- Rusky 7y agoRust isn't "a comparatively bad starting position." Those obstacles I listed are not just cases of "d'oh, if only we had thought of this earlier." They're conscious, intentional design choices to trade off a general monadic interface (and other similar designs) for real benefits in Rust's domain. The people who made these choices, and the people who "exalt" them, thus cannot fairly be described as "just don't see the big picture," "don't care," or "not realizing it's contradictory." And until someone has figured out a way to combine a general monadic interface (or more likely, some other method for orchestrating continuations) with Rust-like zero-cost abstractions, these features continue to be "cool" "in their own right." :)
- 59nadir 7y ago> Rust isn't "a comparatively bad starting position." From the standpoint of "How do we handle things that behave like these things (monads) in a general way?" it's certainly not a good one. It's not that I'm saying that Rust is badly designed overall, but like other languages with these operators it exhibits this particular design smell. It's not really debatable that this kind of special-casing is bad design and lack of foresight or a general lack of caring about this thing in particular. It's also fine not to care about it, just as it's fine to not care about generics if one so chooses. > The people who made these choices, and the people who "exalt" them, thus cannot fairly be described as "just don't see the big picture," "don't care," or "not realizing it's contradictory." And until someone has figured out a way to combine a general monadic interface (or more likely, some other method for orchestrating continuations) with Rust-like zero-cost abstractions, these features continue to be "cool" "in their own right." :) I think you're reading a bit more into this than I intended and I guess that's fair. I don't think it's that big a deal that Rust lacks a way to generalize over this concept, but let's not pretend it's a good thing. At which nth special operator for some variant of this behavior would you consider this to be generally not a great design choice? It's either some N or where you intentionally limit this simply because making a bunch of operators is a silly proposition. Either of those cases mean a failure in design. Is it a major one that matters to everyone? No, but it's a shortcoming. It's fine for languages to make trade-offs and not be perfect in every way, I don't think it's terribly productive to not see obvious shortcomings just because we like something.
- fnord77 7y ago`?` isn't really that great - for all but toy cases you have to jump through hoops - especially if you are trying to handle different error types from separate in a unified way. Not a fan of Result, either - it ties together the error type and the type of the desired item - these should be separate concerns.
- 0815test 7y ago> Not a fan of Result, either - it ties together the error type and the type of the desired item - these should be separate concerns. How so? 'Result' is just a generic variant record with two variant cases, for the "success" and "error" condition. It's the exact same as the `value, err` pattern in Go, except that it additionally enforces proper semantics and handling of the outcome.
- epage 7y ago> `?` isn't really that great - for all but toy cases you have to jump through hoops - especially if you are trying to handle different error types from separate in a unified way. To be clear, that isn't the fault of `?` but that Rust "requires" you to specify your error type. You could just specify `Box<Error>` and go about your day without boiler plate. What you mention and my workaround are two extremes of the solution space. There are Rust crates inbetween that help people handle errors the way they need with minimal boiler plate.