Reputation: 12134
Wasn't sure if I should ask this here or on Programmers, but anyway
In Scala it's possible to write method calls using infix syntax, i.e. omitting dots and parens.
As an example you could do this:
lst foreach println // equivalent to lst.foreach(println)
Naturally one would assume that lst map _.toString
would be evaluated to lst.map(_.toString)
, which is equivalent to lst.map(x$1 => x$1.toString)
But dropping lst map _.toString
into the repl yields a surprising result, it's evaluated as ((x$1) => sList.map(x$1.toString))
causing the method call to malfunction.
So why is that? Why is it that the simple rule of a.f(b)
being equivalent to a f b
no longer applies when writing a f _.b
?
Upvotes: 2
Views: 179
Reputation: 6315
Because the expression is ambiguous.
From Scala's (somewhat outdated) spec P94: http://www.scala-lang.org/docu/files/ScalaReference.pdf
An expression(of syntactic category Expr) may contain embedded underscore symbols
_
at places where identifiers are legal. Such an expression represents an anonymous function where subsequent occurrences of underscores denote successive parameters.
Since lst map _.toString
is a legal expression, it can naturally be evaluated as an anonymous function like (x) => lst.map(x.toString)
.
You can still use infix expression by curly brackets that make Scala compiler evaluate placeholder function first.
scala> val lst = List(1,2,3,4,5)
lst: List[Int] = List(1, 2, 3, 4, 5)
scala> lst map { _.toString }
res43: List[String] = List(1, 2, 3, 4, 5)
Upvotes: 5