Help understanding _

Can someone help me understand the semantics of _ when creating anonymous functions?

If r has type Iterable[Int],
then I can use r.groupBy(a=>a) and expect it to have type Map[Int, Iterable[Int]].
However _ is not interpreted as the identity function in the following: r.groupBy(_)

val s1 = r.groupBy(a=>a)
val s2 = r.groupBy(_)

s1 has type Map[Int, Iterable[Int]] which is good.
But s2 unfortunately has type ((Int) => K_) => Map[Nothing, Iterable[Int]]

So apparently Scala interprets r.groupBy(_) as the body of the function whose argument is _ rather than considering the argument of groupBy as the identity function.

How does Scala determine the body of the function when I use an _ ?

Scala always expands _ to the nearest enclosing expression, if that makes any sense.

So the following transformations hold:

r.groupBy(_)                ~~>  x => r.groupBy(x)
r.groupBy(_.toString)       ~~>  r.groupBy(x => x.toString)
r.groupBy(foo(_))           ~~>  r.groupBy(x => foo(x))
r.groupBy(bar(foo(_)))      ~~>  r.groupBy(bar(x => foo(x)))
r.groupBy(bar(_.toString))  ~~>  r.groupBy(bar(x => x.toString))

If you want to express a => a differently you could also say r.groupBy(identity).

1 Like

Perhaps r.groupBy((_)) would have worked, but I didn’t try it.

Tried it. Doesn’t work. That being said, I really don’t understand Scala parentheses. :frowning:
In the example r.groupBy(( _ )), isn’t the nearest enclosing expression exactly ( _ ) ?

Of course I agree that r.groupBy(identity) is the best solution. I’m just trying to understand whats happening with the mysterious parens and underscore.