# Passing a binary function to List[(Int,Int)].map

Let define a list of tuple of integer.

``````val as = List((1, 1), (2, 4), (3, 9))
``````

When creating a binary function variable `f : (Int, Int) => Int`, we cannot pass it directly to `as.map` like this:

``````val f : (Int, Int) => Int = (i, j) => i + j
as.map(f)
/*Error */
1 |as.map(f)
|       ^
|       Found:    (f : (Int, Int) => Int)
|       Required: ((Int, Int)) => Any
``````

This is because the function required for `List[A].map` must be a unary function accepting a type `A` (with signature `def map[B](f: A => B): List[B]`). Here `A` is `(Int, Int)`.

Normally, we need to convert `f` like this:

``````as.map(f.tupled)
/* Output */
val res4: List[Int] = List(2, 6, 12)
``````

So far everything makes sense.

However, if, instead of creating a function variable, we pass a â€śbinaryâ€ť anonymous function to `map` right away, it turns out that doing this produces the same result without the need to converting a function at all:

``````as.map((i, j) => i + j)
/* Output */
val res5: List[Int] = List(2, 6, 12)
``````

What are mechanisms behind this behavior?

I guess that last example was Scala 3? If so, they have added more sugar syntax to improve the ergonomics at the expense of complexity.

Youâ€™re right! I use worksheet that run Scala 3.

This is parameter untupling.

When reading that doc and the â€śmore detailsâ€ť it seems to me that the function value also should work, as it says:

" Generally, a function value with `n > 1` parameters is converted to a pattern-matching closure using `case` if the expected type is a unary function type of the form `((T_1, ..., T_n)) => U`."

So should not this also cover the case of a function value f as in

``````Welcome to Scala 3.1.1 (11.0.13, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> val xs = List((1,2),(3,4))
val xs: List[(Int, Int)] = List((1,2), (3,4))

scala> val f : (Int, Int) => Int = (i, j) => i + j
val f: (Int, Int) => Int = Lambda\$1432/0x00000008007c1840@5b1420f9

scala> xs.map(f)
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |xs.map(f)
|       ^
|       Found:    (f : (Int, Int) => Int)
|       Required: ((Int, Int)) => Any

longer explanation available when compiling with `-explain`
1 error found

scala> xs.map{case (x,y) => f(x,y)}
val res0: List[Int] = List(3, 7)

``````

?

Thereâ€™s some discussion in the SIP. The difference is that for function literals, the function is defined at the usage site and can directly be created in the required unary/tupled shape, thus no unexpected instantiation, whereas a new function would have to be created, perhaps unexpectedly so, for a reference to an existing n-ary function.

Thanks for the pointer @sangamon . So the argument is one of performance: donâ€™t create yet another function object in this case. Well, I think I might have prioritized regularity over performance here, but at least I now know why the behavior is irregular :). All those performance tweaks are a bit strange to a beginner programmer thoughâ€¦

1 Like

The words are

the adaptation is applied to the mismatching formal parameter list. In particular, the adaptation is not a conversion between function types.

I added the â€śuserâ€ť conversion that turns out to be exactly what youâ€™d get if the compiler supported the â€śextraâ€ť adaptation. Itâ€™s efficient because of â€śtransparent inlineâ€ť in Scala 3.

Actually, that page does not make it clear that â€śthis is an efficient conversionâ€ť. I did remove the previous words on the â€śdetailsâ€ť page that suggested it would not be efficient. And actually, I just tried a quick example and I see boxing where there should be none. So maybe the takeaway is, I didnâ€™t become a programmer because I love gotchas.

1 Like

I guess the phrase â€śnot a conversion between function typesâ€ť might leave a few beginners with blank, distant-looking eyes, so perhaps add an example of that â€śnotâ€ť-case?

BTW: You can borrow my blue and yellow T-shirt with â€śMake love not gotchasâ€ť, if you like