math4tots - 1 year ago 94
Scala Question

# In Scala, what are the rules for making closures with underscores?

At first I had believed that using underscores to make closures (e.g.

`println _`
) were just shorthand for using an arrow (e.g.
`x => println x`
), but I just recently learned that you can also do the following:

``````def f(a: Int, b: Int) = a + 2 * b
List(1, 2, 3).reduce(f _)
``````

Given my past assumptions,
`f _`
looks like a closure that accepts exactly one argument and passes exactly one argument to
`f`
. I assumed it would tell me it couldn't compile because
`f`
expects two arguments, and
`reduce`
should expect a function with two arguments. But it works as if I had written:

``````def f(a: Int, b: Int) = a + 2 * b
List(1, 2, 3).reduce((x, y) => f(x, y))
``````

What is going on here? What are the rules for creating closures with underscores?

Nothing special going on. Method `reduce` takes a function that takes two `Int`s and produces an `Int`, so providing it with an `f` works fine. Note that when you say `f _` that actually expands to `x => f x` (or, in case of two parameters such as here, `(x, y) => f(x, y)`). You can also just provide `f` which will then be used directly, without the extra anonymous function wrapper.

Transforming a method into a function by doing `f _` is called eta-expansion (full disclosure: I wrote that article). Difference is subtle; function is a value, while a method is, well, a method that you invoke upon an object it's defined for, e.g. `myObject.myMethod`. Function can stand alone, be held in collections etc. Defining your method `f` directly as a function would be `val f: (Int, Int) => Int = (a: Int, b: Int) => a + b` or, with type inference, `val f = (a: Int, b: Int) => a + b`.

BTW I don't see how this is a closure.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download