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
A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `with Ord[T]`. The context parameter(s) generated from context bounds come last in the definition of the containing method or class. E.g.,
13
13
```scala
14
-
deff[T:C1:C2, U:C3](x: T)with (y: U, z: V):R
14
+
deff[T:C1:C2, U:C3](x: T)(usingy: U, z: V):R
15
15
```
16
16
would expand to
17
17
```scala
18
-
deff[T, U](x: T)with (y: U, z: V)withC1[T], C2[T], C3[U]):R
18
+
deff[T, U](x: T)(usingy: U, z: V)(usingC1[T], C2[T], C3[U]):R
19
19
```
20
20
Context bounds can be combined with subtype bounds. If both are present, subtype bounds come first, e.g.
21
21
```scala
@@ -25,12 +25,11 @@ def g[T <: B : C](x: T): R = ...
25
25
### Migration
26
26
27
27
To ease migration, context bounds in Dotty map in Scala 3.0 to old-style implicit parameters
28
-
for which arguments can be passed either using `.with(...)` or using a normal application.
29
-
From Scala 3.1 on, they will map to context parameters instead, as is described above.
28
+
for which arguments can be passed either with a `(using ...)` clause or with a normal application. From Scala 3.1 on, they will map to context parameters instead, as is described above.
30
29
31
30
If the source version is `3.1` and the `-migration` command-line option is set, any pairing of an evidence
32
31
context parameter stemming from a context bound with a normal argument will give a migration
33
-
warning. The warning indicates that a `.with(...)` clause should be used instead. The rewrite can be
32
+
warning. The warning indicates that a `(using ...)` clause is needed instead. The rewrite can be
Functional programming tends to express most dependencies as simple function parameterization.
@@ -11,22 +11,19 @@ repetitive arguments instead of the programmer having to write them explicitly.
11
11
For example, with the [given instances](./givens.md) defined previously,
12
12
a maximum function that works for any arguments for which an ordering exists can be defined as follows:
13
13
```scala
14
-
defmax[T](x: T, y: T)with (ord: Ord[T]):T=
14
+
defmax[T](x: T, y: T)(usingord: Ord[T]):T=
15
15
if ord.compare(x, y) <0then y else x
16
16
```
17
-
Here, `ord` is a _context parameter_ introduced with a `with` clause.
17
+
Here, `ord` is a _context parameter_ introduced with a `using` clause.
18
18
The `max` method can be applied as follows:
19
19
```scala
20
-
max(2, 3).with(intOrd)
20
+
max(2, 3)(usingintOrd)
21
21
```
22
-
The `.with(intOrd)` part passes `intOrd` as an argument for the `ord` parameter. But the point of
23
-
context parameters is that this argument can also be left out (and it usually is). So the following
24
-
applications are equally valid:
22
+
The `(using intOrd)` part passes `intOrd` as an argument for the `ord` parameter. But the point of context parameters is that this argument can also be left out (and it usually is). So the following applications are equally valid:
25
23
```scala
26
24
max(2, 3)
27
25
max(List(1, 2, 3), Nil)
28
26
```
29
-
Formatting hint: For legibility it is recommended to always leave one space after a `with` clause before following it with another lexeme.
30
27
31
28
## Anonymous Context Parameters
32
29
@@ -35,45 +32,41 @@ mentioned explicitly at all, since it is used only in synthesized arguments for
35
32
other context parameters. In that case one can avoid defining a parameter name
36
33
and just provide its type. Example:
37
34
```scala
38
-
defmaximum[T](xs: List[T])withOrd[T]:T=
35
+
defmaximum[T](xs: List[T])(usingOrd[T]):T=
39
36
xs.reduceLeft(max)
40
37
```
41
38
`maximum` takes a context parameter of type `Ord` only to pass it on as an
42
39
inferred argument to `max`. The name of the parameter is left out.
43
40
44
-
Generally, context parameters may be defined either as a full parameter list `(p_1: T_1, ..., p_n: T_n)` or just as a sequence of types `T_1, ..., T_n`. Vararg parameters are not supported in with clauses.
45
-
46
-
**Note:** According to the rules above, a `with` clause like `(A, B)` consisting of types in parentheses defines a context parameter of tuple type. But by analogy with `(a: A, b: B)` one might assume that it defines two context parameters
47
-
of type `A` and `B` instead. To avoid confusion, the compiler could issue a warning in this case that clarifies the meaning. If a context parameter of tuple type is in fact intended, the warning can be avoided by switching to a named context parameter,
48
-
e.g. `(ab: (A, B))` or enclosing the tuple in an extra set of parentheses, e.g. `((A, B))`.
41
+
Generally, context parameters may be defined either as a full parameter list `(p_1: T_1, ..., p_n: T_n)` or just as a sequence of types `T_1, ..., T_n`. Vararg parameters are not supported in using clauses.
49
42
50
43
## Inferring Complex Arguments
51
44
52
45
Here are two other methods that have a context parameter of type `Ord[T]`:
Then the following calls are all valid (and normalize to the last one)
84
77
```scala
85
78
f(global)
86
-
f(global).with(ctx)
87
-
f(global).with(ctx).with(sym, kind)
79
+
f(global)(usingctx)
80
+
f(global)(usingctx)(usingsym, kind)
88
81
```
89
-
But `f(global).with(sym, kind)` would give a type error.
82
+
But `f(global)(using sym, kind)` would give a type error.
90
83
91
-
`with` clauses can be freely interspersed with normal parameters, but a normal parameter clause cannot
92
-
directly follow a `with` clause consisting only of types outside parentheses. So the following is illegal:
93
-
```scala
94
-
deffwithA, B (x: C) = ...
95
-
```
96
-
But the following variants are valid:
97
-
```scala
98
-
defgwithA, Bwith (x: C) = ...
99
-
defhwith (A, B) (x: C) = ...
100
-
```
101
84
102
85
## Summoning Instances
103
86
104
87
The method `summon` in `Predef` returns the given of a specific type. For example,
105
88
the given instance for `Ord[List[Int]]` is produced by
106
89
```scala
107
-
summon[Ord[List[Int]]] // reduces to listOrd.with(intOrd)
90
+
summon[Ord[List[Int]]] // reduces to listOrd(using intOrd)
108
91
```
109
92
The `summon` method is simply defined as the (non-widening) identity function over a context parameter.
110
93
```scala
111
-
defsummon[T]with (x: T): x.type= x
94
+
defsummon[T](usingx: T): x.type= x
112
95
```
113
96
114
97
## Syntax
115
98
116
-
Here is the new syntax of parameters and arguments seen as a delta from the [standard context free syntax of Scala 3](../../internals/syntax.md).
99
+
Here is the new syntax of parameters and arguments seen as a delta from the [standard context free syntax of Scala 3](../../internals/syntax.md).`using` is a soft keyword, recognized only at the start of a parameter or argument list. It can be used as a normal identifier everywhere else.
0 commit comments