4 ms·
Can you elaborate on the major developments in error handling in the last 30 years?
by cle 7y ago
Can you elaborate on the major developments in error handling in the last 30 years?
- tylerhou 7y agoI assume exceptions, the Error/Either monad, and StatusOr.
- cle 7y agoGo's error handling is essentially the same as Error/Either/StatusOr (returning errors as values). Re: exceptions, there are a lot of people, myself included, who do not view exceptions as "advancements", but as setbacks. Magically and suddenly subverting the normal control flow and unwinding the stack in highly concurrent programs (as is expected in Go) is an awful way to do error handling, and you end up having to bypass that mechanism and pass the errors as values across call stacks anyway, so what are you really gaining for all the extra complexity, "implicitness", and cognitive load of doing that?
- apta 7y ago> Go's error handling is essentially the same as Error/Either/StatusOr (returning errors as values). Except that you cannot easily chain calls that return errors, or it isn't really that hard to accidentally ignore errors because of shadowing or overwriting the variable you're storing your errors in. Or the fact that using a union type to represent errors is a strictly superior way, both in terms of usability, as well as correctness. People should just face the fact that returning errors as a product type is a mistake. > Magically and suddenly subverting the normal control flow and unwinding the stack in highly concurrent programs (as is expected in Go)... You may want to see what approaches Akka or Erlang takes here. golang authors just decided to ignore established practices and use clunky approaches to problems that have already been solved.
- cle 7y ago> Except that you cannot easily chain calls that return errors, or it isn't really that hard to accidentally ignore errors because of shadowing or overwriting the variable you're storing your errors in. Or the fact that using a union type to represent errors is a strictly superior way, both in terms of usability, as well as correctness. People should just face the fact that returning errors as a product type is a mistake. These are still essentially the same. Errors are returned as values, with no major difference in runtime semantics. Whether the language supports union types is orthogonal to that. > You may want to see what approaches Akka or Erlang takes here. golang authors just decided to ignore established practices and use clunky approaches to problems that have already been solved. There's not one solution, there are multiple solutions with various tradeoffs. The tradeoffs Go made are congruent with its tenets as a language that values simplicity and low cognitive overhead.
- apta 7y ago> These are still essentially the same. Errors are returned as values, with no major difference in runtime semantics. Whether the language supports union types is orthogonal to that. It's not just about runtime semantics. If it were, then exceptions should perform better than returned error values in the non-error case (which should be the majority of the time anyway). It's also about how code gets written, and more importantly, how code is read. > There's not one solution, there are multiple solutions with various tradeoffs. The tradeoffs Go made are congruent with its tenets as a language that values simplicity and low cognitive overhead. Which in practice, doesn't really show. Simplicity at the language level manifests as longer, more complicated code in real designs, because real life is complicated. It's pushing the load from the language and compiler implementors on to the end user.
- int_19h 7y agoThey're essentially the same, in a sense that if/goto is essentially the same as a loop. In practice, there's a big pragmatic difference. And I have to say, the debate around Go error handling does remind me a fair bit of some of the arguments I've read while researching that ancient debate about structured programming - needless abstraction that we're not even sure is right, it's clearer when it's explicit, language is simpler etc.
- whateveracct 7y agoEncoding Either as a product `(a, error)` instead of a sum `a | error` is a pretty big difference. It becomes even sillier when you have to also signal "not found" with something like `(a, bool, error)` instead of `Found a | NotFound | Error error`
- tylerhou 7y ago> Go's error handling is essentially the same as Error/Either/StatusOr (returning errors as values). Not really, it's very annoying to chain calls which can error. Also, as another commenter mentioned, functions which can potentially fail should return sum types and not product types. Compare: do first <- computeFirst second <- computeSecond return $ f first second and first, err := computeFirst() if err != nil { return nil, err } second, err := computeSecond() if err != nil { return nil, err } return f(first, second), nil Even without do-notation the Haskell is considerably shorter: computeFirst >>= (\first -> computeSecond >>= (\second -> return $ f first second)) Agreed about exceptions, though; I dislike them as well.
- retzkek 7y ago> Even without do-notation the Haskell is considerably shorter This is a great example, not to your point, but to the methodology of Go. You give a verbose Go example, that I expect the vast majority of readers here could understand, even if they've never written a single line of Go, followed by a terse but syntax-heavy Haskell example that I expect relatively few could.
- erik_seaberg 7y agoThe Go version is 78% useless noise trying to hide f(computeFirst(), computeSecond()) which is what a maintainer needs to focus on. We know everything can fail, we don't need to be incessantly reminded of that. If completely inexperienced people can read idiomatic code, that means the idioms don't capture anything tricky that had to be learned the hard way. There's no payoff for getting better with the language.
- int_19h 7y agoThe last example is Haskell without the syntactic sugar. The first example is in Haskell how it's normally written, and it's far clearer than Go.
- zimpenfish 7y agoApologies, I know very little Haskell - does that example mean that `computeSecond` will always be called, even if `computeFirst` failed? If it does, it's not the same as the Go code which will not call `computeSecond` in that case (which might be a requirement - who knows?) I'm also assuming that `f first second` will return (an error monad?) if either of `first` or `second` are (an error monad?) - is that right?
- networkimprov 7y agoHere is a menu of Requirements to Consider for Go 2 Error Handling. The Go team's "Draft Design" (with check/handle keywords) somehow omitted a requirements section... https://gist.github.com/networkimprov/961c9caa2631ad3b95413f7d44a2c98a https://gist.github.com/networkimprov/961c9caa2631ad3b95413f...