Issue `object Foo {val 1 = 2}` in scala

I found this scala problem: https://issues.scala-lang.org/browse/SI-4939

It seems we can define a method whose name is a number:

scala> object Foo { val 1 = 2 } defined module Foo 

But we cannot call it:

 scala> Foo.1 <console>:1: error: ';' expected but double literal found. Foo.1 

And we can call it inside the object:

 scala> object O { val 1 = 1; def x = 1 } defined module O scala> Ox res1: Int = 1 

And the error will follow:

 scala> object O { val 1 = 2; def x = 1 } defined module O scala> Ox scala.MatchError: 2 at O$.<init>(<console>:5) at O$.<clinit>(<console>) at .<init>(<console>:7) at .<clinit>(<console>) at RequestResult$.<init>(<console>:9) 

I use scalac -Xprint:typer to view the code, part val 1 = 2 :

 <synthetic> private[this] val x$1: Unit = (2: Int(2) @unchecked) match { case 1 => () } 

It shows that the method name is changed to x$1 and can be called inside this object.

And the solution to this problem: Do not fix

I want to know if there is a reason allowing the number to be the name of the method? Is there any case where we need to use the number method?

+7
source share
4 answers

There is no name " 1 ". val 1 = 2 is an expression for pattern matching, in much the same way val (x,2) = (1,2) binds x to 1 (and will throw a MatchError if the second element was not the same). This allowed, because there is no real reason to add a special case to prohibit it; thus val match pattern works (almost) exactly like match match pattern.

+10
source

There are usually two factors in this decision:

  • Scalac has many errors that have a much higher priority, and resources for fixing errors are limited. This behavior is benign and therefore low priority.

  • There is a long-term cost to any increase in the complexity of a language specification, and the current behavior conforms to the specification. When things begin to acquire a special shell, there may be an avalanche effect.

This is some combination of the two.


Update Here's what seems strange to me:

 val pair = (1, 2) object Foo object Bar val (1, 2) = pair // Pattern matching on constants 1 and 2 val (Foo, Bar) = pair // Pattern matching on stable ids Foo and Bar val (foo, bar) = pair // Binds foo and bar because they are lowercase val 1 = 1 // Pattern matching on constant 1 val Foo = 1 // *Not* pattern matching; binds Foo 

If val 1 = 1 is pattern matching, then why does val Foo = 1 bind Foo , not a pattern?

Update 2. Daniel Sobral noted that this is a special exception, and recently Martin Odersky wrote the same one .

+4
source

Here are a few examples showing how LHS assignment is more than just a name:

 val pair = (1, 2) val (a1, b1) = pair // LHS of the = is a pattern val (1, b2) = pair // okay, b2 is bound the the value 2 val (0, b3) = pair // MatchError, as 0 != 1 val a4 = 1 // okay, a4 is bound to the value 1 val 1 = 1 // okay, but useless, no names are bound val a @ 1 = 1 // well, we can bind a name to a pattern with @ val 1 = 0 // MatchError 
+1
source

As always, you can use backticks to escape the name. I see no problems in supporting such names - either you use them, or they work for you, or they do not work for you, and you do not use them.

0
source

All Articles