views:

221

answers:

3

this works as expected

scala> 3 match { case x:Int => 2*x }
res1: Int = 6

why does this fail?

scala> 3 match { case $x:Int => 2*$x }
:1: error: '=>' expected but ':' found.
       3 match { case $x:Int => 2*$x }
                        ^

scala> 3 match { case `$x`:Int => 2*$x }
:1: error: '=>' expected but ':' found.
       3 match { case `$x`:Int => 2*$x }
                          ^

scala> 3 match { case `$x` : Int => 2*$x }
:1: error: '=>' expected but ':' found.
       3 match { case `$x` : Int => 2*$x }

'$' is supposed to be a valid identifier character, as demonstrated here:

scala> var y = 1
y: Int = 1

scala> var $y = 2
$y: Int = 2

Thanks

+3  A: 

Though legal in identifiers, $ is reserved for use by the compiler. You'll see a lot of $ usage if you call Scala code from Java, for instance.

And, just to make it 100% clear, "reserved" means you can't declare identifiers with it and expect your code to work.

Daniel
is that bug or actually in the Scala spec somewhere?
Alex R
@Alex it is specified.
Daniel
+13  A: 

From "The Scala Language Specification," Chapter 1 ("Lexical Syntax"):

"The ‘$’ character is reserved for compiler-synthesized identifiers. User programs should not define identifiers which contain ‘$’ characters."

So this non-bug is a formal part of the language specification.

Randall Schulz
Thanks. The Scala compiler should at least issue a warning!
Alex R
+5  A: 

Even though it's discouraged, $'s can be written in identifiers. But an identifier starting with a $ does not count as a variable identifier -- only identifiers starting with lower-case letters do. On the other hand a typed pattern id : Type requires a variable identifier in front of the :. That's why the match is rejected.

Martin Odersky
Thanks, that explains why the match/case is one of the only two places where I saw problems with the '$'. Another was in trying to create and pass anonymous functions around (I guess that compiles to a pattern match internally???).
Alex R