Hacker News new | ask | show | jobs
by thejerz 2857 days ago
I've never understood why Go tries so hard to reinvent exceptions. I've read their manifesto, their books, and this new exception syntax, but I'm not convinced the problem they're describing exists; and, even if it does exist, that their implementation solves it.

Exceptions in Ruby, Python, Java, C#, etc. are a tried-and-true paradigm for handling unexpected code paths, with a clear syntax: the only problem with exceptions is that developers don't use them, or don't use them properly, or aren't forced to use them (e.g, checked exceptions, a la Java's throws), all of which can be fixed with compilation rules.

As someone who writes defensive code, and utilizes a lot of exception throwing/handling for 14+ years, Go's lack of a rational exception framework is a big turn off.

4 comments

> a tried-and-true paradigm for handling unexpected code paths, with a clear syntax

Citation needed here. Who seriously has this opinion? There was just a Java/JVM conference on the very topic of how to make exception handling better.

Tried? Yes.

True with a clear syntax? Definitely not.

> the only problem with exceptions is that developers don't use them, or don't use them properly, or aren't forced to use them

Well, that's enough of a rationale for trying some other mechanism, isn't it?

> Exceptions in Ruby, Python, Java, C#, etc. are a tried-and-true paradigm for handling unexpected code paths

the problem is, most errors aren't "unexpected code paths". Trying to open a file whose name is provided by the user, for instance, can fail for several reasons: file does not exist, permission is denied, file is busy, file content is invalid, etc. None of these situations is "unexpected", they are all part of the task being solved.

Now, accessing the first element of an empty list, dereferencing a nil pointer, dealing with a value that has an illegal state, facing a bus error or a stack overflow? Now that sucks, that is unexpected and it should be dealt with some special mechanism. That's where exceptions really shine (and go has panic/recover for those, ahem, exceptional circumstances).

In the Error Values Draft Overview[1], rsc provides another argument against traditional exceptions:

>As a cautionary tale, years ago at Google a program written in an exception-based language was found to be spending all its time generating exceptions. It turned out that a function on a deeply-nested stack was attempting to open each of a fixed list of file paths, to find a configuration file. Each failed open operation threw an exception; the generation of that exception spent a lot of time recording the very deep execution stack; and then the caller discarded all that work and continued around its loop.

[1] https://go.googlesource.com/proposal/+/master/design/go2draf...

There are serious problems with exceptions.

1. It's often not clear which exceptions can be thrown from a function. I don't think many languages force you to list them all. In most languages it is a case of "this function can throw any exception it wants - read the source code (and of all the functions it calls) if you want to know which".

2. Adding context to exceptions is even more verbose than Go's error handling. In the video for this post for example, where they have fmt.Errorf() for each line that might fail you can easily add context like "opening file failed: ..." or "parsing file failed: ...". The equivalent with exceptions is a separate try/catch for every line! I've never seen anyone bother with that.

This seems like a bit of a flaw with the "handler" approach by the way. Rust's map_err() is a bit nicer.

> It's often not clear which exceptions can be thrown from a function

Go 1 failed to solve that as well. "error" as an interface tells me nothing about what could go wrong with a function call. Go 2 is not looking like it will solve it either. I am happy with the proposals, but I know I'm still going to be looking at godocs and be forced to dig into source code to find out what error types actually come back, and hope they don't change from version to version.

I agree with this. It would be great if we didn't have to give up any type safety with error returns. Even still, this is relatively minor when you remember that people write code in JS, Python, Ruby, etc with zero type safety.
This is true. However it is better in one big way - you at least know whether or not it will return an error at all.