Repository navigation
proposal: spec: binary integer literals #19308
Description
Currently, Go supports octal and hexadecimal integer literals in addition to the standard decimal literals you'd expect. In an effort to round out this group, I propose adding binary integer literals as well. They would come in the form as a new prefix to integer literals: 0b or 0B.
Initial Disclaimer
This was my first dive into the Go source code and primarily a learning experience for me to get my feet wet submitting changes and what-not. That being said, I appreciate any and all criticism, comments, and suggestions.
The "Why": Prior Art
Binary literals exist or have appeared in mainstream languages as well, including:
All of the above cases have settled on a convention of using 0b or 0B to prefix binary literals, suggesting that this would be a fairly comfortable and sensible choice for Go as well, avoiding needless invention and providing similarity for programmers coming from these other aforementioned languages.
The "Why": Continued
I managed to find some earlier discussions relating to this, albeit this was after I had already implemented the feature and it has more to do with changing the octal syntax than specifically relating to binary literals. But #12711 (comment) from @griesemer does mention that "both the 'o' for octal and 'b' for binary notation were also discussed in the design of Go. It's simply not enough bang for the buck." However, I don't see this as a good argument against adding something so simple to the language. Especially considering the fact that nowadays more and more languages have adopted the syntax for binary literals, it seems the earlier Go design decisions might need to be looked at under new light.
Example usage
const (
SOME_MASK = 0b00001111
SOME_FLAG_A = 0b00000001
SOME_FLAG_B = 0b00000010
SOME_FLAG_C = 0b00000100
SOME_FLAG_D = 0b00001000
)Implementation
As I stated this was more of a learning experience for me, I already have changes that implement this feature ready:
CL-37502 spec: specify syntax for binary integer literals
CL-37503 cmd/compile/internal/syntax: scan binary literals
CL-37504 go/scanner: scan binary integer literals
CL-37505 strconv: support parsing binary integer literals
CL-37506 test: extend int_lit with binary literal usages
Activity
griesemer commentedon Feb 27, 2017
This has come up before. There is a significant amount of work involved in rolling this out, making the compiler and spec changes is trivial. But there's a lot of libraries that should also be made consistent (strconv, math/big, etc.).
If we make a change in this direction, it should be more thorough and support arbitrary bases. I am against this as is.
EddieRingle commentedon Feb 27, 2017
@griesemer Yes, the changes I'm about to submit also modifies
strconv(to my understanding, it's actually required to support this change).EddieRingle commentedon Feb 27, 2017
@griesemer I disagree however that any change should support arbitrary bases or otherwise no change be made at all. From prior reading, it sounds like that would be a good goal for Go2; this is simply polishing Go1 with syntax developers of other languages might expect when using Go. (i.e. Base-2 is a common enough case, probably more common than octal; base-14 or what-have-you is less-so.)
gopherbot commentedon Feb 27, 2017
CL https://golang.org/cl/37503 mentions this issue.
gopherbot commentedon Feb 27, 2017
CL https://golang.org/cl/37504 mentions this issue.
gopherbot commentedon Feb 27, 2017
CL https://golang.org/cl/37502 mentions this issue.
gopherbot commentedon Feb 27, 2017
CL https://golang.org/cl/37505 mentions this issue.
gopherbot commentedon Feb 27, 2017
CL https://golang.org/cl/37506 mentions this issue.
ALTree commentedon Feb 27, 2017
It's not a particularly strong argument in favour of adding them, either.
IMHO you'll need to expand the "why" section explaining exactly what advantages supporting binary literals will bring to people writing go code.
I don't find them particularly useful; hex is a much more readable and compact format for literals that have a "bit-level meaning".
You gave an 'usage example', but it's not very compelling. I would write those constants using
0xfs and shifts for the others.griesemer commentedon Feb 27, 2017
@EddieRingle This proposal has not been discussed widely nor has it been accepted. Please do not spam us with code reviews. The Go Team has enough to do with work that's actually important.
It is clear to everybody that adding a simple feature to the language is trivial. It's also clear that plenty of people would like this feature (I myself would have liked it sometime). But that said, just because one can, is not an argument that one should. Any however small and simple addition to a language has long-term costs. If we accept this, it will become even more difficult in the future to have a more general mechanism, and we need to remain backward compatible.
Let's wait and see what other people say before jumping the gun. Thanks.
bradfitz commentedon Feb 27, 2017
Reminder of our no-me-too policy: https://golang.org/wiki/NoMeToo
Opinions without constructive content can be expressed using Github's emoji reactions.
EddieRingle commentedon Feb 27, 2017
@ALTree
I'd argue the opposite, actually. Hex is more compact in many cases, yes, but binary literals would be an exact "bit-level" representation and therefore as readable as you could get.
@griesemer
Apologies. It was originally a single change but since it seems like the Go policy is to break up commits based on the area of codebase affected, that's how I ended up splitting them up. I wasn't aware the bot would make individual comments here for every change. I wouldn't be so cold as to call it spamming you, however, nor imply that any effort I put in using my free time is unimportant.
Like was mentioned before, the general-purpose route (which I would prefer, as well) would also encourage the deprecation/removal of the existing (confusing) octal syntax, no? The feeling I got was that the general-purpose syntax (
2r0010or2x0010for base-2, for example) was invention meant for Go2, where breaking changes would be welcome anyway.Putting a potential Go2 aside, to address the statement that "if we accept this, it will become even more difficult in the future to have a more general mechanism": I just don't see how this is true. Adding the binary literal prefix would be orthogonal to an alternative, general-purpose syntax, especially the one you described in #12711 (in fact, that syntax conflicts directly with hexadecimal literals, but would not with this proposed binary literal syntax). They would exist side-by-side just as the general-purpose syntax would with the existing octal, hex, and decimal literals.
cespare commentedon Feb 27, 2017
It's not just that the bot sends mail about CLs, it's that each mailed CL is a request for a Go reviewer to spend time reviewing it.
115 remaining items
fmt: scan new number syntax
text/template: accept new number syntax
math/big: add %#b and %O integer formats
spec: document new Go2 number literals
gopherbot commentedon Apr 24, 2019
Change https://golang.org/cl/173663 mentions this issue:
unicode/utf8: use binary literalsunicode/utf8: use binary literals
gopherbot commentedon May 2, 2019
Change https://golang.org/cl/174897 mentions this issue:
cmd/compile: disable Go1.13 language features for -lang=go1.12 and belowcmd/compile: disable Go1.13 language features for -lang=go1.12 and below
rsc commentedon May 7, 2019
As a reminder, we introduced a new process for these Go 2-related language changes in our blog post blog.golang.org/go2-here-we-come. The Go 1.13 development cycle is now over and it’s time for the final decision.
The feedback on the Go 2 number literal changes has been strongly positive, with very few negative voices. These changes modernize and harmonize Go’s number literal syntax without adding significant complexity to the language: There is now a uniform prefix notation for the three common non-decimal number bases, which matches the notation used in other modern programming languages. The introduction of hexadecimal floating-point literals addresses a pain point for people concerning themselves with numeric code. The suffix “i” may now be used with any (non-imaginary) number literal to create an imaginary constant in a uniform way. And finally, underscores may be used to split longer literals into groups of digits for improved readability.
Proposal accepted for Go 1.13. Closing because the changes have landed.
- rsc for proposal review
gopherbot commentedon Aug 10, 2019
Change https://golang.org/cl/189718 mentions this issue:
compiler: support new numeric literal syntaxcompiler: support new numeric literal syntax
compiler: support new numeric literal syntax