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/extension-methods.md
+29-38Lines changed: 29 additions & 38 deletions
Original file line number
Diff line number
Diff line change
@@ -21,14 +21,13 @@ circle.circumference
21
21
22
22
### Translation of Extension Methods
23
23
24
-
Extension methods are methods that have a parameter clause in front of the defined identifier.
25
-
An extension method named `f` translates to the method named `extension_f` that takes the leading parameter section as its first argument list.
26
-
So, the definition of `circumference` above translates to the following method, and can also be invoked as such:
24
+
An extension method translates to a specially labelled method that takes the leading parameter section as its first argument list. The label, expressed
25
+
as `<extension>` here, is compiler-internal. So, the definition of `circumference` above translates to the following method, and can also be invoked as such:
Note the swap of the two parameters `x` and `xs` when translating
@@ -101,7 +100,7 @@ By contrast, using clauses can be defined for the `extension` as well as per `de
101
100
Sometimes, one wants to define several extension methods that share the same
102
101
left-hand parameter type. In this case one can "pull out" the common parameters into
103
102
a single extension and enclose all methods in braces or an indented region following a '`:`'.
104
-
Following an example using an indented region:
103
+
Example:
105
104
106
105
```scala
107
106
extension (ss: Seq[String]):
@@ -141,6 +140,16 @@ extension (ss: Seq[String])
141
140
deflongestString:String= ss.longestStrings.head
142
141
```
143
142
143
+
Collective extensions also can take type parameters and have using clauses. Example:
144
+
145
+
```scala
146
+
extension [T](xs: List[T])(usingOrdering[T]):
147
+
defsmallest(n: Int):List[T] = xs.sorted.take(n)
148
+
defsmallestIndices(n: Int):List[Int] =
149
+
vallimit= smallest(n).max
150
+
xs.zipWithIndex.collect { case (x, i) if x <= limit => i }
151
+
```
152
+
144
153
### Translation of Calls to Extension Methods
145
154
146
155
To convert a reference to an extension method, the compiler has to know about the extension
@@ -218,9 +227,9 @@ The precise rules for resolving a selection to an extension method are as follow
218
227
Assume a selection `e.m[Ts]` where `m` is not a member of `e`, where the type arguments `[Ts]` are optional, and where `T` is the expected type.
219
228
The following two rewritings are tried in order:
220
229
221
-
1. The selection is rewritten to `extension_m[Ts](e)`.
230
+
1. The selection is rewritten to m[Ts](e)`.
222
231
2. If the first rewriting does not typecheck with expected type `T`,
223
-
and there is an extension method `m` in some eligible object `o`, the selection is rewritten to `o.extension_m[Ts](e)`. An object `o` is _eligible_ if
232
+
and there is an extension method `m` in some eligible object `o`, the selection is rewritten to `o.m[Ts](e)`. An object `o` is _eligible_ if
224
233
225
234
-`o` forms part of the implicit scope of `T`, or
226
235
-`o` is a given instance that is visible at the point of the application, or
@@ -229,15 +238,13 @@ The following two rewritings are tried in order:
229
238
This second rewriting is attempted at the time where the compiler also tries an implicit conversion
230
239
from `T` to a type containing `m`. If there is more than one way of rewriting, an ambiguity error results.
231
240
232
-
An extension method can also be used as an identifier by itself. If an identifier `m` does not
233
-
resolve, the identifier is rewritten to:
234
-
235
-
-`x.m` if the identifier appears in an extension with parameter `x`
236
-
and the method `m` resolves to an extension method in
237
-
a (possibly collective) extension that also contains the call,
238
-
-`this.m` otherwise
239
-
240
-
and the rewritten term is again tried as an application of an extension method. In
241
+
An extension method can also be referenced using a simple identifier without a preceding expression. If an identifier `g` appears in the body of an extension method `f` and refers to an extension method `g` that is defined in the same collective extension
242
+
```scala
243
+
extension (x: T)
244
+
deff ... = ... g ...
245
+
defg ...
246
+
```
247
+
the identifier is rewritten to `x.g`. This is also the case if `f` and `g` are the same method. Example:
241
248
242
249
```scala
243
250
extension (s: String)
@@ -249,27 +256,11 @@ extension (s: String)
249
256
The recursive call `position(ch, n + 1)` expands to `s.position(ch, n + 1)` in this case. The whole extension method rewrites to
0 commit comments