The Scala programming language is filled with all kinds of syntax abbreviations that can do a lot to make code clean, concise, and explicit. Typically these are useful and intuitive for someone who is familiar with the core language, but there are some that could be called cryptic, and maybe even deceptive. The following example is provided by the book Programming in Scala during a lesson on Pattern Matching , and the authors may have omitted necessary explanations in previous sections for the reader to make successful attempts at its interpretation:
val withDefault: Option[Int] => Int = {
case Some( x ) => x
case None => 0
}
At first glance, the code looks very much like a variable declaration that collided with a function definition resulting in a new combined entity and some shrapnel (appearing in the form of Int =
). This is actually a function that returns an instance of Int
, which is confirmed by its behavior:
scala> withDefault( Some( 10 ) )
res28: Int = 10
scala> withDefault( None )
res29: Int = 0
So it’s clear that withDefault
is the variable’s name, but is it somehow also the type Option[Int]
? This cannot be, but it is way too close to a variable declaration for comfort. So what’s going on? And if pattern matching is occurring—which it is—where did the match
statement go?
It turns out the above function literal is shorthand for the following:
val withDefault = ( argument: Option[Int] ) => argument match {
case Some( x ) => x
case None => 0
}
This is unambiguous, while the abbreviated version is not: argument
is supplied to the function referenced by the withDefault
variable and then matching attempts are made against the cases Some(x)
and None
with either x
or 0
being returned, depending on the match that is made. It’s also not that much longer, which makes a person wonder why the shorthand version was included in the language at all.
As a final note, the abbreviated form behaves the same as the following function literal, which uses Scala’s Placeholder Syntax to unshroud the argument:
val withDefault: Option[Int] => Int = {
_ match {
case Some( x ) => x
case None => 0
}
}
So the mystery has been solved, and it’s probably safe to say that this is not one of Scala’s better syntax maneuvers. The piece of code shrapnel Int =
is the only oddity that remains, and this is present because the compiler needs the return type to be specified. Why can’t it make this inference in the original function when it was able to do so in the second and more reasonable definition? Fuck if I know. Maybe the compiler needs a token to appear there so that nonsense like => =
doesn’t ever have to be considered valid. Regardless, this sure seems like a lot of trouble to save the programmer from typing a few extra characters on the keyboard.