diff --git a/docs/_spec/03-types.md b/docs/_spec/03-types.md index cf6d0ad94fb7..7513eb2d782d 100644 --- a/docs/_spec/03-types.md +++ b/docs/_spec/03-types.md @@ -173,7 +173,7 @@ In a sequence of consecutive type infix operations ´t_0 \, \mathit{op} \, t_1 \ 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) ...)´. The type operators `|` and `&` are not really special. -Nevertheless, unless shadowed, they resolve to `scala.|` and `scala.&`, which represent [union and intersection types](#union-and-intersection-types), respectively. +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. ### Function Types @@ -230,6 +230,21 @@ scala.PolyFunction { } ``` +### Tuple Types + +```ebnf +SimpleType1 ::= ... + | ‘(’ TypesOrWildcards ‘)’ +``` + +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]]]`. +The ´T_i´ can be wildcard type arguments. + +Notes: + +- `(´T_1´)` is the type ´T_1´, and not `´T_1´ *: scala.EmptyTuple` (´T_1´ cannot be a wildcard type argument in that case). +- `()` is not a valid type (not even `scala.EmptyTuple`). + ### Concrete Refined Types ```ebnf @@ -285,7 +300,7 @@ _Types_ are either _proper types_, _type constructors_ or _poly-kinded types_. All types live in a single lattice with respect to a [_conformance_](#conformance) relationship ´<:´. The _top type_ is `AnyKind` and the _bottom type_ is `Nothing`: all types conform to `AnyKind`, and `Nothing` conforms to all types. -They can be referred to as the standard library entities `scala.AnyKind` and `scala.Nothing`, respectively. +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. Types can be _concrete_ or _abstract_. 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. - ´S_i´ and ´T_i´ are types and ´S_i =:= T_i´, or - ´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 - ´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"). -- ´T = q.C[T_1, ..., T_n]´ with ´n \geq 0´ and `baseType(´S´, ´C´)` is defined and `baseType(´S´, ´C´) ´<: T´. +- ´T = q.C[T_1, ..., T_n]´ with ´n \geq 0´ and `baseType(´S´, ´C´)` is defined and `baseType(´S´, ´C´) ´<: T´`. - ´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´. - ´S = p.C´ and `´T = C´.this` and ´C´ is the hidden class of an `object` and: - ´p = \epsilon´ or ´p´ is a package ref, or @@ -1129,6 +1144,7 @@ Note that the conditions are not all mutually exclusive. - ´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´. - `´S = S_1´ { ´R´ }` and ´S_1 <: T´. - `´S =´ { ´\alpha´ => ´S_1´ }` and ´S_1 <: T´. +- `´T =´ scala.Tuple´_n[T_1, ..., T_n]´` with ´1 \leq n \leq 22´, and `´S <: T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple`. We define `isSubPrefix(´p´, ´q´)` where ´p´ and ´q´ are prefixes as: diff --git a/docs/_spec/12-the-scala-standard-library.md b/docs/_spec/12-the-scala-standard-library.md index 3ef55647fb45..df8626b5119c 100644 --- a/docs/_spec/12-the-scala-standard-library.md +++ b/docs/_spec/12-the-scala-standard-library.md @@ -12,10 +12,23 @@ Some of these classes are described in the following. ![Class hierarchy of Scala](public/images/classhierarchy.png) + +## Fundamental Type Aliases + +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: + +```scala +type AnyKind = ´x´ // where ´x´ is the internal AnyKind type +type Nothing = ´x´ // where ´x´ is the internal Nothing type +type | = [A, B] =>> A ´|´ B // where | is the internal union type operator +type & = [A, B] =>> A ´&´ B // where & is the internal intersection type operator +``` + ## Root Classes -The root of this hierarchy is formed by class `Any`. +The root of this hierarchy is formed by class `scala.Any`. Every class in a Scala execution environment inherits directly or indirectly from this class. +By definition, `Any` is also the top [proper type](./03-types.html#proper-types). Class `Any` has two direct subclasses: `AnyRef` and `AnyVal`. 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´) { --> ### The `Function` Classes -For each class type `Function´n´` where ´n = 0, ..., 22´, Scala defines the following function class: +For each natural ´n \geq 0´, the `scala` package defines the following function class: ```scala package scala trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]: def apply(´x_1´: ´T_1´, ..., ´x_n´: ´T_n´): ´R´ - override def toString = "" - def curried: ´T_1´ => ... => ´T_n´ => R = ... - def tupled: ((´T_1´, ..., ´T_n´)) => R = ... ``` -For function types `Function´n´` where ´n > 22´, Scala defines a unique function class: +These classes participate in the desugaring of [concrete function types](./03-types.html#function-types). +For values of ´n \leq 22´, the `Function´_n´` classes define additional methods: ```scala package scala -trait FunctionXXL: - def apply(xs: IArray[Object]): Object - override def toString = "" +trait Function´_n´[-´T_1´, ..., -´T_n´, +´R´]: + ... + override def toString = "" + def curried: ´T_1´ => ... => ´T_n´ => R = ... + def tupled: ((´T_1´, ..., ´T_n´)) => R = ... ``` -There is no loss of type safety, as the internal representation is still `Function´n´` for all ´n´. -However this means methods `curried` and `tupled` are not available on functions with more than 22 parameters. - The implicitly imported [`Predef`](#the-predef-object) object defines the name `Function` as an alias of `Function1`. - The `PartialFunction` subclass of `Function1` represents functions that (indirectly) specify their domain. 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). ```scala class PartialFunction[-A, +B] extends Function1[A, B] { def isDefinedAt(x: A): Boolean + + ... // various derived methods } ``` +`PartialFunction` participates in the desugaring of [pattern matching anonymous functions](08-pattern-matching.html#pattern-matching-anonymous-functions). + ### Trait `Product` @@ -351,36 +364,55 @@ All enum definitions automatically extend the `reflect.Enum` trait (and generate ### Tuple Classes -Tuple classes are case classes whose fields can be accessed using selectors `_1`, ..., `_n`. -Their functionality is abstracted in the corresponding `scala.Product_´n´` trait. -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). +Tuples are a form of _HLists_ defined by the following classes: ```scala -case class Tuple´_n´[+´T_1´, ..., +´T_n´](_1: ´T_1´, ..., _n: ´T_n´) -extends Product´_n´[´T_1´, ..., ´T_n´] +/** Superclass of all tuples. */ +sealed trait Tuple extends Product: + /** Return a new tuple by prepending the element to `this` tuple. */ + inline def *: [H, This >: this.type <: Tuple] (x: H): H *: This = ... + ... -trait Product´_n´[+´T_1´, ..., +´T_n´] extends Product: - override def productArity = ´n´ - def _1: ´T_1´ +object Tuple: + /** Type of the element at position N in the tuple X. */ + type Elem[X <: Tuple, N <: Int] = ... ... - def _n: ´T_n´ -``` -#### Short-hand syntax +/** A tuple of 0 elements. */ +type EmptyTuple = EmptyTuple.type + +/** A tuple of 0 elements. */ +case object EmptyTuple extends Tuple: + override def toString(): String = "()" + +/** Tuple of arbitrary non-zero arity */ +sealed trait NonEmptyTuple extends Tuple: + /** Get the i-th element of this tuple. */ + inline def apply[This >: this.type <: NonEmptyTuple](n: Int): Elem[This, n.type] = ... + ... -Tuple classes have dedicated syntax. +sealed abstract class *:[+H, +T <: Tuple] extends NonEmptyTuple -```ebnf -SimpleType ::= ‘(’ Types ‘)’ +object `*:` : + def unapply[H, T <: Tuple](x: H *: T): (H, T) = (x.head, x.tail) ``` -A _tuple type_ ´(T_1, ..., T_n)´ where ´n \geq 2´ is an alias for the type `´T_1´ *: ... *: ´T_n´ *: scala.EmptyTuple`. +For ´1 \leq n \leq 22´, the concrete implementations of `*:` are instances of `Tuple´_n´` classes, which also implement corresponding `Product´_n´` traits. +They are defined at least as follows in the standard Scala library (they might also add other methods and implement other traits). + +```scala +trait Product´_n´[+´T_1´, ..., +´T_n´] extends Product: + override def productArity: Int = ´n´ + def _1: ´T_1´ + ... + def _n: ´T_n´ -Notes: -- `(´T´)` is just the type ´T´, and not `´T´ *: scala.EmptyTuple`. -- `()` is not a valid type, and not `scala.EmptyTuple`. +final case class Tuple´_n´[+´T_1´, ..., +´T_n´](_1: ´T_1´, ..., _n: ´T_n´) + extends *:[´T_1´, ´T_2´ *: ... _: ´T_n´ *: EmptyTuple] + with Product´_n´[´T_1´, ..., ´T_n´] +``` -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´]`. +For ´n > 22´, the concrete implementations of ´*:´ are instances of implementation-specific private classes. ### Class `Array`