# Parameter Untupling - More Details

### Motivation

Say you have a list of pairs

``````val xs: List[(Int, Int)]
``````

and you want to map `xs` to a list of `Int`s so that each pair of numbers is mapped to their sum. Previously, the best way to do this was with a pattern-matching decomposition:

``````xs.map {
case (x, y) => x + y
}
``````

While correct, this is inconvenient. Instead, we propose to write it the following way:

``````xs.map {
(x, y) => x + y
}
``````

or, equivalently:

``````xs.map(_ + _)
``````

Generally, a function value with `n > 1` parameters can be converted to a function with tupled arguments if the expected type is a unary function type of the form `((T_1, ..., T_n)) => U`.

### Type Checking

Let a function `f` of the form `(p1, ..., pn) => e` for `n != 1`, parameters `p1, ..., pn`, and an expression `e`.

If the expected type of `f` is a fully defined function type or SAM-type that has a single parameter of a subtype of `ProductN[T1, ..., Tn]`, where each type `Ti` fits the corresponding parameter `pi`. Then `f` will conform to the function type `ProductN[T1, ..., Tn] => R`.

A type `Ti` fits a parameter `pi` if one of the following two cases is `true`:

• `pi` comes without a type, i.e. it is a simple identifier or `_`.
• `pi` is of the form `x: Ui` or `_: Ui` and `Ti` conforms to `Ui`.

Auto-tupling composes with eta-expansion. That is an n-ary function generated by eta-expansion can in turn be adapted to the expected type with auto-tupling.

If the a function

``````(p1: T1, ..., pn: Tn) => e
``````

is typed as `ProductN[T1, ..., Tn] => Te`, then it will be transformed to

``````(x: TupleN[T1, ..., Tn]) => {
def p1: T1 = x._1
...
def pn: Tn = x._n
e
}
``````
##### Generic tuples

If we come to support generic tuples, which provide the possibility of having tuples/functions of arities larger than 22 we would need to additionally support generic tuples of the form `T1 *: T2 *: ...`. Translation of such a tuples would use the `apply` method on the tuple to access the elements instead of the `_N` methods of `Product`.

### Migration

Code like this could not be written before, hence the new notation would not be ambigouous after adoption.

Though it is possible that someone has written an implicit conversion form `(T1, ..., Tn) => R` to `TupleN[T1, ..., Tn] => R` for some `n`. This change could be detected and fixed by `Scalafix`. Furthermore, such conversion would probably be doing the same translation (semantically) but in a less efficient way.