Skip to content

Commit 58c795a

Browse files
committed
Parameter untupling is not a conversion of functions
1 parent aea38cf commit 58c795a

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

docs/docs/reference/other-new-features/parameter-untupling-spec.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@ is feasible for parameter untupling with the expected type `TupleN[T1, ..., Tn]
7777
with the same expected type.
7878
## Migration
7979

80-
Code like this could not be written before, hence the new notation would not be ambiguous after adoption.
80+
Code like this could not be written before, hence the new notation is not ambiguous after adoption.
8181

82-
Though it is possible that someone has written an implicit conversion form `(T1, ..., Tn) => R` to `TupleN[T1, ..., Tn] => R`
83-
for some `n`. This change could be detected and fixed by [`Scalafix`](https://scalacenter.github.io/scalafix/). Furthermore, such conversion would probably
84-
be doing the same translation (semantically) but in a less efficient way.
82+
It is possible that someone has written an implicit conversion from `(T1, ..., Tn) => R` to `TupleN[T1, ..., Tn] => R` for some `n`.
83+
Such a conversion is now only useful for general conversions of function values, when parameter untupling is not applicable.
84+
Some care is required to implement the conversion efficiently.
85+
Obsolete conversions could be detected and fixed by [`Scalafix`](https://scalacenter.github.io/scalafix/).
8586

8687
## Reference
8788

docs/docs/reference/other-new-features/parameter-untupling.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,42 @@ or, equivalently:
3333
```scala
3434
xs.map(_ + _)
3535
```
36+
and
37+
```scala
38+
def combine(i: Int, j: Int) = i + j
39+
xs.map(combine)
40+
```
3641

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

46+
More specifically, the adaptation is applied to the mismatching formal
47+
parameter list. In particular, the adaptation is not a conversion
48+
between function types. That is why the following is not accepted:
49+
50+
```scala
51+
val combiner: (Int, Int) => Int = _ + _
52+
xs.map(combiner) // Type Mismatch
53+
```
54+
55+
The function value must be explicitly tupled, rather than the parameters untupled:
56+
```scala
57+
xs.map(combiner.tupled)
58+
```
59+
60+
A conversion may be provided in user code:
61+
62+
```scala
63+
import scala.language.implicitConversions
64+
transparent inline implicit def `fallback untupling`(f: (Int, Int) => Int): ((Int, Int)) => Int =
65+
p => f(p._1, p._2) // use specialized apply instead of unspecialized `tupled`
66+
xs.map(combiner)
67+
```
68+
69+
Parameter untupling is attempted before conversions are applied, so that a conversion in scope
70+
cannot subvert untupling.
71+
4172
## Reference
4273

4374
For more information see:

0 commit comments

Comments
 (0)