Skip to content

Commit ce0f527

Browse files
author
Aggelos Biboudis
authored
Merge pull request #5805 from adriaanm/patch-2
Update eta-expansion-spec.md
2 parents 0eb5167 + 33ee48e commit ce0f527

File tree

1 file changed

+11
-22
lines changed

1 file changed

+11
-22
lines changed

docs/docs/reference/changed-features/eta-expansion-spec.md

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,19 @@ title: "Automatic Eta Expansion - More Details"
66
### Motivation
77

88
Scala maintains a convenient distinction between _methods_ and _functions_.
9-
Methods are part of the definition of a class that can be invoked in objects while functions are complete objects themselves, making them first-class entities. For example they can be assigned in variables.
10-
These two mechanisms are bridged in Scala by a mechanism called _eta-expansion_ in literature also called eta-abstraction).
11-
According to this, methods can be turned into functions.
12-
The intuition behind this, is that if we have a function `f(x)` and we need to pass it around
13-
we can either pass its name `f` or a function `x => f(x)` which expresses the idea that two functions
14-
are equivalent if and only if they give the same result for all arguments.
9+
Methods are part of the definition of a class that can be invoked in objects while functions are complete objects themselves, making them first-class entities. For example, they can be assigned to variables.
10+
These two mechanisms are bridged in Scala by a mechanism called _eta-expansion_ (also called eta-abstraction), which converts a reference to a method into a function. Intuitively, a method `m` can be passed around by turning it into an object: the function `x => m(x)`.
1511

16-
Consequently, the essense of eta-expansion is captured in the following snippet.
17-
Imagine that the `val` is generated by the compiler, when the programmer writes ```f = m```.
18-
The right-hand side is not a function so the compiler performs _automatic eta-expansion_:
12+
In this snippet which assigns a method to a `val`, the compiler will perform _automatic eta-expansion_, as shown in the comment:
1913

2014
```scala
2115
def m(x: Int, y: String) = ???
22-
val f = m // generates val f = (x: Int, y: String) => m(x, y)
16+
val f = m // becomes: val f = (x: Int, y: String) => m(x, y)
2317
```
2418

25-
In Scala, previously, a method reference `m` was converted to a function value
26-
only if the expected type was a function type. If that was not the
27-
case, one had to write `m _` to force the conversion.
19+
In Scala 2, a method reference `m` was converted to a function value only if the expected type was a function type, which means the conversion in the example above would not have been triggered, because `val f` does not have a type ascription. To still get eta-expansion, a shortcut `m _` would force the conversion.
2820

29-
For methods with one or more parameters like in the example above, this restriction has now been
30-
dropped. The syntax `m _` is no longer needed and will be deprecated in the
31-
future.
21+
For methods with one or more parameters like in the example above, this restriction has now been dropped. The syntax `m _` is no longer needed and will be deprecated in the future.
3222

3323
## Automatic eta-expansion and partial application
3424
In the following example `m` can be partially applied to the first two parameters.
@@ -70,17 +60,16 @@ val bar: implicit Double => Float = foo(3) // val bar: implicit Double => Float
7060

7161
## Rules
7262

73-
- If `m` has one or more parameters, we always eta-expand
74-
- If `m` is nullary (i.e. has type `()R`):
63+
- If `m` has an argument list with one or more parameters, we always eta-expand
64+
- If `m` is has an empty argument list (i.e. has type `()R`):
7565
1. If the expected type is of the form `() => T`, we eta expand.
7666
2. If m is defined by Java, or overrides a Java defined method, we insert `()`.
7767
3. Otherwise we issue an error of the form:
78-
Unapplied nullary methods are only converted to functions when a function type is expected.
79-
You need to either apply the method to `()`, or convert it to a function with `() => m()`.
8068

81-
The syntax `m _` is deprecated.
69+
Thus, an unapplied method with an empty argument list is only converted to a function when a function type is expected. It is considered best practice to either explicitly apply the method to `()`, or convert it to a function with `() => m()`.
70+
71+
The method value syntax `m _` is deprecated.
8272

8373
### Reference
8474

8575
For more info, see [PR #2701](https://github.com/lampepfl/dotty/pull/2701).
86-

0 commit comments

Comments
 (0)