5 ms·
The Rust Result type has: - map / map_err - and_then / or_else - unwrap / unwrap_or And countless of other functions making it very practical to chain c
by linkdd 5y ago
The Rust Result type has:
- map / map_err
- and_then / or_else
- unwrap / unwrap_or
And countless of other functions making it very practical to chain computations without having to pattern match anything.
I do the same in Erlang/Elixir.
In Golang, I need to check every function call, and if I want to know where an error come from, I need to wrap it in an errors.New() because no exceptions = no stacktrace
- kbd 5y ago> and if I want to know where an error come from, I need to wrap it in an errors.New() because no exceptions = no stacktrace Zig manages to provide traces with very little overhead: https://ziglang.org/documentation/master/#Error-Return-Traces https://ziglang.org/documentation/master/#Error-Return-Trace... I am baffled as to why error handling in Go remains so impoverished.
- egeozcan 5y agoI don't see why that wouldn't be possible to implement now that the generics are here.
- linkdd 5y agoWhich is exactly why I said: > I cannot wait for the Result monad. Generics make this possible, and will be a huge improvement to Go's error handling. I'm not saying it will solve everything, but it's a huge step nonetheless.
- egeozcan 5y agoI seem to have lost track of how the discussion reached that point, thanks for the clarification.
- xyzzy_plugh 5y agoI think you will find that Go's error handling will not change as much as you suggest. The majority of developers are extremely cautious of generics and found the status quo to be the best balance between readability and conciseness. Convenience is not a goal of the language, generally.
- Aeolun 5y agoIt doesn’t need to be part of the core language. Everyone can make their own monad, or use the one from a library.
- saghm 5y ago> The majority of developers are extremely cautious of generics and found the status quo to be the best balance between readability and conciseness. Most people who use Go have specifically chosen to use it though (or at least sought out opportunities, given that it's not something entrenched like Java being used due to inertia), so yes, most of them are fine with how Go is or they wouldn't be using it in the first place. If Go had generics from the start, I'd imagine most users would be fine with that too due to self-selection.
- eru 5y agoDepends on how generic you want this. In Haskell, you can have functions that work generically over option-types, error-able types, lists, functions, tuples, etc. In Rust, you have to specifically implement functionality for all of these. But eg your 'map' function in Rust still works for all lists, no matter what item type. In Go before this change, you had to write a different map function for each item type that could be in your list. In Haskell, the same 'map' function works for lists, functions, error-able types etc.
- DarylZero 5y agoIn general, you can replace pattern matching with a function that takes one function for each constructor of the sum type. However, doing this kind of ... sucks.
- eru 5y agoIt sucks when you have to use it for everything, but it's a useful enough technique that most Haskell datatypes come with functions that provide exactly this conversion to church encoding. See eg 'maybe' (https://www.stackage.org/haddock/lts-18.18/base-4.14.3.0/Prelude.html#v:maybe https://www.stackage.org/haddock/lts-18.18/base-4.14.3.0/Pre... on stackage) or foldr for lists. 'foldr' is interesting, because it encapsulates a recursive pattern matching on lists. For the non-recursive version, see 'uncons' composed with 'maybe'.
- DarylZero 5y agoIt's probably actually better than pattern matching when there are only two, as in those cases. But even at three, it becomes a mess. And more than three? Yuck.
- eru 5y agoIf your language does currying similar to Haskell, and there's a good order to your constructors / arguments, even with three or more there might be some benefits with partial application.
- johnisgood 5y agoHuge no to anything that will require .unwrap() noise everywhere in the codebase. I use Erlang, my code does not have ".unwrap().unwrap()"[1] anywhere. [1] https://github.com/SeaQL/sea-orm/blob/64c54f8ad603df0c1d9da85ce7b0d9b59dc32fe4/examples/rocket_example/src/main.rs#L56 https://github.com/SeaQL/sea-orm/blob/64c54f8ad603df0c1d9da8...
- imron 5y agoI use rust and my code does not have .unwrap() (and definitely not .unwrap().unwrap()) in it either. That's what the ? operator is for.
- eru 5y agoThe '?' is not a conceptual advance over .unwrap(), it's "just" a major syntactic convenience.
- ComputerGuru 5y agoOf course it is. Unwrap panics on error, while ? bubbles up the error instead. But ? wasn’t introduced to replace unwrap, unwrap was always frowned upon. It instead replaces match and return.
- imron 5y agoIt was always frowned upon, but still ended up everywhere (including lots of documentation and example code) because it was less verbose than the match handling. The ? helped remove that last obstacle.
- TheDong 5y agoThe comparison here is with go. Unwrap would look like: file := os.Open("foo").Unwrap() I'll take that over the current go state of the art: file, err := os.Open("foo") if err != nil { panic(err) } Just like "panic(err)" is used infrequently, "unwrap" would be used infrequently. They're comparable, and for the cases where unwrap is okay (test code, once-off scripts, etc), I'd definitely prefer it to the panic boilerplate.
- preseinger 5y agoChaining computations hides the error control flow path, which negatively impacts readability.
- mariusor 5y agoStack traces exist in go[1], I'm not sure why you consider exceptions to be the only way of getting a stack representation. Not to mention that traditional exception handling advice I've been handed down from the gray beards is to always handle exceptions as early as possible, which is exactly what go forces you to do with their approach. [1] https://pkg.go.dev/runtime/debug#Stack https://pkg.go.dev/runtime/debug#Stack