One of the bits of the Go 2 error handling proposal that some people dislike is that the new
check
keyword only works on values of type
error
. I've seen a number of suggestions in the wiki feedback page that widen this, making
check
more generally applicable. I don't have a strong opinion on this, but I do have an observation on the current approach.
One of my firm beliefs is that most programmers are strongly driven to do what their languages make easy. If a language makes something the easiest path to what programmers want, programmers will use that path, even if it's not what the path is really for and even if it requires some contortions. What the language designers feel about this or advocate doesn't really matter; people will not take the hard road just because you want them to and think they should.
In the current Go 2 error handling proposal, using a
check
on an
error
value is the easiest way to check for exceptional conditions. The obvious thing to expect here is that people will increasingly signal exceptional conditions through
error
values, including adding them to APIs where necessary or changing return values from other types (especially
bool
) to
error
instead. The resulting
error
may or may not be meaningful (in some cases it will be a boolean), but it can be used with
check
to make exception handling easy, and that's what a lot of people will care about.
(Some of these APIs will be public, but a lot more will be internal or even the informal 'APIs' of internal functions and methods inside a package.)
Whether or not this is a good thing probably depends on your perspective. On the one hand, we're likely to see a lot more use of
error
rather than people making up their own error mechanisms. On the other hand, some of those uses of
error
will not be for actual errors and the
error
values won't be particularly meaningful. Some of them will really be booleans, where the only thing that matters is whether the value is
nil
or non-
nil
. This risks confusing other people who expect the
error
values to have any meaning or use beyond the
nil
check used by
check
.
If people consider this change in
error
usage to be a bad thing, I don't think that there's any way out short of either not implementing error handling or of making
check
more general somehow.
(This is related to my views on the Go 2 error inspection proposal , where I also expect people to do what the proposal makes easiest, whether or not it's what the language designers want.)
Sidebar: A reason to keep
check
restricted to
error
values despite this
An
error
value is a clear signal that this is where you find whether or not something has succeeded (well, mostly, and CGo is an exception that is not really in normal Go APIs ). This means that you can be very confident that checking an
error
for non-nil is a proper activity; you are not accidentally checking something that is not really an error signal. You can't have as much confidence in
bool
values or the like, and therefor there's a higher chance that programmers who are slapping
check
in front of functions that return
bool
are actually making a (tempting) mistake.
You might think that no one would ever make this sort of confusion. I disagree; exactly what is and isn't an error, and how they're signaled, is something that can easily go wrong if you're not working with something that is completely unambiguous. See, for example, how ZFS on Linux accidentally misunderstood an error return in a way that caused a kernel crash .
(In Go, a non-
nil
error
value meaning an error is socially unambiguous, and it would become more so in a world with
check
in it. CGo is an unfortunate forced exception that I don't think anyone likes.)