1

I'm trying to understand the rationale behind the wildcard (_) when assigning functions to values. What does it mean? And how does it work?

I'm getting a weird type when I do this:

scala> def maximize(x: Int, y: Int) = if (x > y) x else y
maximize: (x: Int, y: Int)Int

scala> def max = maximize _
max: (Int, Int) => Int

scala> def m = max _
m: () => (Int, Int) => Int

Why did I get () => (Int, Int) => Int for m and what does it mean? A function chain? Can someone clarify for the layman?

Pika Sucar
  • 115
  • 6

2 Answers2

2

"Wildcard" character here is used to convert a method reference into a function object. maximize is a method, that accepts two parameters and returns an Int. maximize _ is a function, accepting to parameters and returning Int. Now, max is a method, that accepts no parameters and returns a function. Then max _ is a function, returning a function . m s a method returning max _, so, it's return type has to be the same: a function returning a function with two parameters, returning an Int.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
Dima
  • 39,570
  • 6
  • 44
  • 70
0

In order to understand the wildcard converting methods to functions (called eta-expansion) we need to understand that Scala views named methods (such as maximize) and functions (all declared as FunctionN in Scala, e.g Function1, Function2, etc) differently. The former doesn't actually have a value type. In the Scala Specification, they are listed under Non Value Types:

The types explained in the following do not denote sets of values, nor do they appear explicitly in programs. They are introduced in this report as the internal types of defined identifiers.

Since named methods don't have a value, Scala uses a convince syntax with the _ wildcard after the named method do convert it to a method value, which is one of the FunctionN family. There also exists implicit conversions when assigning a method to a value:

Method types do not exist as types of values. If a method name is used as a value, its type is implicitly converted to a corresponding function type.

Now that we have that covered, it rather simple to analyze the type you're seeing'

scala> def max = maximize _
max: (Int, Int) => Int

What you've done here is convert maximize from a non value method type to a method value of type Function2, which accepts two Int values and returns an Int.

scala> def m = max _
m: () => (Int, Int) => Int

Now, since max is already a Function2 and we're creating yet another method value, we actually get a Function0[Function2[Int, Int, Int], which is a function that generates yet another function and accepts no arguments and returns the former method.

If you're interested in a more in depth explanation, see Difference between method and function in Scala

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • `_` is not implicit conversion, it's pretty explicit, implicit is when you place method name in a function context. Also there is no such thing as "method value", `_` simply creates `FunctionN` object which calls method from its `apply` method. – Victor Moroz Jun 19 '16 at 02:06
  • @VictorMoroz I didn't mean to add that implicit in front of the conversion, that was a typo. Regarding method values, there is definitely such a thing. See [Scala Specification section 6.7 called "Method Values"](http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#method-values) – Yuval Itzchakov Jun 19 '16 at 07:25
  • You are right about the latter, I forget that Scala is notorious with inventing various terms. Syntactic sugar is called "method value" being in fact something that is usually called function with a closure. – Victor Moroz Jun 19 '16 at 14:00