You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/_docs/reference/contextual/right-associative-extension-methods.md
+39-3
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,22 @@ single explicit term parameter (in other words, `rightParam` is present). In the
36
36
37
37
The Scala compiler pre-processes a right-associative infix operation such as `x +: xs`
38
38
to `xs.+:(x)` if `x` is a pure expression or a call-by-name parameter and to `val y = x; xs.+:(y)` otherwise. This is necessary since a regular right-associative infix method
39
-
is defined in the class of its right operand. To make up for this swap,
39
+
is defined in the class of its right operand.
40
+
41
+
### Natural Order Right-Associative Extension Methods
42
+
If the right-associative extension methods is defined as infix, then the extension is used in its natural order. The `leftParam` is the receiver and
43
+
the `rightParam` is the argument. The order of the parameters is kept consistent with the order of the arguments at call site after desugaring.
44
+
For instance:
45
+
46
+
```scala
47
+
extension [T](xs: List[T])
48
+
infixdef+:: (x: T):List[T] = ...
49
+
50
+
y +:: ys // ys.::y // +::(ys)(y)
51
+
```
52
+
53
+
### Inverted Right-Associative Extension Methods
54
+
To make up for the swap in the order at call site,
40
55
the expansion of right-associative extension methods performs the inverse parameter swap. More precisely, if `rightParam` is present, the total parameter sequence
41
56
of the extension method's expansion is:
42
57
@@ -59,6 +74,27 @@ For instance, the `+::` method above would become
59
74
```
60
75
61
76
This expansion has to be kept in mind when writing right-associative extension
62
-
methods with inter-parameter dependencies.
77
+
methods with inter-parameter dependencies. To avoid this limitation use _natural order right-associative extension methods_.
78
+
79
+
This expansion also introduces some inconsistencies when calling the extension methods in non infix form. The user needs to invert the order of the arguments at call site manually. For instance:
80
+
81
+
```scala
82
+
extension [T](x: T)
83
+
def*:(xs: List[T]):List[T] = ...
84
+
85
+
y.*:(ys) // error when following the parameter definition order
86
+
ys.*:(y)
87
+
88
+
*:(y)(ys) // error when following the parameter definition order
89
+
*:(ys)(y)
90
+
```
63
91
64
-
An overall simpler design could be obtained if right-associative operators could _only_ be defined as extension methods, and would be disallowed as normal methods. In that case neither arguments nor parameters would have to be swapped. Future versions of Scala should strive to achieve this simplification.
92
+
Another limitation of this representation is that it is impossible to pass the
93
+
type parameters of the `def` explicitly. For instance:
94
+
95
+
```scala
96
+
extension (x: Int)
97
+
def*:[T](xs: List[T]):List[T] =???
98
+
99
+
xs.*:[Int](1) // error when trying to set T explicitly
0 commit comments