"return foo, err" can return 4 kinds of responses:
- foo, nil
- nil, error
- nil, nil
- foo, error
What's the right behavior when the function returns both a result and an error? What's the right behavior when it returns two nils? At best, you make everybody agree to language conventions to prevent that from happening.
In Haskell (or even Swift and Kotlin with their optional types) the compiler guarantees those cases cannot happen. In Go, you just hope they never happen because almost no code handles them.
I code in Go every day. But I can't defend its decision here. I'd much rather have a richer type system where the compiler can guarantee that I'll get an error or a result, but not both or neither.
I think you just treat an error being returned as the value being ignored, which is what 99.9% of go programs do.
As for two nils being returned, I think it's reasonable for a program to run successfully without returning a result. Search for some work to do, return a list of tasks -- if there are none, the list is empty (nil) but there was no problem checking, so there is also no error. I don't see a problem.
As for the compiler checking, try running "func f() (value, error)" like "foo := f()". It blows up. What you do with the error is up to you; all Haskell adds with the Error monad is that it short-circuits to the end of the do {} block with the error value. No different than a Java exception; all of the upsides, all of the downsides.
Regardless, I stand by my original point that if you want to handle runtime errors, Haskell doesn't really add anything over any other language. Semantic has cases that handle errors. So would the program written in any other language.
The author should have just said, "I wrote it in Haskell because I felt like it" instead of making up reasons that simply aren't true.
- foo, nil
- nil, error
- nil, nil
- foo, error
What's the right behavior when the function returns both a result and an error? What's the right behavior when it returns two nils? At best, you make everybody agree to language conventions to prevent that from happening.
In Haskell (or even Swift and Kotlin with their optional types) the compiler guarantees those cases cannot happen. In Go, you just hope they never happen because almost no code handles them.
I code in Go every day. But I can't defend its decision here. I'd much rather have a richer type system where the compiler can guarantee that I'll get an error or a result, but not both or neither.