Skip to content

Commit 9ec07a2

Browse files
committed
Spec: Adapt basic declarations to the new type system.
1 parent d83aa49 commit 9ec07a2

File tree

2 files changed

+56
-57
lines changed

2 files changed

+56
-57
lines changed

docs/_spec/03-types.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ A _type lambda_ of the form `[´\pm a_1 >: L_1 <: H_1´, ..., ´\pm a_n >: L_n <
370370
When applied to ´n´ type arguments that conform to the specified bounds, it produces another type ´U´.
371371
Type lambdas are always concrete types.
372372

373+
The scope of a type parameter extends over the result type ´U´ as well as the bounds of the type parameters themselves.
374+
373375
All type constructors conform to some type lambda.
374376

375377
The type bounds of the parameters of a type lambda are in contravariant position, while its result type is in covariant position.

docs/_spec/04-basic-declarations-and-definitions.md

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ Def ::= PatVarDef
1919
| TmplDef
2020
```
2121

22-
A _declaration_ introduces names and assigns them types.
23-
It can form part of a [class definition](05-classes-and-objects.html#templates) or of a refinement in a [compound type](03-types.html#compound-types).
22+
A _declaration_ introduces names and assigns them types or type definitions.
23+
It can form part of a [class definition](05-classes-and-objects.html#templates) or of a refinement in a [refined type](03-types.html#concrete-refined-types).
2424

2525
A _definition_ introduces names that denote terms or types.
2626
It can form part of an object or class definition or it can be local to a block.
@@ -61,11 +61,11 @@ PatDef ::= Pattern2 {‘,’ Pattern2} [‘:’ Type] ‘=’ Expr
6161
ids ::= id {‘,’ id}
6262
```
6363

64-
A value declaration `val ´x´: ´T´` introduces ´x´ as a name of a value of type ´T´.
64+
A value declaration `val ´x´: ´T´` introduces ´x´ as a name of a value of _declared type_ ´T´.
6565

6666
A value definition `val ´x´: ´T´ = ´e´` defines ´x´ as a name of the value that results from the evaluation of ´e´.
67-
If the value definition is not recursive, the type ´T´ may be omitted, in which case the [packed type](06-expressions.html#expression-typing) of expression ´e´ is assumed.
68-
If a type ´T´ is given, then ´e´ is expected to conform to it.
67+
If the value definition is not recursive, the declared type ´T´ may be omitted, in which case the [packed type](06-expressions.html#expression-typing) of expression ´e´ is assumed.
68+
If a type ´T´ is given, then it must be a [proper type](03-types.html#proper-types) and ´e´ is expected to [conform to it](06-expressions.html#expression-typing).
6969

7070
Evaluation of the value definition implies evaluation of its right-hand side ´e´, unless it has the modifier `lazy`.
7171
The effect of the value definition is to bind ´x´ to the value of ´e´
@@ -156,7 +156,7 @@ An implementation of a class may _define_ a declared variable using a variable d
156156

157157
A variable definition `var ´x´: ´T´ = ´e´` introduces a mutable variable with type ´T´ and initial value as given by the expression ´e´.
158158
The type ´T´ can be omitted, in which case the type of ´e´ is assumed.
159-
If ´T´ is given, then ´e´ is expected to [conform to it](06-expressions.html#expression-typing).
159+
If ´T´ is given, then it must be a [proper type](03-types.html#proper-types) and ´e´ is expected to [conform to it](06-expressions.html#expression-typing).
160160

161161
Variable definitions can alternatively have a [pattern](08-pattern-matching.html#patterns) as left-hand side.
162162
A variable definition `var ´p´ = ´e´` where ´p´ is a pattern other than a simple name or a name followed by a colon and a type is expanded in the same way as a [value definition](#value-declarations-and-definitions) `val ´p´ = ´e´`, except that the free names in ´p´ are introduced as mutable variables, not values.
@@ -217,41 +217,55 @@ A variable definition `var ´x_1, ..., x_n: T´ = ´e´` is a shorthand for the
217217

218218
## Type Declarations and Type Aliases
219219

220-
<!-- TODO: Higher-kinded tdecls should have a separate section -->
221-
222220
```ebnf
223221
Dcl ::= ‘type’ {nl} TypeDcl
224222
TypeDcl ::= id [TypeParamClause] [‘>:’ Type] [‘<:’ Type]
225223
Def ::= ‘type’ {nl} TypeDef
226224
TypeDef ::= id [TypeParamClause] ‘=’ Type
227225
```
228226

227+
A possibly parameterized _type declaration_ `type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´H´` declares ´t´ to be an abstract type.
228+
If omitted, ´L´ and ´H´ are implied to be `Nothing` and `scala.Any`, respectively.
229+
230+
A possibly parameterized _type alias_ `type ´t´[´\mathit{tps}\,´] = ´T´` defines ´t´ to be a concrete type member.
231+
232+
If a type parameter clause `[´\mathit{tps}\,´]` is present, it is desugared away according to the rules in the following section.
233+
229234
### Desugaring of parameterized type declarations
230-
A parameterized type declaration is desugared into an unparameterized type declaration
231-
whose bounds are type lambdas with explicit variance annotations.
235+
236+
A parameterized type declaration is desugared into an unparameterized type declaration whose bounds are [type lambdas](03-types.html#type-lambdas) with explicit variance annotations.
237+
238+
The scope of a type parameter extends over the bounds `>: ´L´ <: ´U´` or the alias `= ´T´` and the type parameter clause ´\mathit{tps}´ itself.
239+
A higher-order type parameter clause (of an abstract type constructor ´tc´) has the same kind of scope, restricted to the declaration of the type parameter ´tc´.
240+
241+
To illustrate nested scoping, these declarations are all equivalent: `type t[m[x] <: Bound[x], Bound[x]]`, `type t[m[x] <: Bound[x], Bound[y]]` and `type t[m[x] <: Bound[x], Bound[_]]`, as the scope of, e.g., the type parameter of ´m´ is limited to the declaration of ´m´.
242+
In all of them, ´t´ is an abstract type member that abstracts over two type constructors: ´m´ stands for a type constructor that takes one type parameter and that must be a subtype of `Bound`, ´t´'s second type constructor parameter.
243+
`t[MutableList, Iterable]` is a valid use of ´t´.
232244

233245
#### Abstract Type
234-
An abstract type
246+
247+
A parameterized abstract type
235248
```scala
236-
type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´U´
249+
type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´H´
237250
```
238251
is desugared into an unparameterized abstract type as follow:
239252
- If `L` conforms to `Nothing`, then,
240253

241254
```scala
242255
type ´t´ >: Nothing
243-
<:\mathit{tps'}\,´] =>> ´U´
256+
<:\mathit{tps'}\,´] =>> ´H´
244257
```
245258
- otherwise,
246259

247260
```scala
248261
type ´t´ >:\mathit{tps'}\,´] =>> ´L´
249-
<:\mathit{tps'}\,´] =>> ´U´
262+
<:\mathit{tps'}\,´] =>> ´H´
250263
```
251-
252-
If at least one of the ´\mathit{tps}´ contains an explicit variance annotation, then ´\mathit{tps'} = \mathit{tps}´, otherwise we infer the variance of each type parameter as with the user-written type lambda `[´\mathit{tps}\,´] =>> ´U´`.
253264

254-
The same desugaring applies to type parameters. For instance,
265+
If at least one of the ´\mathit{tps}´ contains an explicit variance annotation, then ´\mathit{tps'} = \mathit{tps}´, otherwise we infer the variance of each type parameter as with the user-written type lambda `[´\mathit{tps}\,´] =>> ´H´`.
266+
267+
The same desugaring applies to type parameters.
268+
For instance,
255269
```scala
256270
[F[X] <: Coll[X]]
257271
```
@@ -261,6 +275,7 @@ is treated as a shorthand for
261275
```
262276

263277
#### Type Alias
278+
264279
A parameterized type alias
265280
```scala
266281
type ´t´[´\mathit{tps}\,´] = ´T´
@@ -271,34 +286,17 @@ type ´t´ = [´\mathit{tps'}\,´] =>> ´T´
271286
```
272287
where ´\mathit{tps'}´ is computed as in the previous case.
273288

274-
´\color{red}{\text{TODO SCALA3: Everything else in this section (and the next one
275-
on type parameters) needs to be rewritten to take into account the desugaring described above.}}´
289+
### Non-Parameterized Type Declarations and Type Aliases
276290

277-
A _type declaration_ `type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´U´` declares ´t´ to be an abstract type with lower bound type ´L´ and upper bound type ´U´.
278-
If the type parameter clause `[´\mathit{tps}\,´]` is omitted, ´t´ abstracts over a proper type, otherwise ´t´ stands for a type constructor that accepts type arguments as described by the type parameter clause.
291+
A _type declaration_ `type ´t´ >: ´L´ <: ´H´` declares ´t´ to be an abstract type whose [type definition](03-types.html#type-definitions) has the lower bound type ´L´ and upper bound type ´H´.
279292

280-
If a type declaration appears as a member declaration of a type, implementations of the type may implement ´t´ with any type ´T´ for which ´L <: T <: U´.
281-
It is a compile-time error if ´L´ does not conform to ´U´.
282-
Either or both bounds may be omitted.
283-
If the lower bound ´L´ is absent, the bottom type `scala.Nothing` is assumed.
284-
If the upper bound ´U´ is absent, the top type `scala.Any` is assumed.
285-
286-
A type constructor declaration imposes additional restrictions on the concrete types for which ´t´ may stand.
287-
Besides the bounds ´L´ and ´U´, the type parameter clause may impose higher-order bounds and variances, as governed by the [conformance of type constructors](03-types.html#conformance).
288-
289-
The scope of a type parameter extends over the bounds `>: ´L´ <: ´U´` and the type parameter clause ´\mathit{tps}´ itself.
290-
A higher-order type parameter clause (of an abstract type constructor ´tc´) has the same kind of scope, restricted to the declaration of the type parameter ´tc´.
291-
292-
To illustrate nested scoping, these declarations are all equivalent: `type t[m[x] <: Bound[x], Bound[x]]`, `type t[m[x] <: Bound[x], Bound[y]]` and `type t[m[x] <: Bound[x], Bound[_]]`, as the scope of, e.g., the type parameter of ´m´ is limited to the declaration of ´m´.
293-
In all of them, ´t´ is an abstract type member that abstracts over two type constructors: ´m´ stands for a type constructor that takes one type parameter and that must be a subtype of ´Bound´, ´t´'s second type constructor parameter.
294-
`t[MutableList, Iterable]` is a valid use of ´t´.
293+
If a type declaration appears as a member declaration of a type, implementations of the type may implement ´t´ with any type ´T´ for which ´L <: T <: H´.
294+
It is a compile-time error if ´L´ does not conform to ´H´.
295295

296296
A _type alias_ `type ´t´ = ´T´` defines ´t´ to be an alias name for the type ´T´.
297-
The left hand side of a type alias may have a type parameter clause, e.g. `type ´t´[´\mathit{tps}\,´] = ´T´`.
298-
The scope of a type parameter extends over the right hand side ´T´ and the type parameter clause ´\mathit{tps}´ itself.
299297

300-
The scope rules for [definitions](#basic-declarations-and-definitions) and [type parameters](#method-declarations-and-definitions) make it possible that a type name appears in its own bound or in its right-hand side.
301-
However, it is a static error if a type alias refers recursively to the defined type constructor itself.
298+
The scope rules for [definitions](#basic-declarations-and-definitions) and [type parameters](#method-declarations-and-definitions) make it possible that a type name appears in its own bounds or in its right-hand side.
299+
However, it is a static error if a type alias refers recursively to the defined type itself.
302300
That is, the type ´T´ in a type alias `type ´t´[´\mathit{tps}\,´] = ´T´` may not refer directly or indirectly to the name ´t´.
303301
It is also an error if an abstract type is directly or indirectly its own upper or lower bound.
304302

@@ -309,8 +307,8 @@ The following are legal type declarations and definitions:
309307
```scala
310308
type IntList = List[Integer]
311309
type T <: Comparable[T]
312-
type Two[A] = Tuple2[A, A]
313-
type MyCollection[+X] <: Iterable[X]
310+
type Two[A] = Tuple2[A, A] // desugars to Two = [A] =>> Tuple2[A, A]
311+
type MyCollection[+X] <: Iterable[X] // desugars to MyCollection <: [+X] =>> Iterable[X]
314312
```
315313

316314
The following are illegal:
@@ -323,11 +321,11 @@ type T <: S
323321

324322
type T >: Comparable[T.That] // Cannot select from T.
325323
// T is a type, not a value
326-
type MyCollection <: Iterable // Type constructor members must explicitly
327-
// state their type parameters.
324+
type MyCollection <: Iterable // The reference to the type constructor
325+
// Iterable must explicitly state its type arguments.
328326
```
329327

330-
If a type alias `type ´t´[´\mathit{tps}\,´] = ´S´` refers to a class type ´S´, the name ´t´ can also be used as a constructor for objects of type ´S´.
328+
If a type alias `type ´t´ = ´S´` refers to a class type ´S´ (or to a type lambda that is the eta-expansion of class type ´S´), the name ´t´ can also be used as a constructor for objects of type ´S´.
331329

332330
###### Example
333331

@@ -432,22 +430,21 @@ The variance position changes at the following constructs.
432430
- The variance position of the lower bound of a type declaration or type parameter is the opposite of the variance position of the type declaration or parameter.
433431
- The type of a mutable variable is always in invariant position.
434432
- The right-hand side of a type alias is always in invariant position.
435-
- The prefix ´S´ of a type selection `´S´#´T´` is always in invariant position.
436-
- For a type argument ´T´ of a type `´S´[´... T ...´ ]`:
437-
If the corresponding type parameter is invariant, then ´T´ is in invariant position.
438-
If the corresponding type parameter is contravariant, the variance position of ´T´ is the opposite of the variance position of the enclosing type `´S´[´... T ...´ ]`.
439-
440-
<!-- TODO: handle type aliases -->
433+
- The prefix ´p´ of a type selection `´p.T´` is always in invariant position.
434+
- For a type argument ´T´ of a type `´S´[´..., T, ...´]`:
435+
- If the corresponding type parameter of ´S´ is invariant, then ´T´ is in invariant position.
436+
- If the corresponding type parameter of ´S´ is contravariant, the variance position of ´T´ is the opposite of the variance position of the enclosing type `´S´[´..., T, ...´]`.
441437

442-
References to the type parameters in [object-private or object-protected values, types, variables, or methods](05-classes-and-objects.html#modifiers) of the class are not checked for their variance position.
438+
References to the type parameters in [object-private values, types, variables, or methods](05-classes-and-objects.html#modifiers) of the class are not checked for their variance position.
443439
In these members the type parameter may appear anywhere without restricting its legal variance annotations.
444440

445441
###### Example
446442
The following variance annotation is legal.
447443

448444
```scala
449445
abstract class P[+A, +B] {
450-
def fst: A; def snd: B
446+
def fst: A
447+
def snd: B
451448
}
452449
```
453450

@@ -471,14 +468,14 @@ If the mutable variables are object-private, the class definition becomes legal
471468

472469
```scala
473470
abstract class R[+A, +B](x: A, y: B) {
474-
private[this] var fst: A = x // OK
475-
private[this] var snd: B = y // OK
471+
private var fst: A = x // OK
472+
private var snd: B = y // OK
476473
}
477474
```
478475

479476
###### Example
480477

481-
The following variance annotation is illegal, since ´a´ appears in contravariant position in the parameter of `append`:
478+
The following variance annotation is illegal, since ´A´ appears in contravariant position in the parameter of `append`:
482479

483480
```scala
484481
abstract class Sequence[+A] {
@@ -591,7 +588,7 @@ ParamType ::= ‘=>’ Type
591588
```
592589

593590
The type of a value parameter may be prefixed by `=>`, e.g. `´x´: => ´T´`.
594-
The type of such a parameter is then the parameterless method type `=> ´T´`.
591+
The type of such a parameter is then the [by-name type](./03-types.html#by-name-types) `=> ´T´`.
595592
This indicates that the corresponding argument is not evaluated at the point of method application, but instead is evaluated at each use within the method.
596593
That is, the argument is evaluated using _call-by-name_.
597594

0 commit comments

Comments
 (0)