Skip to content

Commit 7c08c0e

Browse files
committed
Fix right-associative-extension-methods.md
1 parent 0f7f890 commit 7c08c0e

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

docs/_docs/reference/contextual/right-associative-extension-methods.md

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,54 @@ title: "Right-Associative Extension Methods: Details"
44
nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/right-associative-extension-methods.html
55
---
66

7-
The most general form of leading parameters of an extension method is as follows:
8-
7+
The most general signature an extension method can have is as follows:
8+
- An optional type clause `leadingTyParamss`
99
- A possibly empty list of using clauses `leadingUsing`
10-
- A single parameter `extensionParam`
10+
- A single parameter `leftParamss`
1111
- A possibly empty list of using clauses `trailingUsing`
12+
- A name (preceded by the `def` keyword)
13+
- An optional type clause `rightTyParamss`
14+
- An optional explicit term clause `rightParamss`
15+
- Any number of any clauses `rest`
1216

13-
This is then followed by `def`, the method name, and possibly further parameters
14-
`otherParams`. An example is:
17+
For example:
1518

1619
```scala
17-
extension (using a: A, b: B)(using c: C) // <-- leadingUsing
18-
(x: X) // <-- extensionParam
20+
extension [T] // <-- leadingTyParamss
21+
(using a: A, b: B)(using c: C) // <-- leadingUsing
22+
(x: X) // <-- leftParamss
1923
(using d: D) // <-- trailingUsing
20-
def +:: (y: Y)(using e: E)(z: Z) // <-- otherParams
24+
def +:: [U] // <-- rightTyParamss
25+
(y: Y) // <-- rightParamss
26+
[V](using e: E)[W](z: Z) // <-- rest
2127
```
2228

29+
2330
An extension method is treated as a right-associative operator
2431
(as in [SLS §6.12.3](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#infix-operations))
25-
if it has a name ending in `:` and is immediately followed by a
26-
single parameter. In the example above, that parameter is `(y: Y)`.
32+
if it has a name ending in `:`, and is immediately followed by a
33+
single explicit term parameter (in other words, `rightParamss` is present). In the example above, that parameter is `(y: Y)`.
2734

2835
The Scala compiler pre-processes a right-associative infix operation such as `x +: xs`
2936
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
3037
is defined in the class of its right operand. To make up for this swap,
31-
the expansion of right-associative extension methods performs an analogous parameter swap. More precisely, if `otherParams` consists of a single parameter
32-
`rightParam` followed by `remaining`, the total parameter sequence
38+
the expansion of right-associative extension methods performs the inverse parameter swap. More precisely, if `rightParamss` is present, the total parameter sequence
3339
of the extension method's expansion is:
3440

3541
```
36-
leadingUsing rightParam trailingUsing extensionParam remaining
42+
leadingTyParamss leadingUsing rightTyParamss rightParamss leftParamss trailingUsing rest
3743
```
3844

3945
For instance, the `+::` method above would become
4046

4147
```scala
42-
<extension> def +:: (using a: A, b: B)(using c: C)
48+
<extension> def +:: [T]
49+
(using a: A, b: B)(using c: C)
50+
[U]
4351
(y: Y)
44-
(using d: D)
4552
(x: X)
46-
(using e: E)(z: Z)
53+
(using d: D)
54+
[V](using e: E)[W](z: Z)
4755
```
4856

4957
This expansion has to be kept in mind when writing right-associative extension

0 commit comments

Comments
 (0)