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
Stack 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.
It 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.
'foldr' is interesting, because it encapsulates a recursive pattern matching on lists. For the non-recursive version, see 'uncons' composed with 'maybe'.
It'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.
If 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.
I 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.
> 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.
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.
Huge no to anything that will require .unwrap() noise everywhere in the codebase. I use Erlang, my code does not have ".unwrap().unwrap()"[1] anywhere.
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.
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.
I don't understand this example at all. A Rust programmer would essentially never use unwrap on the return from File::open. It would be like checking open(2) with assert() in C.
Of 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.
It 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.
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