3

Why did Go creators choose to not treat nil as false? What why did they think it is better to explicitly compare values to nil? Is there a reliable source that would explain why is that is Go? What was their opinion? What was the logic behind this decision?

I'm looking for a historical reference.


E.g.:

f, err := os.Open(name)
if err != nil {
    return err
}

Than to implicitly cast nils to false like in many other languages:

f, err := os.Open(name)
if err {
    return err
}

As of now, the latter would give:

non-bool err (type error) used as if condition
sanmai
  • 29,083
  • 12
  • 64
  • 76
  • 4
    false isn't nil, and by reflexivity of identity, nil isn't false. – hobbs Apr 26 '16 at 02:04
  • 1
    Unfortunately, opinion *is* the only argument here. As you have guessed from that thread, neither option is any better than the other. Indeed, all matters of programming style are *inherently subjective*, and ultimately it is up to the language designers to decide what they should or should not include in a language. It isn't necessarily about personal taste, though; in general the Go authors design the language based around what they feel leads to better code in the general case, even if it means abandoning their personal favorite idioms. – andlabs Apr 26 '16 at 04:58
  • 2
    There's nothing stopping you form doing `type Err bool` and then `func (e Err) Error() { "Im an error" }`. In that case, false is actually an error. Obviously, it's unlikely anyone writes that code. But languages with a truthiness concept implicitly impose some standard meanings behind non-boolean data (0/1 being false/true for example). The Go authors chose to be explicit rather than implicit here probably due to it simplifying the language as well as not wanting surprises in general – David Budworth Apr 26 '16 at 05:09
  • @DavidBudworth do you have a canonical source in regard of their decision? – sanmai Apr 26 '16 at 06:48
  • https://stackoverflow.com/questions/29138591/hiding-nil-values-understanding-why-golang-fails-here – froderik Apr 26 '16 at 06:50
  • @sanmai I do not, I was more drawing conclusions based on other design decisions made by the language creators. – David Budworth Apr 26 '16 at 14:23

2 Answers2

12

Some languages did that and it caused too many problems. It's primarily a violation of principle of least surprise. Some of the problems are:

  • All non-nil values would evaluate to true. A pointer to false boolean value would evaluate to true. All of that would create new and larger set of complications, aka more bugs.
  • Assigning a boolean to nil would be valid. Comparing a boolean to nil would be valid. That creates a semantic confusion. More bugs.
  • Code would be harder to read because it hides the intent. It's impossible to tell from an expression if you want to check a boolean's value or assert "non-nilness" of some other type of variable. More bugs.
  • Omitted operands in comparison operations in expressions would compile fine, making identifying bugs harder. Think about if a == '3' && b { .. } kind of cases where you forget to add the comparison so b always evaluates to true even if it's not what you intend. More and more bugs.

Go people probably thought about it and preferred code with less bugs is better.

There could be a shortcut though just to propagate the error to the caller such as:

require f := os.Open(name)
// if the call returns error, return error 

EDIT: I'm happy to report that Go team is considering a very similar approach to what I suggested, in Go 2. Only they used the keyword check instead:

check f := os.Open(name)
// if the call returns error run the declared error handler 
// which in turn, can return the error or do something else about it.
Sedat Kapanoglu
  • 46,641
  • 25
  • 114
  • 148
1

While I can't find an exact reason in any of the golang documentation or developer discussions, the closest reason is simply that that absence of a value (nil) should not be interpreted as false. This is also in line with the fact that golang is a very opinionated language, and that its authors felt that not casting types when evaluating for true/false would lead to better quality of code.

vogtb
  • 442
  • 2
  • 8