Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spec: nil, true, false not reserved words #18193

Closed
simen opened this issue Dec 4, 2016 · 16 comments
Closed

spec: nil, true, false not reserved words #18193

simen opened this issue Dec 4, 2016 · 16 comments

Comments

@simen
Copy link

simen commented Dec 4, 2016

What version of Go are you using (go version)?

go1.7.3 darwin/amd64

What operating system and processor architecture are you using (go env)?

$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/simen/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.7.3/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.7.3/libexec/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/_9/2x43ffkj2t13pf5wn5fwnwtc0000gn/T/go-build537154098=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"

What did you do?

https://play.golang.org/p/5dRCQ7TYEB

package main

import "fmt"

func main() {
  nil := "World"
  true := false
  if (true == false) {
    fmt.Printf("Hello, %s!", nil)
  }
}

What did you expect to see?

Expected the code not to compile because it assigns arbitrary values to (what I expected to be) important reserved words.

What did you see instead?

The code works as … unexpected and prints "Hello, World".

I understand these have status as Predeclared identifiers (https://golang.org/ref/spec#Predeclared_identifiers) but question the value of not flagging these as errors immediately.

@minux
Copy link
Member

minux commented Dec 4, 2016 via email

@minux minux closed this as completed Dec 4, 2016
@atombender
Copy link

One of the reason is that we can extend the language by introducing more of these without breaking existing

@minux: Making "nil" a reserved word does not prevent the introduction of future identifiers that are not called "nil", so the explanation doesn't make sense. Certainly, if you were to introduce a new special value today called "foo", for example, you simply couldn't avoid having to make it identifier instead of a reserved word. But "nil" and friends have existed since before the dawn of Go.

Besides, does assigning new values to true, false, nil, iota (all of which have globally destructive effects) even have legitimate use cases? It can be argued that any such assignment is going to lead to Very Bad Things, or at least Pretty Silly And Unexpected Things.

Go is very strict about things like unused imports and unused variables, yet it curiously has no problem with this. At the very least go vet should say something, which it doesn't.

@minux
Copy link
Member

minux commented Dec 4, 2016 via email

@ianlancetaylor
Copy link
Contributor

@atombender Making nil a reserved word would break existing correct Go programs, and would therefore violate the Go 1 guarantee (https://golang.org/doc/go1compat).

@atombender
Copy link

atombender commented Dec 5, 2016 via email

@griesemer
Copy link
Contributor

@atombender The rationale is pretty simple: Only identifiers that must be keywords for syntactic reasons are keywords.

In fact, in the very beginning there was some discussion as to whether things like nil, iota, etc. should be keywords. Eventually we agreed on the rule above which settled it.

@ianlancetaylor
Copy link
Contributor

I'll add that once the language has this concept, it becomes easy to add new predeclared identifiers without breaking existing programs.

@simen
Copy link
Author

simen commented Dec 5, 2016

That's been clearly stated by now, but seeing as the go vet generally very strict and opinionated, it is impossible to grasp why it would not also warn about reassigning nil or bona fide boolean literals. I struggle to imagine a situation where that would be intentional and well advised.

@atombender
Copy link

@griesemer: I suggest that the documentation is updated to include the explanation, because it's not obvious to someone who wasn't there. The rationale is unusually unpragmatic compared to Go's other design choices, and also unusually lax for Go, which is otherwise terribly strict and opinioned about so many things.

@griesemer
Copy link
Contributor

@simen It's not impossible to grasp, it's just not been done... :-) And the reason is probably that it's not important to check because it just doesn't happen to be an issue. There's simply more important things to worry about. Also, it's a different issue from this one, so please don't hijack this issue for another subject. This issue is closed. Thanks.

@atombender Feel free to submit a CL for review (perhaps for the FAQ). Also, I respectfully disagree. The rationale is very pragmatic: it's a simple rule that makes it easy to decide what needs to be a keyword and what doesn't; and as @ianlancetaylor has pointed out, it makes it easy to add new predeclared identifiers. Finally, Go is in no way unusual about where it is strict and where not as far as statically typed languages go. The approach chosen for keywords and predeclared identifiers is not new either and has a long history going back at least 40 years of programming language design (Pascal).

@atombender
Copy link

@griesemer But other languages are more strict than Go here; 40 years of programming language design has provided us with unassignable constants for these things.

You can't redefine or reassign nullptr or true in C++, except using macros. Since you mentioned Pascal: FreePascal and ObjectPascal don't allow reassigning true or nil (no idea about other implementations). Same thing in Java and D, I believe. Even Python and Ruby are more strict. From what I can tell it's Go that stands out.

I'll submit a PR if I have time.

@bradfitz
Copy link
Contributor

bradfitz commented Dec 5, 2016

I'll submit a PR if I have time.

A PR isn't the problem. This was a design decision.

@griesemer
Copy link
Contributor

@atombender I'm not surprised about C++... But at least the Python I checked doesn't do anything special:

$ python
Python 2.7.10 (default, Jul 30 2016, 18:31:42) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> x = True
>>> True = False
>>> False = x
>>> True
False
>>> False
True
>>> 

I'm not saying there's isn't languages where this is not the case. But Go is not the only language that made the respective decision.

There's also a question about the wisdom of making these restrictions: It doesn't really prevent people from writing bad code. I could still write var True = false (notice the capital T), and mislead readers. And so forth. Adding restrictions to a language and making it more complicated for a situation that in practice never occurs is in my mind not a good use of resources.

@griesemer
Copy link
Contributor

A FAQ entry may be ok explaining this was simply deliberate and carefully thought out design decision - but there's no need to debate this any further. I'm going to lock this issue.

@atombender
Copy link

@bradfitz I meant PR for the FAQ/docs.

@griesemer Python isn't strict about the booleans (which are just values), but is about None. Ruby is strict about both.

@golang golang locked and limited conversation to collaborators Dec 5, 2016
@griesemer
Copy link
Contributor

@atombender Thanks for the clarification. We did discuss making nil a reserved word, but the regularity of the rule mentioned above trumped the irregularity for nil. (The reason was - if I remember correctly - that if one changed nil one couldn't recreate it from whole cloth. On the other hand, if somebody at the top-level changed true and false, one would always be able to re-create them, say via 0==0 and 0!=0. That said, nobody is going to do this in practice.)

@ALTree ALTree changed the title nil, true, false not reserved words spec: nil, true, false not reserved words May 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants