4 ms·
> That enforced error handling is novel to Rust afaik Hardly, though Rust of course has merit in making it popular, to the point that people think it was intro
by andrenth 5y ago
> That enforced error handling is novel to Rust afaik
Hardly, though Rust of course has merit in making it popular, to the point that people think it was introduced by the language.
- OJFord 5y agoWell that's why I said as far as I know. What else has something similar?
- content_sesh 5y agoHaskell's Maybe type (monad?) comes to mind.
- OJFord 5y agoThat's true, it's a while since I did only a little bit of Haskell, but yes. I suppose I didn't think of it because it feels less like 'having to handle' it in Haskell, since that's the norm anyway. Whereas if you compare Rust to Python, C(++), or Go as I was - having to consume a returned 'result' is more notable.
- monocasa 5y agoAnything with ADTs. I know it from the ML family of languages (Ocaml, Standard ML, F#, etc.)
- OJFord 5y ago> Anything with ADTs. Well that's not true, that's completely orthogonal?
- monocasa 5y agoIt's not. "Forced error handling" in Rust (particularly when contrasted with something like Go like we're doing here) is exemplified with the Option and Result types, and how the compiler will maintain type safety around the concepts of success and error. ADTs are what lets it do that, and the MLs do that as well. You can also see this in how Typescript for example uses ADTs for typesafe error/success state space enumeration.
- OJFord 5y agoBut you could have ADTs without using them for 'forced error handling', and you could have 'forced error handling' without using ADTs for it - C could require 'consumption' (for a slightly less strict meaning of it) of return values. That's the bit I think is interesting/was new to me. You can't just call `maybe_works();`, you have to explicitly consume its 'result', even if just to propagate the error as `maybe_works()?;`.
- monocasa 5y agoOh, ok. Yeah that in fact does exist in C and C++ the same way as in Rust. Rust doesn't actually by default require you to consume a return value; a lot of functions are just marked as #[must_use]. C and C++ do the same thing with [[nodiscard]] and __attribute__((warn_unused_result)). There's a go vet pass as well. https://pkg.go.dev/github.com/golangci/govet#hdr-Unused_result_of_certain_function_calls https://pkg.go.dev/github.com/golangci/govet#hdr-Unused_resu...
- ttymck 5y agoNo, not really, it's an accurate summation of where the pattern is commonly found. ADTs, like Rust's Enum, enable this kind of error handling, and are made more ergonomic with monad behaviors. Scala's Either[A, B] is another example.
- scns 5y agoYes, but Haskells'/Scalas' Either is abstract while Rusts' Result is specific SFBAP (Sorry For Being A Pedant).
- ttymck 5y agoCan you clarify the distinction between "abstract" and "specific"? Is Scala's Try[A] "specific"?
- scns 5y agoSure. Result is specific, you get a value or an error. Either can be used the same way, but you don't have to. The convention is use Right for the value and Left for the error but you can use it in other ways too, eg Left for an Int and Right for a Float.
- Zababa 5y agoI think one difference between Rust and OCaml is that in Rust non exhaustive pattern matches are an error, while in OCaml they are a warning.