Underscore in Named Arguments

When you wrote:

 WithUnit(value = _, unit = "cm")

You wanted it to mean:

 x => WithUnit(value = x, unit = "cm")

But if you take a close look at the error message, you'll see that the compiler didn't see it that way, it parsed it as:

 WithUnit(x => value = x, unit = "cm"})

As you can see, the _ is scoped more tightly than you wanted.

_ always picks the tightest non-degenerate scope it can. The scope is determined purely syntactically, during parsing, without regard to types.

By non-degenerate, I mean that the compiler didn't think you meant:

WithUnit(value = x => x, unit = "cm")

Tightest non-degenerate scope means the scope defined by the innermost function parenthesis relative to the underscore. Without such a rule the compiler wouldn't be able to know which _ corresponds to which function when function calls are nested.


Try this:

scala> val withUnits = s map { x => WithUnit(value = x, unit = "cm") }
withUnits: Seq[WithUnit] = List(WithUnit(1.0,cm), WithUnit(2.0,cm), WithUnit(3.0,cm), WithUnit(4.0,cm))

The problem is the usage of the underscore to directly define an anynymous function.

A detailed description is in chapter 8.5. Placeholder syntax in the "Programming in Scala" book.