Skip to content

Commit 0d03af4

Browse files
Merge pull request #8596 from tegonal/documentation
bundle of documentation improvements
2 parents 2dfb359 + abc35b7 commit 0d03af4

15 files changed

+72
-61
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ With that setup, the table construction code above compiles and expands to:
112112
```
113113
### Example: Postconditions
114114

115-
As a larger example, here is a way to define constructs for checking arbitrary postconditions using an extension method `ensuring` so that the checked result can be referred to simply by `result`. The example combines opaque aliases, context function types, and extension methods to provide a zero-overhead abstraction.
115+
As a larger example, here is a way to define constructs for checking arbitrary postconditions using an extension method `ensuring` so that the checked result can be referred to simply by `result`. The example combines opaque type aliases, context function types, and extension methods to provide a zero-overhead abstraction.
116116

117117
```scala
118118
object PostConditions {

docs/docs/reference/dropped-features/package-objects.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ The compiler generates synthetic objects that wrap toplevel definitions falling
3131

3232
- all pattern, value, method, and type definitions,
3333
- implicit classes and objects,
34-
- companion objects of opaque types.
34+
- companion objects of opaque type aliases.
3535

3636
If a source file `src.scala` contains such toplevel definitions, they will be put in a synthetic object named `src$package`. The wrapping is transparent, however. The definitions in `src` can still be accessed as members of the enclosing package.
3737

docs/docs/reference/enums/desugarEnums.md

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,34 @@ some terminology and notational conventions:
1919

2020
- _Class cases_ are those cases that are parameterized, either with a type parameter section `[...]` or with one or more (possibly empty) parameter sections `(...)`.
2121
- _Simple cases_ are cases of a non-generic enum that have neither parameters nor an extends clause or body. That is, they consist of a name only.
22-
- _Value cases_ are all cases that do not have a parameter section but that do have a (possibly generated) extends clause and/or a body.
22+
- _Value cases_ are all cases that do not have a parameter section but that do have a (possibly generated) `extends` clause and/or a body.
2323

2424
Simple cases and value cases are collectively called _singleton cases_.
2525

2626
The desugaring rules imply that class cases are mapped to case classes, and singleton cases are mapped to `val` definitions.
2727

2828
There are nine desugaring rules. Rule (1) desugar enum definitions. Rules
29-
(2) and (3) desugar simple cases. Rules (4) to (6) define extends clauses for cases that
30-
are missing them. Rules (7) to (9) define how such cases with extends clauses
31-
map into case classes or vals.
32-
33-
1. An `enum` definition
34-
```scala
35-
enum E ... { <defs> <cases> }
36-
```
37-
expands to a `sealed` `abstract` class that extends the `scala.Enum` trait and
38-
an associated companion object that contains the defined cases, expanded according
39-
to rules (2 - 8). The enum trait starts with a compiler-generated import that imports
40-
the names `<caseIds>` of all cases so that they can be used without prefix in the trait.
41-
```scala
42-
sealed abstract class E ... extends <parents> with scala.Enum {
43-
import E.{ <caseIds> }
29+
(2) and (3) desugar simple cases. Rules (4) to (6) define `extends` clauses for cases that
30+
are missing them. Rules (7) to (9) define how such cases with `extends` clauses
31+
map into `case class`es or `val`s.
32+
33+
1. An `enum` definition
34+
```scala
35+
enum E ... { <defs> <cases> }
36+
```
37+
expands to a `sealed abstract` class that extends the `scala.Enum` trait and
38+
an associated companion object that contains the defined cases, expanded according
39+
to rules (2 - 8). The enum trait starts with a compiler-generated import that imports
40+
the names `<caseIds>` of all cases so that they can be used without prefix in the trait.
41+
```scala
42+
sealed abstract class E ... extends <parents> with scala.Enum {
43+
import E.{ <caseIds> }
4444
<defs>
45-
}
46-
object E { <cases> }
47-
```
48-
2. A simple case consisting of a comma-separated list of enum names
45+
}
46+
object E { <cases> }
47+
```
48+
49+
2. A simple case consisting of a comma-separated list of enum names
4950
```scala
5051
case C_1, ..., C_n
5152
```
@@ -69,7 +70,7 @@ map into case classes or vals.
6970

7071
4. If `E` is an enum with type parameters
7172
```scala
72-
V1 T1 > L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0)
73+
V1 T1 >: L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0)
7374
```
7475
where each of the variances `Vi` is either `'+'` or `'-'`, then a simple case
7576
```scala
@@ -81,7 +82,7 @@ map into case classes or vals.
8182
```
8283
where `Bi` is `Li` if `Vi = '+'` and `Ui` if `Vi = '-'`. This result is then further
8384
rewritten with rule (8). Simple cases of enums with non-variant type
84-
parameters are not permitted.
85+
parameters are not permitted (however value cases with explicit `extends` clause are)
8586

8687
5. A class case without an extends clause
8788
```scala
@@ -201,4 +202,4 @@ Cases such as `case C` expand to a `@static val` as opposed to a `val`. This all
201202
explicitly declared in it.
202203

203204
- If an enum case has an extends clause, the enum class must be one of the
204-
classes that's extended.
205+
classes that's extended.

docs/docs/reference/new-types/match-types.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type LeafElem[X] = X match {
3939
```
4040
Recursive match type definitions can also be given an upper bound, like this:
4141
```scala
42-
type Concat[+Xs <: Tuple, +Ys <: Tuple] <: Tuple = Xs match {
42+
type Concat[Xs <: Tuple, +Ys <: Tuple] <: Tuple = Xs match {
4343
case Unit => Ys
4444
case x *: xs => x *: Concat[xs, Ys]
4545
}
@@ -124,17 +124,21 @@ The third rule states that a match type conforms to its upper bound
124124

125125
Within a match type `Match(S, Cs) <: B`, all occurrences of type variables count as covariant. By the nature of the cases `Ci` this means that occurrences in pattern position are contravarant (since patterns are represented as function type arguments).
126126

127-
## Typing Rules for Match Expressions
127+
<!-- TODO revise this section, at least `S` has to be invariant according to the current implementation -->
128+
129+
## Typing Rules for Match Expressions (Work in Progress)
130+
131+
<!-- TODO document the final solution and remove (Work in Progress) -->
128132

129133
Typing rules for match expressions are tricky. First, they need some new form of GADT matching for value parameters.
130134
Second, they have to account for the difference between sequential match on the term level and parallel match on the type level. As a running example consider:
131135
```scala
132-
type M[+X] = X match {
136+
type M[X] = X match {
133137
case A => 1
134138
case B => 2
135139
}
136140
```
137-
We'd like to be able to typecheck
141+
We would like to be able to typecheck
138142
```scala
139143
def m[X](x: X): M[X] = x match {
140144
case _: A => 1 // type error
@@ -144,14 +148,14 @@ def m[X](x: X): M[X] = x match {
144148
Unfortunately, this goes nowhere. Let's try the first case. We have: `x.type <: A` and `x.type <: X`. This tells
145149
us nothing useful about `X`, so we cannot reduce `M` in order to show that the right hand side of the case is valid.
146150

147-
The following variant is more promising:
151+
The following variant is more promising but does not compile either:
148152
```scala
149153
def m(x: Any): M[x.type] = x match {
150154
case _: A => 1
151155
case _: B => 2
152156
}
153157
```
154-
To make this work, we'd need a new form of GADT checking: If the scrutinee is a term variable `s`, we can make use of
158+
To make this work, we would need a new form of GADT checking: If the scrutinee is a term variable `s`, we can make use of
155159
the fact that `s.type` must conform to the pattern's type and derive a GADT constraint from that. For the first case above,
156160
this would be the constraint `x.type <: A`. The new aspect here is that we need GADT constraints over singleton types where
157161
before we just had constraints over type parameters.

docs/docs/reference/other-new-features/control-syntax.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ The rules in detail are:
3939
### Rewrites
4040

4141
The Dotty compiler can rewrite source code from old syntax and new syntax and back.
42-
When invoked with options `-rewrite -new-syntax` it will rewrite from old to new syntax, dropping parentheses and braces in conditions and enumerators. When invoked with with options `-rewrite -old-syntax` it will rewrite in the reverse direction, inserting parentheses and braces as needed.
42+
When invoked with options `-rewrite -new-syntax` it will rewrite from old to new syntax, dropping parentheses and braces in conditions and enumerators. When invoked with options `-rewrite -old-syntax` it will rewrite in the reverse direction, inserting parentheses and braces as needed.

docs/docs/reference/other-new-features/explicit-nulls.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ Instead, to mark a type as nullable we use a [type union](https://dotty.epfl.ch/
1717
val x: String|Null = null // ok
1818
```
1919

20-
Explicit nulls are enabled via a `-Yexplicit-nulls` flag, so they're an opt-in feature.
20+
Explicit nulls are enabled via a `-Yexplicit-nulls` flag.
2121

2222
Read on for details.
2323

2424
## New Type Hierarchy
2525

26-
When explicit nulls are enabled, the type hierarchy changes so that `Null` is subtype only of
26+
When explicit nulls are enabled, the type hierarchy changes so that `Null` is only a subtype of
2727
`Any`, as opposed to every reference type.
2828

2929
This is the new type hierarchy:
@@ -33,7 +33,7 @@ After erasure, `Null` remains a subtype of all reference types (as forced by the
3333

3434
## Unsoundness
3535

36-
The new type system is unsound with respect to `null`. This means there are still instances where an expressions has a non-nullable type like `String`, but its value is `null`.
36+
The new type system is unsound with respect to `null`. This means there are still instances where an expression has a non-nullable type like `String`, but its value is actually `null`.
3737

3838
The unsoundness happens because uninitialized fields in a class start out as `null`:
3939
```scala

docs/docs/reference/other-new-features/indentation.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ title: Optional Braces
44
---
55

66
As an experimental feature, Scala 3 enforces some rules on indentation and allows
7-
some occurrences of braces `{...}` to be optional.
7+
some occurrences of braces `{...}` to be optional.
8+
It can be turned off with the compiler flag `-noindent`.
89

9-
- First, some badly indented programs are ruled out, which means they are flagged with warnings.
10+
- First, some badly indented programs are flagged with warnings.
1011
- Second, some occurrences of braces `{...}` are made optional. Generally, the rule
1112
is that adding a pair of optional braces will not change the meaning of a well-indented program.
1213

docs/docs/reference/other-new-features/opaques-details.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,22 @@ The general form of a (monomorphic) opaque type alias is
2020
```scala
2121
opaque type T >: L <: U = R
2222
```
23-
where the lower bound `L` and the upper bound `U` may be missing, in which case they are assumed to be `scala.Nothing` and `scala.Any`, respectively. If bounds are given, it is checked that the right hand side `R` conforms to them, i.e. `L <: R` and `R <: U`. F-bounds are not supported for opaque types: `T` is not allowed to appear in `L` or `U`.
23+
where the lower bound `L` and the upper bound `U` may be missing, in which case they are assumed to be `scala.Nothing` and `scala.Any`, respectively. If bounds are given, it is checked that the right hand side `R` conforms to them, i.e. `L <: R` and `R <: U`. F-bounds are not supported for opaque type aliases: `T` is not allowed to appear in `L` or `U`.
2424

2525
Inside the scope of the alias definition, the alias is transparent: `T` is treated
2626
as a normal alias of `R`. Outside its scope, the alias is treated as the abstract type
2727
```scala
2828
type T >: L <: U
2929
```
30-
A special case arises if the opaque type is defined in an object. Example:
30+
A special case arises if the opaque type alias is defined in an object. Example:
3131
```
3232
object o {
3333
opaque type T = R
3434
}
3535
```
3636
In this case we have inside the object (also for non-opaque types) that `o.T` is equal to
3737
`T` or its expanded form `o.this.T`. Equality is understood here as mutual subtyping, i.e.
38-
`o.T <: o.this.T` and `o.this.T <: T`. Furthermore, we have by the rules of opaque types
38+
`o.T <: o.this.T` and `o.this.T <: T`. Furthermore, we have by the rules of opaque type aliases
3939
that `o.this.T` equals `R`. The two equalities compose. That is, inside `o`, it is
4040
also known that `o.T` is equal to `R`. This means the following code type-checks:
4141
```scala
@@ -48,7 +48,7 @@ def id(x: o.T): o.T = x
4848

4949
### Toplevel Opaque Types
5050

51-
An opaque type on the toplevel is transparent in all other toplevel definitions in the sourcefile where it appears, but is opaque in nested
51+
An opaque type alias on the toplevel is transparent in all other toplevel definitions in the sourcefile where it appears, but is opaque in nested
5252
objects and classes and in all other source files. Example:
5353
```scala
5454
// in test1.scala
@@ -69,10 +69,10 @@ object test1$package {
6969
val x: A = "abc"
7070
}
7171
object obj {
72-
val y: A = "abc" // error: cannot assign "abc" to opaque type A
72+
val y: A = "abc" // error: cannot assign "abc" to opaque type alias A
7373
}
7474
```
75-
The opaque type `A` is transparent in its scope, which includes the definition of `x`, but not the definitions of `obj` and `y`.
75+
The opaque type alias `A` is transparent in its scope, which includes the definition of `x`, but not the definitions of `obj` and `y`.
7676

7777

7878
### Relationship to SIP 35

docs/docs/reference/other-new-features/open-classes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ open class Writer[T] {
1313
/** Sends to stdout, can be overridden */
1414
def send(x: T) = println(x)
1515

16-
/** Send all arguments using `send` */
16+
/** Sends all arguments using `send` */
1717
def sendAll(xs: T*) = xs.foreach(send)
1818
}
1919

docs/docs/reference/other-new-features/parameter-untupling-spec.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ parameter `pi`. Then `f` will conform to the function type `ProductN[T1, ..., Tn
4343
A type `Ti` fits a parameter `pi` if one of the following two cases is `true`:
4444

4545
* `pi` comes without a type, i.e. it is a simple identifier or `_`.
46-
* `pi` is of the form `x: Ui` or `_: Ui` and `Ti` conforms to `Ui`.
46+
* `pi` is of the form `x: Ui` or `_: Ui` and `Ti <: Ui`.
4747

4848
Auto-tupling composes with eta-expansion. That is an n-ary function generated by eta-expansion
4949
can in turn be adapted to the expected type with auto-tupling.
5050

51-
#### Term addaptation
51+
#### Term adaptation
5252

53-
If the a function
53+
If the function
5454
```scala
5555
(p1: T1, ..., pn: Tn) => e
5656
```
@@ -73,7 +73,7 @@ Translation of such a tuples would use the `apply` method on the tuple to access
7373

7474
### Migration
7575

76-
Code like this could not be written before, hence the new notation would not be ambigouous after adoption.
76+
Code like this could not be written before, hence the new notation would not be ambiguous after adoption.
7777

7878
Though it is possible that someone has written an implicit conversion form `(T1, ..., Tn) => R` to `TupleN[T1, ..., Tn] => R`
7979
for some `n`. This change could be detected and fixed by `Scalafix`. Furthermore, such conversion would probably

docs/docs/reference/other-new-features/threadUnsafe-annotation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ layout: doc-page
33
title: threadUnsafe annotation
44
---
55

6-
A new annotation `@threadUnsafe` can be used on a field which defines a lazy
7-
val. When this annotation is used, the initialization of the lazy val will use a
6+
A new annotation `@threadUnsafe` can be used on a field which defines a `lazy
7+
val`. When this annotation is used, the initialization of the lazy val will use a
88
faster mechanism which is not thread-safe.
99

1010
### Example

docs/docs/reference/other-new-features/tupled-function.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,19 @@ sealed trait TupledFunction[F, G] {
2626
The compiler will synthesize an instance of `TupledFunction[F, G]` if:
2727

2828
* `F` is a function type of arity `N`
29-
* `G` is a function with a single tuple argument of size `N` and it's types are equal to the arguments of `F`
29+
* `G` is a function with a single tuple argument of size `N` and its types are equal to the arguments of `F`
3030
* The return type of `F` is equal to the return type of `G`
31-
* `F` and `G` are the same kind of function (both are `(...) => R` or both are `(...) ?=> R`)
31+
* `F` and `G` are the same sort of function (both are `(...) => R` or both are `(...) ?=> R`)
3232
* If only one of `F` or `G` is instantiated the second one is inferred.
3333

3434
Examples
3535
--------
36-
`TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-tupled.scala))
36+
`TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities.
37+
The following defines `tupled` as [extension method](../contextual/extension-methods.html) ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-tupled.scala)).
3738

3839
```scala
3940
/** Creates a tupled version of this function: instead of N arguments,
40-
* it accepts a single [[scala.Tuple]] argument.
41+
* it accepts a single [[scala.Tuple]] with N elements as argument.
4142
*
4243
* @tparam F the function type
4344
* @tparam Args the tuple type with the same types as the function arguments of F
@@ -46,11 +47,11 @@ Examples
4647
def [F, Args <: Tuple, R](f: F).tupled(using tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f)
4748
```
4849

49-
`TupledFunction` can be used to generalize the `Function.untupled` methods to functions of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-untupled.scala))
50+
`TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-untupled.scala))
5051

5152
```scala
52-
/** Creates an untupled version of this function: instead of single [[scala.Tuple]] argument,
53-
* it accepts a N arguments.
53+
/** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements,
54+
* it accepts N arguments.
5455
*
5556
* This is a generalization of [[scala.Function.untupled]] that work on functions of any arity
5657
*
@@ -64,7 +65,7 @@ def [F, Args <: Tuple, R](f: Args => R).untupled(using tf: TupledFunction[F, Arg
6465
`TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/blob/master/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples.
6566

6667
```scala
67-
/** Composes two instances of TupledFunctions in a new TupledFunctions, with this function applied last
68+
/** Composes two instances of TupledFunction into a new TupledFunction, with this function applied last.
6869
*
6970
* @tparam F a function type
7071
* @tparam G a function type

docs/docs/reference/soft-modifier.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ title: Soft Modifiers
44
---
55

66
A soft modifier is one of the identifiers `opaque` and `inline`.
7+
<!--
8+
TODO this is most likely outdated should at least contain `extension` in addition.
9+
Worth maintaining? or maybe better refer to internal/syntax.md ?
10+
-->
711

812
It is treated as a potential modifier of a definition, if it is followed by a hard modifier or a keyword combination starting a definition (`def`, `val`, `var`, `type`, `class`, `case class`, `trait`, `object`, `case object`, `enum`). Between the two words there may be a sequence of newline tokens and soft modifiers.
913

tests/run/tupled-function-tupled.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ object Test {
1616
}
1717

1818
/** Creates a tupled version of this function: instead of N arguments,
19-
* it accepts a single [[scala.Tuple]] argument.
19+
* it accepts a single [[scala.Tuple]] with N elements as argument.
2020
*
2121
* This is a generalization of [[scala.FunctionN.tupled]] that work on functions of any arity
2222
*

tests/run/tupled-function-untupled.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ object Test {
9595

9696
}
9797

98-
/** Creates an untupled version of this function: instead of single [[scala.Tuple]] argument,
99-
* it accepts a N arguments.
98+
/** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements,
99+
* it accepts N arguments.
100100
*
101101
* This is a generalization of [[scala.Function.untupled]] that work on functions of any arity
102102
*

0 commit comments

Comments
 (0)