Skip to content

proposal: different octal base literal representation #12711

Closed
@RomanSaveljev

Description

@RomanSaveljev

Shortly

Proposal is to add an alternative syntax for representing octal literals and deprecate the current syntax in Go 2+. Deprecation is not necessary, but is personally perceived to be inline with Go's idioms

Current syntax: octal_lit = "0" { octal_digit } .
Proposed change: octal_lit = "0o" { octal_digit } .

Background

The idea is directly borrowed from CoffeeScript, where the feature exists to help developers to avoid various typos in their code:

  • Missed x in 0x1234
  • Missed . after 0 in 0.1234
  • Missed . before 0 in .01234
  • Extra leading 0 in decimal literal as in 01234

Personal view on the current syntax

I think that the current syntax for octal literals is outdated and was simply copied from ancestor languages, because the problem it introduced there was not evident. This proposal may very well be rejected on the grounds of Go 1 compatibility promise assesment, but I guess it is good to keep the pressure for a change.

Activity

DisposaBoy

DisposaBoy commented on Sep 22, 2015

@DisposaBoy

I don't have any opinion on this proposal, I'd just like to point out that at least 3 of those 4 points are invalid IMO.

Missed x in 0x1234

If you can miss x, what stops you missing o

Missed . after 0 in 0.1234
Missed . before 0 in .01234

I don't think most real code would even compile if you made this mistake because (presumably) you'd end up passing/assigning that float to an int and vice-versa

Extra leading 0 in decimal literal as in 01234

This one's a little less invalid, but I don't know that I see any benefit here either. I can't remember a time when I've seen such a number that wasn't octal so that kinda rules out copy-paste mistakes. And if you can type that number by mistake, what stops you from typing 11234.

RomanSaveljev

RomanSaveljev commented on Sep 22, 2015

@RomanSaveljev
Author

@DisposaBoy thanks, I realized that I mostly agree with your comments on floating point numbers. There is one more thing though. 072.40 is a perfectly valid floating point number and is equal to 72.40. To me this is again a confusing language decision.

If you can miss x, what stops you missing o

The deprecation of a leading 0 to denote octal (floating-point?) literals will turn it into a compilation error.

And if you can type that number by mistake, what stops you from typing 11234

Nothing would stop me from typing mistyping any number, correct. The proposal is simply about little more help from a compiler here and there.

Please continue giving a constructive feedback. I appreciate your comments

ianlancetaylor

ianlancetaylor commented on Sep 22, 2015

@ianlancetaylor
Contributor

I feel like you are missing a cost/benefit discussion. Changing the language, even in a hypothetical Go 2, carries a cost. The benefit should be something more than personal preference.

I'm not saying that it's impossible to change the language in Go 2, if there is a Go 2. I'm saying that the language should only be changed for good reasons that bring clear benefits.

RomanSaveljev

RomanSaveljev commented on Sep 22, 2015

@RomanSaveljev
Author

That is true. Some cost is implied here (as with any change). It is obvious the effort should weighed against the gains. However, I am in no position to judge on that (speaking from my less than shallow experience with Go).

Any educated input on the matter is more than welcome.

robpike

robpike commented on Sep 22, 2015

@robpike
Contributor

If anything like this is to happen in Go 2, it should be more interesting than this. One possibility is a general way to have literals of arbitrary base, such as 3r012 where 3 is the base (radix), r is the marker, and the digits follow. This form has been used in other languages.

Regardless, I don't believe any change is worthwhile. There is no pressing need for any of this. The current triad is convenient, familiar, and within a tiny fraction of being always enough.

griesemer

griesemer commented on Sep 22, 2015

@griesemer
Contributor

For the historical perspective: The leading-0 notation was not "simply copied from ancestor languages" - this was quite a deliberate decision, with several weeks of on-and-off thinking about it. There was also discussion about a more general notation to support other number bases (2 comes to mind), or arbitrary bases. Eventually we decided to stick with the historic notation, despite its problems for several reasons:

  • C programmers are familiar with it, there are no surprises
  • there was a feeling that ignoring the leading 0 might lead to hard-to-track down errors when existing C code using the 0-notation (file access) would be ported to Go
  • at the time, none of us (Ken, Rob, I) had a better suggestion or felt a strong need for changing it

In retrospect, being afraid of introducing subtle errors was perhaps overly cautious, but we don't really know.

That said, I don't like you suggestion, and fwiw, 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.

If, and that is a big IF, there were such a change, I think it should enable arbitrary number bases with a uniform syntax (I see Rob made just the same point). I have proposed the following notation during the design phase of Go (albeit after we made the decision to stick with the 0x and leading-0 notation):

int_lit = [ radix 'x' ] digit { digit } .
radix = decimal_digit [ decimal_digit ] .
digit = decimal_digit | 'a' | 'A' | 'b' | 'B' | ... 'z' | 'Z' .
decimal_digit = '0' | '1' | ... '9' .

With the following semantics: A leading radix indicates the number base, any value from 2 to 36 is valid. The subsequent digits must be in the range from 0 to radix-1. For instance, 2x101 means (decimal) 5, 8x660 corresponds to our current 0660, 12x106 means (decimal) 150, etc. Additionally, we permit the radix 0 and state that radix 0 is equivalent to radix 16. This permits the common and widely recognized hexadecimal notation 0x1234 as we know it. (This is exactly what Rob suggested above, but with r replaced by x which enables backward-compatibility with our existing hex notation).

The cost of introducing this is probably small if we keep that leading-0 notation as well (it's fully backward-compatible, and it's done in one or 2 places in a compiler's frontend, and its trivial). But the benefit might be even smaller.

RomanSaveljev

RomanSaveljev commented on Sep 22, 2015

@RomanSaveljev
Author

@robpike @griesemer Thank you. I agree with your reasoning. Tthis is also good to know similar thoughts have (had) been sitting in the back of your head.

This proposal is not pressing whatsoever and the least surprise principle must hold. Well, I am happy to see it implemented in a more "interesting" way, or not at all.

added this to the Unplanned milestone on Sep 22, 2015
changed the title [-]Proposal: Enhanced octal base literal representation[/-] [+]proposal: different octal base literal representation[/+] on Oct 19, 2015
rsc

rsc commented on Oct 24, 2015

@rsc
Contributor

I am against this, for the reasons Rob and Robert already gave (which were the reasons we didn't do it in 2009).

General consensus seems against too.

83 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.ProposalProposal-Acceptedv2An incompatible library change

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @bradfitz@rsc@DisposaBoy@RomanSaveljev@ianlancetaylor

        Issue actions

          proposal: different octal base literal representation · Issue #12711 · golang/go