Which is also my opinion.
> most often they either exit on exception (which is like
> not catching an exception)
Not really. Exiting on error is an explicit decision that you make, hopefully only in your top-level (func main) scoping block. Letting an exception bubble up to that level without catching it is invisible. > or pass the error up the call stack (the default
> behaviour for an uncaught exception)
The crucial difference, which the Go team takes great pains to elucidate and fans of exceptions never seem to acknowledge, is that by treating the error as a first-order value, you make its propagation up the call stack explicit, in the normal i.e. visible code path. That makes reasoning about your error path a lot easier, and makes producing code that handles errors correctly a lot simpler.The "Eureka" of error handling in Go isn't a massive thing. It's just the reification of the small and important understanding that errors are values, just like anything else.
The thing that some Go fans miss is that it's actually pretty rare (in my own experience, but I've seen a lot of people echo the same thing) to have to deal with an exception. Usually an exception means that the show is over -- at best you'll report it to the user and continue running your main loop if your application is interactive. Or you may retry the operation a certain number of times.
But most of the time you just want to stop the application, or let some upper level deal with it, and those are exactly the default behaviors of exceptions.
With un-checked exception handling code, all I have to do is look for "catches" in the call stack to my function. That code stands out and it's easy to find. With Golang, I have to spend way more energy analyzing every caller in the stack because they all touch my error.
> So, your argument is that - because you actually see
> some code that simply propagates an error, it's easier
> to reason about where the error ends up being handled?
Not just where the error gets handled, but how it flows through the execution path of your code -- but, yes. > That's like saying you'd rather search for a needle in
> a haystack than a needle on a platter.
I'm sorry, but I don't see how this follows at all. > With Golang, I have to spend way more energy analyzing
> every caller in the stack because they all touch my
> error.
Spending time thinking about the error path for all of your code is time well spent, because it's necessary if your code is going to function correctly. Deferring consideration of failure results in dangerous (at best) and/or broken (at worst) systems. I hope this is noncontroversial.In the end I think the problem is that there are two separate classes of programs. The first is where crash on exception is tolerable and even a desired property (or blindly and optimistically continuing). The second is always deal with exceptions and any error no matter how rare and unlikely they are, and attempt to recover and deal with them properly. No one language and standard library can really please both sides.