Skip to content

Commit fe77e3f

Browse files
authored
Clear the not-backported documentation changes queue (#19699)
2 parents de4c4ed + 5f85033 commit fe77e3f

File tree

5 files changed

+101
-89
lines changed

5 files changed

+101
-89
lines changed

docs/_docs/reference/changed-features/wildcards.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Wildcard Arguments in Types
44
nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/wildcards.html
55
---
66

7-
The syntax of wildcard arguments in types has changed from `_` to `?`. Example:
7+
The syntax of wildcard arguments in types is changing from `_` to `?`. Example:
88
```scala
99
List[?]
1010
Map[? <: AnyRef, ? >: Null]
@@ -14,8 +14,8 @@ Map[? <: AnyRef, ? >: Null]
1414

1515
We would like to use the underscore syntax `_` to stand for an anonymous type parameter, aligning it with its meaning in
1616
value parameter lists. So, just as `f(_)` is a shorthand for the lambda `x => f(x)`, in the future `C[_]` will be a shorthand
17-
for the type lambda `[X] =>> C[X]`. This makes higher-kinded types easier to use. It also removes the wart that, used as a type
18-
parameter, `F[_]` means `F` is a type constructor whereas used as a type, `F[_]` means it is a wildcard (i.e. existential) type.
17+
for the type lambda `[X] =>> C[X]`. This will make higher-kinded types easier to use. It will also remove the wart that, used as a type
18+
parameter, `F[_]` means `F` is a type constructor, whereas used as a type, `F[_]` means it is a wildcard (i.e. existential) type.
1919
In the future, `F[_]` will mean the same thing, no matter where it is used.
2020

2121
We pick `?` as a replacement syntax for wildcard types, since it aligns with
@@ -28,11 +28,11 @@ compiler plugin still uses the reverse convention, with `?` meaning parameter pl
2828

2929
A step-by-step migration is made possible with the following measures:
3030

31-
1. In Scala 3.0, both `_` and `?` are legal names for wildcards.
32-
2. In Scala 3.1, `_` is deprecated in favor of `?` as a name for a wildcard. A `-rewrite` option is
31+
1. In earlier versions of Scala 3, both `_` and `?` are legal names for wildcards.
32+
2. In Scala 3.4, `_` will be deprecated in favor of `?` as a name for wildcards. A `-rewrite` option is
3333
available to rewrite one to the other.
34-
3. In Scala 3.2, the meaning of `_` changes from wildcard to placeholder for type parameter.
35-
4. The Scala 3.1 behavior is already available today under the `-source future` setting.
34+
3. At some later point in the future, the meaning of `_` will change from wildcard to placeholder for type parameters.
35+
4. Some deprecation warnings are already available under the `-source future` setting.
3636

3737
To smooth the transition for codebases that use kind-projector, we adopt the following measures under the command line
3838
option `-Ykind-projector`:
@@ -42,7 +42,7 @@ option `-Ykind-projector`:
4242
available to rewrite one to the other.
4343
3. In Scala 3.3, `*` is removed again, and all type parameter placeholders will be expressed with `_`.
4444

45-
These rules make it possible to cross build between Scala 2 using the kind projector plugin and Scala 3.0 - 3.2 using the compiler option `-Ykind-projector`.
45+
These rules make it possible to cross-build between Scala 2 using the kind projector plugin and Scala 3.0 - 3.2 using the compiler option `-Ykind-projector`.
4646

4747
There is also a migration path for users that want a one-time transition to syntax with `_` as a type parameter placeholder.
4848
With option `-Ykind-projector:underscores` Scala 3 will regard `_` as a type parameter placeholder, leaving `?` as the only syntax for wildcards.

docs/_docs/reference/contextual/context-functions.md

+67-57
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,29 @@ _Context functions_ are functions with (only) context parameters.
88
Their types are _context function types_. Here is an example of a context function type:
99

1010
```scala
11+
import scala.concurrent.ExecutionContext
12+
1113
type Executable[T] = ExecutionContext ?=> T
1214
```
1315
Context functions are written using `?=>` as the "arrow" sign.
1416
They are applied to synthesized arguments, in
1517
the same way methods with context parameters are applied. For instance:
1618
```scala
17-
given ec: ExecutionContext = ...
19+
given ec: ExecutionContext = ...
1820

19-
def f(x: Int): ExecutionContext ?=> Int = ...
21+
def f(x: Int): ExecutionContext ?=> Int = ...
2022

21-
// could be written as follows with the type alias from above
22-
// def f(x: Int): Executable[Int] = ...
23+
// could be written as follows with the type alias from above
24+
// def f(x: Int): Executable[Int] = ...
2325

24-
f(2)(using ec) // explicit argument
25-
f(2) // argument is inferred
26+
f(2)(using ec) // explicit argument
27+
f(2) // argument is inferred
2628
```
2729
Conversely, if the expected type of an expression `E` is a context function type
2830
`(T_1, ..., T_n) ?=> U` and `E` is not already an
2931
context function literal, `E` is converted to a context function literal by rewriting it to
3032
```scala
31-
(x_1: T1, ..., x_n: Tn) ?=> E
33+
(x_1: T1, ..., x_n: Tn) ?=> E
3234
```
3335
where the names `x_1`, ..., `x_n` are arbitrary. This expansion is performed
3436
before the expression `E` is typechecked, which means that `x_1`, ..., `x_n`
@@ -38,14 +40,14 @@ Like their types, context function literals are written using `?=>` as the arrow
3840

3941
For example, continuing with the previous definitions,
4042
```scala
41-
def g(arg: Executable[Int]) = ...
43+
def g(arg: Executable[Int]) = ...
4244

43-
g(22) // is expanded to g((ev: ExecutionContext) ?=> 22)
45+
g(22) // is expanded to g((ev: ExecutionContext) ?=> 22)
4446

45-
g(f(2)) // is expanded to g((ev: ExecutionContext) ?=> f(2)(using ev))
47+
g(f(2)) // is expanded to g((ev: ExecutionContext) ?=> f(2)(using ev))
4648

47-
g((ctx: ExecutionContext) ?=> f(3)) // is expanded to g((ctx: ExecutionContext) ?=> f(3)(using ctx))
48-
g((ctx: ExecutionContext) ?=> f(3)(using ctx)) // is left as it is
49+
g((ctx: ExecutionContext) ?=> f(3)) // is expanded to g((ctx: ExecutionContext) ?=> f(3)(using ctx))
50+
g((ctx: ExecutionContext) ?=> f(3)(using ctx)) // is left as it is
4951
```
5052

5153
## Example: Builder Pattern
@@ -54,63 +56,65 @@ Context function types have considerable expressive power. For
5456
instance, here is how they can support the "builder pattern", where
5557
the aim is to construct tables like this:
5658
```scala
57-
table {
58-
row {
59-
cell("top left")
60-
cell("top right")
61-
}
62-
row {
63-
cell("bottom left")
64-
cell("bottom right")
65-
}
59+
table {
60+
row {
61+
cell("top left")
62+
cell("top right")
63+
}
64+
row {
65+
cell("bottom left")
66+
cell("bottom right")
6667
}
68+
}
6769
```
6870
The idea is to define classes for `Table` and `Row` that allow the
6971
addition of elements via `add`:
7072
```scala
71-
class Table:
72-
val rows = new ArrayBuffer[Row]
73-
def add(r: Row): Unit = rows += r
74-
override def toString = rows.mkString("Table(", ", ", ")")
73+
import scala.collection.mutable.ArrayBuffer
74+
75+
class Table:
76+
val rows = new ArrayBuffer[Row]
77+
def add(r: Row): Unit = rows += r
78+
override def toString = rows.mkString("Table(", ", ", ")")
7579

76-
class Row:
77-
val cells = new ArrayBuffer[Cell]
78-
def add(c: Cell): Unit = cells += c
79-
override def toString = cells.mkString("Row(", ", ", ")")
80+
class Row:
81+
val cells = new ArrayBuffer[Cell]
82+
def add(c: Cell): Unit = cells += c
83+
override def toString = cells.mkString("Row(", ", ", ")")
8084

81-
case class Cell(elem: String)
85+
case class Cell(elem: String)
8286
```
8387
Then, the `table`, `row` and `cell` constructor methods can be defined
8488
with context function types as parameters to avoid the plumbing boilerplate
8589
that would otherwise be necessary.
8690
```scala
87-
def table(init: Table ?=> Unit) =
88-
given t: Table = Table()
89-
init
90-
t
91-
92-
def row(init: Row ?=> Unit)(using t: Table) =
93-
given r: Row = Row()
94-
init
95-
t.add(r)
96-
97-
def cell(str: String)(using r: Row) =
98-
r.add(new Cell(str))
91+
def table(init: Table ?=> Unit) =
92+
given t: Table = Table()
93+
init
94+
t
95+
96+
def row(init: Row ?=> Unit)(using t: Table) =
97+
given r: Row = Row()
98+
init
99+
t.add(r)
100+
101+
def cell(str: String)(using r: Row) =
102+
r.add(new Cell(str))
99103
```
100104
With that setup, the table construction code above compiles and expands to:
101105
```scala
102-
table { ($t: Table) ?=>
103-
104-
row { ($r: Row) ?=>
105-
cell("top left")(using $r)
106-
cell("top right")(using $r)
107-
}(using $t)
108-
109-
row { ($r: Row) ?=>
110-
cell("bottom left")(using $r)
111-
cell("bottom right")(using $r)
112-
}(using $t)
113-
}
106+
table { ($t: Table) ?=>
107+
108+
row { ($r: Row) ?=>
109+
cell("top left")(using $r)
110+
cell("top right")(using $r)
111+
}(using $t)
112+
113+
row { ($r: Row) ?=>
114+
cell("bottom left")(using $r)
115+
cell("bottom right")(using $r)
116+
}(using $t)
117+
}
114118
```
115119
## Example: Postconditions
116120

@@ -131,12 +135,18 @@ import PostConditions.{ensuring, result}
131135

132136
val s = List(1, 2, 3).sum.ensuring(result == 6)
133137
```
134-
**Explanations**: We use a context function type `WrappedResult[T] ?=> Boolean`
138+
### Explanation
139+
140+
We use a context function type `WrappedResult[T] ?=> Boolean`
135141
as the type of the condition of `ensuring`. An argument to `ensuring` such as
136142
`(result == 6)` will therefore have a given of type `WrappedResult[T]` in
137-
scope to pass along to the `result` method. `WrappedResult` is a fresh type, to make sure
143+
scope to pass along to the `result` method.
144+
145+
`WrappedResult` is a fresh type, to make sure
138146
that we do not get unwanted givens in scope (this is good practice in all cases
139-
where context parameters are involved). Since `WrappedResult` is an opaque type alias, its
147+
where context parameters are involved).
148+
149+
Since `WrappedResult` is an opaque type alias, its
140150
values need not be boxed, and since `ensuring` is added as an extension method, its argument
141151
does not need boxing either. Hence, the implementation of `ensuring` is close in efficiency to the best possible code one could write by hand:
142152

0 commit comments

Comments
 (0)