I recently translated great article — Errors are values by Rob Pike — and we discussed it in our podcast Golangshow (in russian). One thing I was surprised about is that even experienced Go developers sometimes do not understand the core idea of that article.

Looking back, I remember my first impressions when I read it for the first time. It was similar to “It looks like Pike just adds some complexity to what could’ve been solved gracefully with exceptions”. I have never been fond of exceptions, but that’s the first thought I remember. The example in the article was clearly asking for comparison with exceptions’ way to deal with errors and it didn’t look like a winner here.

Still I knew, there must be something more profound in these words — “errors are values”. After all, I was always comfortable with Go errors handling, so I gave some time to myself to absorb the article.

And then I got it.

Go doesn’t want us to treat errors as something different from our main code. Erroneous situation is a first-class citizen in program flow design.

Errors shouldn’t be hidden or ignored in the same way as you don’t hide or ignore any other code. They are part of your logic and code.

Just try to imagine your way of thinking when you deal with usual concepts — values, conditions, loops etc., and apply it to the errors. Errors are the same level entities as the rest of your code. You don’t ignore return values of other types for no reason, right? You don’t ask language to bring special way to handle boolean variables, because “if” is boring. You don’t ask yourself “What should I do, if I don’t know what to do with this slice on this abstraction level?”. You just program the logic you need.

Again, errors are values, and errors’ handling is a normal programming.

Of course, there are always some patterns to deal with errors (like with any other programming conception), but they emerge naturally and fit perfectly in the existing language capabilities.