Bring back leading zero for decimal literals (not for octal uses)

I couldn’t believe it when I first encountered this:

  val i  = 01 //Error: Decimal integer literals may not have a leading zero. (Octal syntax is obsolete.)

It is completely understandable that the octal syntax was confusing, but I think it is important for better code alignment in some decimal use-cases:

  val mySeq1 = (0012, 1234, 2536, 9911) 
  val mySeq2 = (2020, 0010, 1111, 9911) 

I propose we bring it back behind a compiler flag, just in case we want to prevent old octal codebases from silently breaking when migrating. For Scala 3, I think all have moved on from octal numbers, so the flag can be removed.

The only reason I can think of to not do this is that a leading ‘0’ is used for other non-base 10 numbers. An example is hexadecimal. It might make parsing Scala more complicated to allow base-10 numbers to begin with an ‘0’.

Oddly, such numbers can have leading zeros! So why not base-10 numbers indeed.

scala> 0x010
res1: Int = 16

A counterargument could be that people coming from other languages in which 0101 means 65 may expect to read and write numeric literals starting with 0 as if they were octal.

Some people know how much of an alignment fanatic I can be, but I don’t think that this looks that bad:

val MagicNumberTable = Array(
  Array( 123, 4512, 5583),
  Array(1294, 4423,  491),
  Array(  23,    1, 1331),
)

I believe when people use a new language, they check for non-trivial semantics. IMHO, leading zero for octal is non-trivial, and not something one might expect as a default from a language. Additionally, as I mentioned, we enable this behind a flag -YleadingZeroDecimals or whatever.

I’d propose or “soronpose” bringing back leading zero with no flag, but warning under -Xlint.

Additionally, with underscore in numeric literals, disable the lint for leading 0_.

val i = 0_12
val j = 2020
val k = 0_01

I’d be willing to update the What are all the uses of underscore in Scala question on stackoverflow.

There’s a PR that demotes the leading zero error to a warning behind a flag. (It might make more sense as an -Xmigration warning, which is what it really is.)

The PR takes either underscore or single quote for numeric literal separator. It’s quite tiresome that there have been several discussions over several years but no action. Martin always says sure go ahead, someone says maybe I’ll PR, then it’s still not a feature. To be fair, Martin has said that if Java didn’t do underscore, he’d never go for it. He’s funny that way.

I also intend to lint lowercase ell for Long as in 1l, as it’s a sentiment everyone can agree on. Oh, it just occurred to me that it should be a scalafix, as it is a bit of lint that one may wish to auto-correct.