Skip to content

Commit ae2f23c

Browse files
committed
Syntax change: inferred for instead of instance of
1 parent 90c2963 commit ae2f23c

File tree

6 files changed

+97
-95
lines changed

6 files changed

+97
-95
lines changed

docs/docs/reference/instances/context-params.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
layout: doc-page
3-
title: "Implicit Parameters and Arguments"
3+
title: "Inferred Parameters and Arguments"
44
---
55

66
A new syntax for implicit parameters aligns definition and call syntax. Parameter definitions and method arguments both follow a `given` keyword. On the definition side, the old syntax
@@ -54,8 +54,8 @@ lists in a definition. Example:
5454
```scala
5555
def f given (u: Universe) (x: u.T) given Context = ...
5656

57-
instance global of Universe { type T = String ... }
58-
instance ctx of Context { ... }
57+
inferred global for Universe { type T = String ... }
58+
inferred ctx for Context { ... }
5959
```
6060
Then the following calls are all valid (and normalize to the last one)
6161
```scala
@@ -69,7 +69,7 @@ or as a sequence of types. To distinguish the two, a leading `(` always indicate
6969

7070
## Summoning an Instance
7171

72-
A method `summon` in `Predef` creates an implicit instance value for a given type, analogously to what `implicitly[T]` did. The only difference between the two is that
72+
A method `summon` in `Predef` returns the inferred value for a given type, analogously to what `implicitly[T]` did. The only difference between the two is that
7373
`summon` takes a context parameter, where `implicitly` took an old-style implicit parameter:
7474
```scala
7575
def summon[T] with (x: T) = x

docs/docs/reference/instances/implicit-conversions.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ layout: doc-page
33
title: "Implicit Conversions"
44
---
55

6-
Implicit conversions are defined by instances of the `scala.Conversion` class.
6+
Implicit conversions are defined by inferred instances of the `scala.Conversion` class.
77
This class is defined in package `scala` as follows:
88
```scala
99
abstract class Conversion[-T, +U] extends (T => U)
1010
```
1111
For example, here is an implicit conversion from `String` to `Token`:
1212
```scala
13-
instance of Conversion[String, Token] {
13+
inferred for Conversion[String, Token] {
1414
def apply(str: String): Token = new KeyWord(str)
1515
}
1616
```
@@ -33,7 +33,7 @@ If such an instance `C` is found, the expression `e` is replaced by `C.apply(e)`
3333
primitive number types to subclasses of `java.lang.Number`. For instance, the
3434
conversion from `Int` to `java.lang.Integer` can be defined as follows:
3535
```scala
36-
instance int2Integer of Conversion[Int, java.lang.Integer] {
36+
inferred int2Integer for Conversion[Int, java.lang.Integer] {
3737
def apply(x: Int) = new java.lang.Integer(x)
3838
}
3939
```
@@ -56,13 +56,13 @@ object Completions {
5656
//
5757
// CompletionArg.from(statusCode)
5858

59-
instance from of Conversion[String, CompletionArg] {
59+
inferred from for Conversion[String, CompletionArg] {
6060
def apply(s: String) = CompletionArg.Error(s)
6161
}
62-
instance from of Conversion[Future[HttpResponse], CompletionArg] {
62+
inferred from for Conversion[Future[HttpResponse], CompletionArg] {
6363
def apply(f: Future[HttpResponse]) = CompletionArg.Response(f)
6464
}
65-
instance from of Conversion[Future[StatusCode], CompletionArg] {
65+
inferred from for Conversion[Future[StatusCode], CompletionArg] {
6666
def apply(code: Future[StatusCode]) = CompletionArg.Status(code)
6767
}
6868
}

docs/docs/reference/instances/implicit-function-types.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,31 @@ layout: doc-page
33
title: "Implicit Function Types and Closures"
44
---
55

6-
An implicit function type describes functions with implicit (context) parameters. Example:
6+
An implicit function type describes functions with inferred parameters. Example:
77
```scala
88
type Contextual[T] = given Context => T
99
```
10-
A value of implicit function type is applied to context arguments, in
11-
the same way a method with context parameters is applied. For instance:
10+
A value of implicit function type is applied to inferred arguments, in
11+
the same way a method with inferred parameters is applied. For instance:
1212
```scala
13-
implicit val ctx: Context = ...
13+
inferred ctx for Context = ...
1414

1515
def f(x: Int): Contextual[Int] = ...
1616

1717
f(2) given ctx // explicit argument
18-
f(2) // argument left implicit
18+
f(2) // argument is inferred
1919
```
2020
Conversely, if the expected type of an expression `E` is an implicit
2121
function type `given (T_1, ..., T_n) => U` and `E` is not already an
22-
implicit function value, `E` is converted to an implicit function value
22+
implicit function value, `E` is converted to an inferred function value
2323
by rewriting to
2424
```scala
2525
given (x_1: T1, ..., x_n: Tn) => E
2626
```
27-
where the names `x_1`, ..., `x_n` are arbitrary. Implicit closures are written
28-
with a `given` prefix. They differ from normal closures in two ways:
27+
where the names `x_1`, ..., `x_n` are arbitrary. inferred function values are written
28+
with a `given` prefix. They differ from normal function values in two ways:
2929

30-
1. Their parameters are implicit context parameters
30+
1. Their parameters are inferred parameters
3131
2. Their types are implicit function types.
3232

3333
For example, continuing with the previous definitions,
Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
22
layout: doc-page
3-
title: "Instance Definitions"
3+
title: "Inferred Instances"
44
---
55

6-
Instance definitions provide a concise and uniform syntax for defining implicit values. Example:
6+
Inferred instance definitions provide a concise and uniform syntax for defining values
7+
that can be inferred as implicit arguments. Example:
78

89
```scala
910
trait Ord[T] {
@@ -12,12 +13,12 @@ trait Ord[T] {
1213
def (x: T) > (y: T) = x.compareTo(y) > 0
1314
}
1415

15-
instance IntOrd of Ord[Int] {
16+
inferred IntOrd for Ord[Int] {
1617
def (x: Int) compareTo (y: Int) =
1718
if (x < y) -1 else if (x > y) +1 else 0
1819
}
1920

20-
instance ListOrd[T: Ord] of Ord[List[T]] {
21+
inferred ListOrd[T: Ord] for Ord[List[T]] {
2122
def (xs: List[T]) compareTo (ys: List[T]): Int = (xs, ys) match {
2223
case (Nil, Nil) => 0
2324
case (Nil, _) => -1
@@ -28,16 +29,16 @@ instance ListOrd[T: Ord] of Ord[List[T]] {
2829
}
2930
}
3031
```
31-
Instance definitions can be seen as shorthands for what is currently expressed with implicit object and method definitions.
32-
For example, the definition of instance `IntOrd` above defines an implicit value of type `Ord[Int]`. It is hence equivalent
32+
Inferred instance definitions can be seen as shorthands for what is currently expressed with implicit object and method definitions.
33+
For example, the definition of the inferred instance `IntOrd` above defines an implicit value of type `Ord[Int]`. It is hence equivalent
3334
to the following implicit object definition:
3435
```scala
3536
implicit object IntOrd extends Ord[Int] {
3637
def (x: Int) compareTo (y: Int) =
3738
if (x < y) -1 else if (x > y) +1 else 0
3839
}
3940
```
40-
The definition of instance `ListOrd` defines an ordering for `List[T]` provided there is an ordering for type `T`. With existing
41+
The definition of the inferred instance `ListOrd` defines an ordering for `List[T]` provided there is an ordering for type `T`. With existing
4142
implicits, this could be expressed as a pair of a class and an implicit method:
4243
```scala
4344
class ListOrd[T: Ord] extends Ord[List[T]] {
@@ -52,70 +53,70 @@ class ListOrd[T: Ord] extends Ord[List[T]] {
5253
}
5354
implicit def ListOrd[T: Ord]: Ord[List[T]] = new ListOrd[T]
5455
```
55-
## Instances for Extension Methods
56+
## Inferred Instances for Extension Methods
5657

57-
Instances can also be defined without an `of` clause. A typical application is to use a instance to package some extension methods. Examples:
58+
Inferred instances can also be defined without a `for` clause. A typical application is to use an inferred instance to package some extension methods. Examples:
5859

5960
```scala
60-
instance StringOps {
61+
inferred StringOps {
6162
def (xs: Seq[String]) longestStrings: Seq[String] = {
6263
val maxLength = xs.map(_.length).max
6364
xs.filter(_.length == maxLength)
6465
}
6566
}
6667

67-
instance ListOps {
68+
inferred ListOps {
6869
def (xs: List[T]) second[T] = xs.tail.head
6970
}
7071
```
71-
## Anonymous Instances
72+
## Anonymous Inferred Instances
7273

73-
The name of an instance definition can be left out. Examples:
74+
The name of an inferred instance can be left out. Examples:
7475
```scala
75-
instance of Ord[Int] { ... }
76-
instance [T: Ord] of Ord[List[T]] { ... }
76+
inferred for Ord[Int] { ... }
77+
inferred [T: Ord] for Ord[List[T]] { ... }
7778

78-
instance {
79+
inferred {
7980
def (xs: List[T]) second[T] = xs.tail.head
8081
}
8182
```
82-
If the name of an instance is missing, the compiler will synthesize a name from
83+
If the name of an inferred instance is missing, the compiler will synthesize a name from
8384
the type in the of clause, or, if that is missing, from the first defined
8485
extension method.
8586

86-
**Aside: ** Why anonymous instances?
87+
**Aside: ** Why anonymous inferred instances?
8788

8889
- It avoids clutter, relieving the programmer from having to invent names that are never referred to.
8990
Usually the invented names are either meaning less (e.g. `ev1`), or they just rephrase the implemented type.
90-
- It gives a systematic foundation for synthesized instance definitions, such as those coming from a `derives` clause.
91+
- It gives a systematic foundation for synthesized inferred instance definitions, such as those coming from a `derives` clause.
9192
- It achieves a uniform principle that the name of an implicit is always optional, no matter
92-
whether the implicit is an instance definition or an implicit parameter.
93+
whether the implicit is an inferred instance definition or an implicit parameter.
9394

94-
## Conditional Implicits
95+
## Conditional Instances
9596

96-
An instance definition can depend on another instance being defined. Example:
97+
An inferred instance definition can depend on another inferred instance being defined. Example:
9798
```scala
9899
trait Conversion[-From, +To] {
99100
def apply(x: From): To
100101
}
101102

102-
instance [S, T] given (c: Conversion[S, T]) of Conversion[List[S], List[T]] {
103+
inferred [S, T] given (c: Conversion[S, T]) for Conversion[List[S], List[T]] {
103104
def convert(x: List[From]): List[To] = x.map(c.apply)
104105
}
105106
```
106107
This defines an implicit conversion from `List[S]` to `List[T]` provided there is an implicit conversion from `S` to `T`.
107108
The `given` clause defines required instances. The `Conversion[List[From], List[To]]` instance above
108109
is defined only if a `Conversion[From, To]` instance exists.
109110

110-
Context bounds in instance definitions also translate to implicit parameters,
111-
and therefore they can be represented alternatively as with clauses. For example,
111+
Context bounds in inferred instance definitions also translate to implicit parameters,
112+
and therefore they can be represented alternatively as `given` clauses. For example,
112113
here is an equivalent definition of the `ListOrd` instance:
113114
```scala
114-
instance ListOrd[T] given (ord: Ord[T]) of List[Ord[T]] { ... }
115+
inferred ListOrd[T] given (ord: Ord[T]) for List[Ord[T]] { ... }
115116
```
116117
The name of a parameter in a `given` clause can also be left out, as shown in the following variant of `ListOrd`:
117118
```scala
118-
instance ListOrd[T] given Ord[T] of List[Ord[T]] { ... }
119+
inferred ListOrd[T] given Ord[T] for List[Ord[T]] { ... }
119120
```
120121
As usual one can then infer to implicit parameter only indirectly, by passing it as implicit argument to another function.
121122

@@ -137,7 +138,7 @@ object Monoid {
137138
def apply[T] = implicitly[Monoid[T]]
138139
}
139140

140-
instance of Monoid[String] {
141+
inferred for Monoid[String] {
141142
def (x: String) combine (y: String): String = x.concat(y)
142143
def unit: String = ""
143144
}
@@ -158,50 +159,51 @@ trait Monad[F[_]] extends Functor[F] {
158159
def pure[A](x: A): F[A]
159160
}
160161

161-
instance ListMonad of Monad[List] {
162+
inferred ListMonad for Monad[List] {
162163
def (xs: List[A]) flatMap[A, B] (f: A => List[B]): List[B] =
163164
xs.flatMap(f)
164165
def pure[A](x: A): List[A] =
165166
List(x)
166167
}
167168

168-
instance ReaderMonad[Ctx] of Monad[[X] => Ctx => X] {
169+
inferred ReaderMonad[Ctx] for Monad[[X] => Ctx => X] {
169170
def (r: Ctx => A) flatMap[A, B] (f: A => Ctx => B): Ctx => B =
170171
ctx => f(r(ctx))(ctx)
171172
def pure[A](x: A): Ctx => A =
172173
ctx => x
173174
}
174175
```
175-
## Alias Instances
176+
## Inferred Alias Instances
176177

177-
An alias instance creates an instance that is equal to some expression. E.g.,
178+
An inferred alias instance creates an inferred instance that is equal to
179+
some expression. E.g.,
178180
```
179-
instance ctx of ExecutionContext = currentThreadPool().context
181+
inferred ctx for ExecutionContext = currentThreadPool().context
180182
```
181-
Here, we create an instance `ctx` of type `ExecutionContext` that resolves to the
182-
right hand side `currentThreadPool().context`. Each time an instance of `ExecutionContext`
183+
Here, we create an inferred instance `ctx` of type `ExecutionContext` that resolves to the
184+
right hand side `currentThreadPool().context`. Each time an inferred instance of `ExecutionContext`
183185
is demanded, the result of evaluating the right-hand side expression is returned. The instance definition is equivalent to the following implicit definition:
184186
```
185187
final implicit def ctx: ExecutionContext = currentThreadPool().context
186188
```
187189
Alias instances may be anonymous, e.g.
188190
```
189-
instance of Position = enclosingTree.position
191+
inferred for Position = enclosingTree.position
190192
```
191-
An alias instance can have type and context parameters just like any other instance definition, but it can only implement a single type.
193+
An inferred alias instance can have type and context parameters just like any other inferred instance definition, but it can only implement a single type.
192194

193195
## Syntax
194196

195-
Here is the new syntax of instance definitions, seen as a delta from the [standard context free syntax of Scala 3](http://dotty.epfl.ch/docs/internals/syntax.html).
197+
Here is the new syntax of inferred instance definitions, seen as a delta from the [standard context free syntax of Scala 3](http://dotty.epfl.ch/docs/internals/syntax.html).
196198
```
197199
TmplDef ::= ...
198-
| ‘instance’ InstanceDef
200+
| ‘inferred’ InstanceDef
199201
InstanceDef ::= [id] InstanceParams InstanceBody
200202
InstanceParams ::= [DefTypeParamClause] {InstParamClause}
201203
InstParamClause ::= ‘given’ (‘(’ [DefParams] ‘)’ | ContextTypes)
202-
InstanceBody ::= [‘of’ ConstrApp {‘,’ ConstrApp }] [TemplateBody]
203-
| ‘of’ Type ‘=’ Expr
204+
InstanceBody ::= [‘for’ ConstrApp {‘,’ ConstrApp }] [TemplateBody]
205+
| ‘for’ Type ‘=’ Expr
204206
ContextTypes ::= RefinedType {‘,’ RefinedType}
205207
```
206-
The identifier `id` can be omitted only if either the `of` part or the template body is present.
207-
If the `of` part is missing, the template body must define at least one extension method.
208+
The identifier `id` can be omitted only if either the `for` part or the template body is present.
209+
If the `for` part is missing, the template body must define at least one extension method.

0 commit comments

Comments
 (0)