Skip to content

Commit

Permalink
Add spec for auto-tupling of n-ary functions
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Oct 15, 2018
1 parent 7087a6c commit d91fa07
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
81 changes: 81 additions & 0 deletions docs/docs/reference/auto-parameter-tupling-spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
layout: doc-page
title: "Automatic Tupling of Function Parameters - More Details"
---

### Motivation

Say you have a list of pairs

```scala
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:
```scala
xs.map {
case (x, y) => x + y
}
```
While correct, this is also inconvenient. Instead, automatic tupling of function parameters proposed to be able to write it the following way:

```scala
xs.map {
(x, y) => x + y
}
```
or, equivalently:
```scala
xs.map(_ + _)
```

Generally, a function value with `n > 1` parameters can be 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`.

### Type Checking

Let a function `F` of the form `F = (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`.

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

* `p` comes without a type, i.e. it is a simple identifier or `_`.
* `p` is of the form `x: U` or `_: U` and `T` conforms to `U`.

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.

#### Term addaptation

If the a function
```scala
(p1: T1, ..., pn: Tn) => E
```

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

```scala
(x: TupleN[T1, ..., Tn]) => {
def p1: T1 = x._1
...
def pn: Tn = x._n
E
}
```

### Migration

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

Thought it is possible that someone has written an implicit conversion for `(T1, ..., Tn) => R` into `TupleN[T1, ..., Tn]`
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.

### Reference

For more info see:
* [Issue #897](https://github.com/lampepfl/dotty/issues/897).
4 changes: 3 additions & 1 deletion docs/docs/reference/auto-parameter-tupling.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ function type of the form `((T_1, ..., T_n)) => U`.

### Reference

For more info, see [Issue #897](https://github.com/lampepfl/dotty/issues/897).
For more info see:
* [More details](./auto-parameter-tupling-spec.html)
* [Issue #897](https://github.com/lampepfl/dotty/issues/897).
2 changes: 2 additions & 0 deletions docs/sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ sidebar:
url: docs/reference/implicit-by-name-parameters.html
- title: Auto Parameter Tupling
url: docs/reference/auto-parameter-tupling.html
- title: Auto Parameter Tupling - More Details
url: docs/reference/auto-parameter-tupling-spec.html
- title: Named Type Arguments
url: docs/reference/named-typeargs.html
- title: Erased Terms
Expand Down

0 comments on commit d91fa07

Please sign in to comment.