story
- 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
Zig manages to provide traces with very little overhead:
https://ziglang.org/documentation/master/#Error-Return-Trace...
I am baffled as to why error handling in Go remains so impoverished.
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.
However, doing this kind of ... sucks.
See eg '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'.
> 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.
Convenience is not a goal of the language, generally.
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.
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.
[1] https://github.com/SeaQL/sea-orm/blob/64c54f8ad603df0c1d9da8...
In Haskell, 'Maybe (Maybe Int)' is a different type from 'Maybe Int'.
That means that when you use eg a hash table that returns some kind null value like 'Nothing' on lookup when a key is not found, you can still stick exactly that kind of null value as a normal value into the table and everything will turn out fine.
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.