Skip to content

Commit 702cae7

Browse files
sjrdKordyjan
authored andcommitted
Spec: Revisit Tuples and Function types.
Also add fundamental type aliases for `AnyKind`, `Nothing`, `&` and `|`. [Cherry-picked 1acafc3]
1 parent 31a4733 commit 702cae7

File tree

2 files changed

+83
-35
lines changed

2 files changed

+83
-35
lines changed

docs/_spec/03-types.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ In a sequence of consecutive type infix operations ´t_0 \, \mathit{op} \, t_1 \
173173
If they are all left-associative, the sequence is interpreted as ´(... (t_0 \mathit{op_1} t_1) \mathit{op_2} ...) \mathit{op_n} t_n´, otherwise it is interpreted as ´t_0 \mathit{op_1} (t_1 \mathit{op_2} ( ... \mathit{op_n} t_n) ...)´.
174174

175175
The type operators `|` and `&` are not really special.
176-
Nevertheless, unless shadowed, they resolve to `scala.|` and `scala.&`, which represent [union and intersection types](#union-and-intersection-types), respectively.
176+
Nevertheless, unless shadowed, they resolve to [the fundamental type aliases `scala.|` and `scala.&`](./12-the-scala-standard-library.html#fundamental-type-aliases), which represent [union and intersection types](#union-and-intersection-types), respectively.
177177

178178
### Function Types
179179

@@ -230,6 +230,21 @@ scala.PolyFunction {
230230
}
231231
```
232232

233+
### Tuple Types
234+
235+
```ebnf
236+
SimpleType1 ::= ...
237+
| ‘(’ TypesOrWildcards ‘)’
238+
```
239+
240+
A _tuple type_ ´(T_1, ..., T_n)´ where ´n \geq 2´ is sugar for the type `´T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple`, which is itself a series of nested infix types which are sugar for `*:[´T_1´, *:[´T_2´, ... *[´T_n´, scala.EmptyTuple]]]`.
241+
The ´T_i´ can be wildcard type arguments.
242+
243+
Notes:
244+
245+
- `(´T_1´)` is the type ´T_1´, and not `´T_1´ *: scala.EmptyTuple` (´T_1´ cannot be a wildcard type argument in that case).
246+
- `()` is not a valid type (not even `scala.EmptyTuple`).
247+
233248
### Concrete Refined Types
234249

235250
```ebnf
@@ -285,7 +300,7 @@ _Types_ are either _proper types_, _type constructors_ or _poly-kinded types_.
285300

286301
All types live in a single lattice with respect to a [_conformance_](#conformance) relationship ´<:´.
287302
The _top type_ is `AnyKind` and the _bottom type_ is `Nothing`: all types conform to `AnyKind`, and `Nothing` conforms to all types.
288-
They can be referred to as the standard library entities `scala.AnyKind` and `scala.Nothing`, respectively.
303+
They can be referred to with [the fundamental type aliases `scala.AnyKind` and `scala.Nothing`](./12-the-scala-standard-library.html#fundamental-type-aliases), respectively.
289304

290305
Types can be _concrete_ or _abstract_.
291306
An abstract type ´T´ always has lower and upper bounds ´L´ and ´H´ such that ´L >: T´ and ´T <: H´.
@@ -1086,7 +1101,7 @@ Note that the conditions are not all mutually exclusive.
10861101
- ´S_i´ and ´T_i´ are types and ´S_i =:= T_i´, or
10871102
- ´S_i´ is a type and ´T_i´ is a wildcard type argument of the form ´? >: L_2 <: H_2´ and ´L_2 <: S_i´ and ´S_i <: H_2´, or
10881103
- ´S_i´ is a wildcard type argument of the form ´? >: L_1 <: H_1´ and ´T_i´ is a wildcard type argument of the form ´? >: L_2 <: H_2´ and ´L_2 <: L_1´ and ´H_1 <: H_2´ (i.e., the ´S_i´ "interval" is contained in the ´T_i´ "interval").
1089-
- ´T = q.C[T_1, ..., T_n]´ with ´n \geq 0´ and `baseType(´S´, ´C´)` is defined and `baseType(´S´, ´C´) ´<: T´.
1104+
- ´T = q.C[T_1, ..., T_n]´ with ´n \geq 0´ and `baseType(´S´, ´C´)` is defined and `baseType(´S´, ´C´) ´<: T´`.
10901105
- ´S = p.X[S_1, ..., S_n]´ and ´p.X´ is non-class type designator and ´H <: T´ where ´H´ is the upper bound of the underlying type definition of ´p.X´.
10911106
- ´S = p.C´ and `´T = C´.this` and ´C´ is the hidden class of an `object` and:
10921107
- ´p = \epsilon´ or ´p´ is a package ref, or
@@ -1129,6 +1144,7 @@ Note that the conditions are not all mutually exclusive.
11291144
- ´S´ is a stable type and ´T = q.x´ is a term designator with underlying type ´T_1´ and ´T_1´ is a stable type and ´S <: T_1´.
11301145
- `´S = S_1´ { ´R´ }` and ´S_1 <: T´.
11311146
- `´S =´ { ´\alpha´ => ´S_1´ }` and ´S_1 <: T´.
1147+
- `´T =´ scala.Tuple´_n[T_1, ..., T_n]´` with ´1 \leq n \leq 22´, and `´S <: T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple`.
11321148

11331149
We define `isSubPrefix(´p´, ´q´)` where ´p´ and ´q´ are prefixes as:
11341150

docs/_spec/12-the-scala-standard-library.md

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,23 @@ Some of these classes are described in the following.
1212
![Class hierarchy of Scala](public/images/classhierarchy.png)
1313

1414
<!-- TODO: Briefly mention scala.deprecated somewhere, and link to [deprecated page](./A%3F-deprecated.md) -->
15+
16+
## Fundamental Type Aliases
17+
18+
The `scala` package provides the following fundamental type aliases, which expose to user code some forms of [types](./03-types.html) that cannot otherwise be written:
19+
20+
```scala
21+
type AnyKind = ´x´ // where ´x´ is the internal AnyKind type
22+
type Nothing = ´x´ // where ´x´ is the internal Nothing type
23+
type | = [A, B] =>> A ´´ B // where | is the internal union type operator
24+
type & = [A, B] =>> A ´&´ B // where & is the internal intersection type operator
25+
```
26+
1527
## Root Classes
1628

17-
The root of this hierarchy is formed by class `Any`.
29+
The root of this hierarchy is formed by class `scala.Any`.
1830
Every class in a Scala execution environment inherits directly or indirectly from this class.
31+
By definition, `Any` is also the top [proper type](./03-types.html#proper-types).
1932
Class `Any` has two direct subclasses: `AnyRef` and `AnyVal`.
2033

2134
The subclass `AnyRef` represents all values which are represented as objects in the underlying host system.
@@ -304,42 +317,42 @@ case class Tuple´n´[+T_1, ..., +T_n](_1: T_1, ..., _´n´: T_´n´) {
304317
-->
305318
### The `Function` Classes
306319

307-
For each class type `Function´n´` where ´n = 0, ..., 22´, Scala defines the following function class:
320+
For each natural ´n \geq 0´, the `scala` package defines the following function class:
308321

309322
```scala
310323
package scala
311324
trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]:
312325
def apply(´x_1´: ´T_1´, ..., ´x_n´: ´T_n´): ´R´
313-
override def toString = "<function´_n´>"
314-
def curried: ´T_1´ => ... => ´T_n´ => R = ...
315-
def tupled: ((´T_1´, ..., ´T_n´)) => R = ...
316326
```
317327

318-
For function types `Function´n´` where ´n > 22´, Scala defines a unique function class:
328+
These classes participate in the desugaring of [concrete function types](./03-types.html#function-types).
319329

330+
For values of ´n \leq 22´, the `Function´_n´` classes define additional methods:
320331
```scala
321332
package scala
322-
trait FunctionXXL:
323-
def apply(xs: IArray[Object]): Object
324-
override def toString = "<functionXXL>"
333+
trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]:
334+
...
335+
override def toString = "<function´_n´>"
336+
def curried: ´T_1´ => ... => ´T_n´ => R = ...
337+
def tupled: ((´T_1´, ..., ´T_n´)) => R = ...
325338
```
326339

327-
There is no loss of type safety, as the internal representation is still `Function´n´` for all ´n´.
328-
However this means methods `curried` and `tupled` are not available on functions with more than 22 parameters.
329-
330340
The implicitly imported [`Predef`](#the-predef-object) object defines the name
331341
`Function` as an alias of `Function1`.
332342

333-
<!-- TODO: Remove below ? -->
334343
The `PartialFunction` subclass of `Function1` represents functions that (indirectly) specify their domain.
335344
Use the `isDefined` method to query whether the partial function is defined for a given input (i.e., whether the input is part of the function's domain).
336345

337346
```scala
338347
class PartialFunction[-A, +B] extends Function1[A, B] {
339348
def isDefinedAt(x: A): Boolean
349+
350+
... // various derived methods
340351
}
341352
```
342353

354+
`PartialFunction` participates in the desugaring of [pattern matching anonymous functions](08-pattern-matching.html#pattern-matching-anonymous-functions).
355+
343356
### Trait `Product`
344357
<!-- TODO: Move somewhere else ? -->
345358
<!-- TODO: Could not find more info on which non-Product methods case class automatically define -->
@@ -351,36 +364,55 @@ All enum definitions automatically extend the `reflect.Enum` trait (and generate
351364

352365
### Tuple Classes
353366

354-
Tuple classes are case classes whose fields can be accessed using selectors `_1`, ..., `_n`.
355-
Their functionality is abstracted in the corresponding `scala.Product_´n´` trait.
356-
The _n_-ary tuple class and product trait are defined at least as follows in the standard Scala library (they might also add other methods and implement other traits).
367+
Tuples are a form of _HLists_ defined by the following classes:
357368

358369
```scala
359-
case class Tuple´_n´[+´T_1´, ..., +´T_n´](_1: ´T_1´, ..., _n: ´T_n´)
360-
extends Product´_n´[´T_1´, ..., ´T_n´]
370+
/** Superclass of all tuples. */
371+
sealed trait Tuple extends Product:
372+
/** Return a new tuple by prepending the element to `this` tuple. */
373+
inline def *: [H, This >: this.type <: Tuple] (x: H): H *: This = ...
374+
...
361375

362-
trait Product´_n´[+´T_1´, ..., +´T_n´] extends Product:
363-
override def productArity = ´n´
364-
def _1: ´T_1´
376+
object Tuple:
377+
/** Type of the element at position N in the tuple X. */
378+
type Elem[X <: Tuple, N <: Int] = ...
365379
...
366-
def _n: ´T_n´
367-
```
368380

369-
#### Short-hand syntax
381+
/** A tuple of 0 elements. */
382+
type EmptyTuple = EmptyTuple.type
383+
384+
/** A tuple of 0 elements. */
385+
case object EmptyTuple extends Tuple:
386+
override def toString(): String = "()"
387+
388+
/** Tuple of arbitrary non-zero arity */
389+
sealed trait NonEmptyTuple extends Tuple:
390+
/** Get the i-th element of this tuple. */
391+
inline def apply[This >: this.type <: NonEmptyTuple](n: Int): Elem[This, n.type] = ...
392+
...
370393

371-
Tuple classes have dedicated syntax.
394+
sealed abstract class *:[+H, +T <: Tuple] extends NonEmptyTuple
372395

373-
```ebnf
374-
SimpleType ::= ‘(’ Types ‘)’
396+
object `*:` :
397+
def unapply[H, T <: Tuple](x: H *: T): (H, T) = (x.head, x.tail)
375398
```
376399

377-
A _tuple type_ ´(T_1, ..., T_n)´ where ´n \geq 2´ is an alias for the type `´T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple`.
400+
For ´1 \leq n \leq 22´, the concrete implementations of `*:` are instances of `Tuple´_n´` classes, which also implement corresponding `Product´_n´` traits.
401+
They are defined at least as follows in the standard Scala library (they might also add other methods and implement other traits).
402+
403+
```scala
404+
trait Product´_n´[+´T_1´, ..., +´T_n´] extends Product:
405+
override def productArity: Int = ´n´
406+
def _1: ´T_1´
407+
...
408+
def _n: ´T_n´
378409

379-
Notes:
380-
- `(´T´)` is just the type ´T´, and not `´T´ *: scala.EmptyTuple`.
381-
- `()` is not a valid type, and not `scala.EmptyTuple`.
410+
final case class Tuple´_n´[+´T_1´, ..., +´T_n´](_1: ´T_1´, ..., _n: ´T_n´)
411+
extends *:T_1´, ´T_2´ *: ... _: ´T_n´ *: EmptyTuple]
412+
with Product´_n´[´T_1´, ..., ´T_n´]
413+
```
382414

383-
If ´n \leq 22´, the type `´T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple` is both a subtype and a supertype of tuple class `scala.Tuple´_n´[´T_1´, ..., ´T_n´]`.
415+
For ´n > 22´, the concrete implementations of ´*:´ are instances of implementation-specific private classes.
384416

385417
### Class `Array`
386418

0 commit comments

Comments
 (0)