golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.86k stars 17.65k forks source link

proposal: Go 2: spec: expand reserved keywords list to include: true, false, nil #25490

Closed andizzle closed 6 years ago

andizzle commented 6 years ago

Should this be allowed? https://play.golang.org/p/_ige_iHPQEn

false := true
nil := false

fmt.Println(false, nil)
meirf commented 6 years ago

That would break Go1 code so this would probably need to wait for Go2, pending approval.

odeke-em commented 6 years ago

@andizzle, true, false are predeclared constants, nil, iota are predeclared identifiers whose values can be created even by programmers so am not sure what the bar for reserving them would and perhaps that might also warrant reserving predeclared types? As @meirf notes this would break current code.

I'll loop in @griesemer for his wisdom

ALTree commented 6 years ago

This is a dup of #18193; which includes an explanation for this design decision.

griesemer commented 6 years ago

If anything, we want to remove keywords if at all possible. Again, see #18193 for the details of the discussion.

If you want to write false := true, go right ahead. There's plenty of ways one can shoot oneself in the foot in any language, and that's also true for Go. The solution is simple: Don't do that!

I'm going to close this as there's zero chance of this getting adopted. It also doesn't solve any real problem.

andizzle commented 6 years ago

@griesemer just want to point out the Python example given in #18193, is no longer the case in Python 3.

Python 3.6.5 (default, Mar 30 2018, 06:41:53)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> False = True
  File "<stdin>", line 1
SyntaxError: can't assign to keyword

Thanks for point out that this is a design decision, that's all I'm looking for.

griesemer commented 6 years ago

@andizzle Thanks for the update. The question really is: Is it worthwhile to add more keywords, which then have to be mentioned in the respective expression grammar, and which have to be explained in the spec, simply to protect against people doing false := true? By making true, false, and nil predeclared constants (or value, for nil), no extra keywords need to be introduced, the expression grammar doesn't need special cases, and the usual scoping rules take care of the rest. It's simpler and gets the job done w/o exceptions.

Or looking from a different angle: If we were to disallow false := true (which could also be done with special handling of those predeclared identifiers, not just with keywords), should we also prevent zero := 1.0 ? And if not, why not? How is it different? (Surely, anyone seeing zero would assume it to be some sort of zero value!). Or what about disallowing the declaration of a local function panic that doesn't panic? Etc.

There's plenty of opportunity for mischief in Go (and any language for that matter) - and these examples are things people don't really do accidentally in the real world. They do these if they want to prove a point or, well, create trouble (for themselves or others). We can't prevent this and thus we don't even try in these cases.

Thanks.

griesemer commented 6 years ago

PS: There's a different design argument that could be made if true, false, and nil were the only predeclared identifiers: Maybe then it would make sense to make them keywords, and then there wouldn't be any notion of predeclared identifiers. But Go has many predeclared identifiers, so adding these three fits right into the design w/o complicating it.

andizzle commented 6 years ago

Agree. If people want to write false := true, let them. To me, this question raised because I naturally assumed this behaviour would be considered as abnormal, or somehow should be illegal because it "looks wrong". But I now see the reason behind this design decision.

This is unlike some cases in other languages where if you don't know about them, you can be tricked. If people deliberately write false := true, then they are looking for trouble.

Thanks again for clarifying this.