Why isn’t ‘nil’ treated as ‘false’ in Go?

Another day, another question got downvoted, closed, drawn and quartered by StackOverflow moderators for obscure reasons. So here I am moving my answer here with some more elaboration.

The question was “why did Go creators choose to not treat nil as false?”. I think that it is a great question and can enhance someone’s understanding of certain concepts when explored.

First, we should ask about why references are evaluated to booleans in some languages. I think that comes from the time when C treated almost everything as integers. That meant a boolean type did not exist but there was a shortcut for using an integer variable as an expression to check if its value is zero or not.

int a = 5;
if (a) {
printf("a is non-zero!");
}

That would print “a is non-zero!”. The syntax made the language simpler and lighter. Booleans could be worked around by using integers and macros easily. There was no need to complicate the language. Elegant.

That came with implications, however, because pointers were essentially integers and could be used the same way for “null” checks, like our pseudo-booleans:

char *a = "test";
if (a) {
printf("a is a valid pointer!");
}

This syntax was handy for many scenarios because checking if a pointer was null or not was a quite common task. Developers started using it everywhere. Some programming languages took it to the extreme, like JavaScript which evaluated almost everything to a boolean, regardless how much it made sense.

Like every shortcut, it came with its own set of problems. First, what the expression means isn’t clear. Are we checking validity of a pointer, are we checking a value of a boolean or are we just checking if an integer is zero?

The ambiguity is especially is problematic when you are checking the value of a pointer to a boolean. What if you forget dereferencing it? There is nothing there to remind you of the error.

When you evaluate pointers to booleans, you assign the pointer to a boolean as a side effect. So it becomes a problem when assigning from a pointer to a boolean to a boolean too. Let’s assume Go had that:

a bool = true
b *bool = make(bool, false) // if Go supported this
a = b // should have been "a = *b"

The line would not cause any problems with the compiler and a’s value would still be . This would cause bugs and readability issues.

Similarly, if nil was a boolean value you could compile incorrectly written reference expressions without any errors.

a int = 3
b *bool = make(bool, false) // let's keep imagining
if a == 3 && b {
println("Problem!");
}

The code above would print “problem” incorrectly. The expression should have been , another missed bug.

Go people probably thought fewer bugs were better. I think they were right.

Why do people want this?

Go relies on explicit handling code for errors rather than exceptions. In order to check if a function succeeded or not you have to check if the error return value is nil or not and return early accordingly. So you have to write something like:

result, err := someFunc()
if err != nil {
return err
}

The code gets swamped with these checks. They hurt readability and get cumbersome at some point. I understand why people want a shorter syntax to write them.

Obviously, it would be much better if Go didn’t have this “tuple-like” return values for error propagation. The return value layout can change between functions so it’s impossible to determine a common structure for error propagation. Given the design constraints, they seem to have come up with an optimal solution.

In short, there would be no shorter way to write those error handling code without a nil-boolean shortcut and having such a shortcut would create many problems.

If Go had generics and discriminated unions, some elegant error handling mechanisms could have been devised. Without them, we are bound to the current way of doing things, for good reasons. And yes, we have to explicitly write every time because it makes our code better.

Writing Street Coder (https://www.manning.com/books/street-coder) · Ex-Software Engineer at Microsoft · Founder of eksisozluk.com · Demoscene old-timer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store