summaryrefslogtreecommitdiff
path: root/spec/03-types.md
diff options
context:
space:
mode:
authorAntoine Gourlay <antoine@gourlay.fr>2014-09-15 12:08:51 +0200
committerAntoine Gourlay <antoine@gourlay.fr>2014-09-17 13:40:09 +0200
commit3b0c71df60a41e13e47ec9ae8dbc606e1928aba8 (patch)
tree306897801df10e0318b454c67738156997e4b29d /spec/03-types.md
parentbca19f35103c4ff1205e1c8054eb3f803217a18b (diff)
downloadscala-3b0c71df60a41e13e47ec9ae8dbc606e1928aba8.tar.gz
scala-3b0c71df60a41e13e47ec9ae8dbc606e1928aba8.tar.bz2
scala-3b0c71df60a41e13e47ec9ae8dbc606e1928aba8.zip
spec: remove trailing whitespace everywhere
Diffstat (limited to 'spec/03-types.md')
-rw-r--r--spec/03-types.md281
1 files changed, 128 insertions, 153 deletions
diff --git a/spec/03-types.md b/spec/03-types.md
index 29e6426530..5cfb85e1fc 100644
--- a/spec/03-types.md
+++ b/spec/03-types.md
@@ -11,9 +11,9 @@ chapter: 3
| InfixType [ExistentialClause]
FunctionArgTypes ::= InfixType
| ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’
- ExistentialClause ::= ‘forSome’ ‘{’ ExistentialDcl
+ ExistentialClause ::= ‘forSome’ ‘{’ ExistentialDcl
{semi ExistentialDcl} ‘}’
- ExistentialDcl ::= ‘type’ TypeDcl
+ ExistentialDcl ::= ‘type’ TypeDcl
| ‘val’ ValDcl
InfixType ::= CompoundType {id [nl] CompoundType}
CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement]
@@ -31,7 +31,7 @@ chapter: 3
We distinguish between first-order types and type constructors, which
take type parameters and yield types. A subset of first-order types
called _value types_ represents sets of (first-class) values.
-Value types are either _concrete_ or _abstract_.
+Value types are either _concrete_ or _abstract_.
Every concrete value type can be represented as a _class type_, i.e. a
[type designator](#type-designators) that refers to a
@@ -39,8 +39,8 @@ Every concrete value type can be represented as a _class type_, i.e. a
[compound type](#compound-types) representing an
intersection of types, possibly with a [refinement](#compound-types)
that further constrains the types of its members.
-<!--
-A shorthand exists for denoting [function types](#function-types)
+<!--
+A shorthand exists for denoting [function types](#function-types)
-->
Abstract value types are introduced by [type parameters](04-basic-declarations-and-definitions.html#type-parameters)
and [abstract type bindings](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases).
@@ -50,20 +50,19 @@ Parentheses in types can be used for grouping.
define a class (of the same name as the object or package, but
inaccessible to user programs).
-Non-value types capture properties of identifiers that
-[are not values](#non-value-types). For example, a
-[type constructor](#type-constructors) does not directly specify a type of
-values. However, when a type constructor is applied to the correct type
-arguments, it yields a first-order type, which may be a value type.
-
-Non-value types are expressed indirectly in Scala. E.g., a method type is
-described by writing down a method signature, which in itself is not a real
-type, although it gives rise to a corresponding [method type](#method-types).
-Type constructors are another example, as one can write
-`type Swap[m[_, _], a,b] = m[b, a]`, but there is no syntax to write
+Non-value types capture properties of identifiers that
+[are not values](#non-value-types). For example, a
+[type constructor](#type-constructors) does not directly specify a type of
+values. However, when a type constructor is applied to the correct type
+arguments, it yields a first-order type, which may be a value type.
+
+Non-value types are expressed indirectly in Scala. E.g., a method type is
+described by writing down a method signature, which in itself is not a real
+type, although it gives rise to a corresponding [method type](#method-types).
+Type constructors are another example, as one can write
+`type Swap[m[_, _], a,b] = m[b, a]`, but there is no syntax to write
the corresponding anonymous type function directly.
-
## Paths
```ebnf
@@ -83,19 +82,18 @@ A path is one of the following.
- The empty path ε (which cannot be written explicitly in user programs).
- $C.$`this`, where $C$ references a class.
The path `this` is taken as a shorthand for $C.$`this` where
- $C$ is the name of the class directly enclosing the reference.
+ $C$ is the name of the class directly enclosing the reference.
- $p.x$ where $p$ is a path and $x$ is a stable member of $p$.
- _Stable members_ are packages or members introduced by object definitions or
+ _Stable members_ are packages or members introduced by object definitions or
by value definitions of [non-volatile types](#volatile-types).
- $C.$`super`$.x$ or $C.$`super`$[M].x$
- where $C$ references a class and $x$ references a
- stable member of the super class or designated parent class $M$ of $C$.
+ where $C$ references a class and $x$ references a
+ stable member of the super class or designated parent class $M$ of $C$.
The prefix `super` is taken as a shorthand for $C.$`super` where
- $C$ is the name of the class directly enclosing the reference.
+ $C$ is the name of the class directly enclosing the reference.
A _stable identifier_ is a path which ends in an identifier.
-
## Value Types
Every value in Scala has a type which is of one of the following
@@ -110,7 +108,7 @@ SimpleType ::= Path ‘.’ type
A singleton type is of the form $p.$`type`, where $p$ is a
path pointing to a value expected to [conform](06-expressions.html#expression-typing)
to `scala.AnyRef`. The type denotes the set of values
-consisting of `null` and the value denoted by $p$.
+consisting of `null` and the value denoted by $p$.
A _stable type_ is either a singleton type or a type which is
declared to be a subtype of trait `scala.Singleton`.
@@ -122,11 +120,11 @@ SimpleType ::= SimpleType ‘#’ id
```
A type projection $T$#$x$ references the type member named
-$x$ of type $T$.
+$x$ of type $T$.
<!--
The following is no longer necessary:
-If $x$ references an abstract type member, then $T$ must be a
+If $x$ references an abstract type member, then $T$ must be a
[stable type](#singleton-types)
-->
@@ -162,8 +160,6 @@ with a type member `Node` and the standard class `scala.Int`,
|scala.Int | scala.type#Int |
|data.maintable.Node | data.maintable.type#Node |
-
-
### Parameterized Types
```ebnf
@@ -172,7 +168,7 @@ TypeArgs ::= ‘[’ Types ‘]’
```
A parameterized type $T[ U_1 , \ldots , U_n ]$ consists of a type
-designator $T$ and type parameters $U_1 , \ldots , U_n$ where
+designator $T$ and type parameters $U_1 , \ldots , U_n$ where
$n \geq 1$. $T$ must refer to a type constructor which takes $n$ type
parameters $a_1 , \ldots , a_n$.
@@ -270,7 +266,6 @@ The following type adds the `@suspendable` annotation to the type `String`:
String @suspendable
```
-
### Compound Types
```ebnf
@@ -283,7 +278,7 @@ RefineStat ::= Dcl
```
A compound type $T_1$ `with` … `with` $T_n \\{ R \\}$
-represents objects with members as given in the component types
+represents objects with members as given in the component types
$T_1 , \ldots , T_n$ and the refinement $\\{ R \\}$. A refinement
$\\{ R \\}$ contains declarations and type definitions.
If a declaration or definition overrides a declaration or definition in
@@ -291,7 +286,7 @@ one of the component types $T_1 , \ldots , T_n$, the usual rules for
[overriding](05-classes-and-objects.html#overriding) apply; otherwise the declaration
or definition is said to be “structural” [^2].
-[^2]: A reference to a structurally defined member (method call or access
+[^2]: A reference to a structurally defined member (method call or access
to a value or variable) may generate binary code that is significantly
slower than an equivalent code to a non-structural member.
@@ -341,7 +336,6 @@ Although `Bird` and `Plane` do not share any parent class other than
refinement with structural declarations to accept any object that declares
a value `callsign` and a `fly` method.
-
### Infix Types
```ebnf
@@ -350,7 +344,7 @@ InfixType ::= CompoundType {id [nl] CompoundType}
An infix type $T_1$ `op` $T_2$ consists of an infix
operator `op` which gets applied to two type operands $T_1$ and
-$T_2$. The type is equivalent to the type application
+$T_2$. The type is equivalent to the type application
`op`$[T_1, T_2]$. The infix operator `op` may be an
arbitrary identifier.
@@ -360,13 +354,13 @@ of a type operator is determined as for term operators: type operators
ending in a colon ‘:’ are right-associative; all other
operators are left-associative.
-In a sequence of consecutive type infix operations
+In a sequence of consecutive type infix operations
$t_0 \, \mathit{op} \, t_1 \, \mathit{op_2} \, \ldots \, \mathit{op_n} \, t_n$,
all operators $\mathit{op}\_1 , \ldots , \mathit{op}\_n$ must have the same
associativity. If they are all left-associative, the sequence is
-interpreted as
+interpreted as
$(\ldots (t_0 \mathit{op_1} t_1) \mathit{op_2} \ldots) \mathit{op_n} t_n$,
-otherwise it is interpreted as
+otherwise it is interpreted as
$t_0 \mathit{op_1} (t_1 \mathit{op_2} ( \ldots \mathit{op_n} t_n) \ldots)$.
### Function Types
@@ -380,25 +374,25 @@ FunctionArgs ::= InfixType
The type $(T_1 , \ldots , T_n) \Rightarrow U$ represents the set of function
values that take arguments of types $T1 , \ldots , Tn$ and yield
results of type $U$. In the case of exactly one argument type
-$T \Rightarrow U$ is a shorthand for $(T) \Rightarrow U$.
+$T \Rightarrow U$ is a shorthand for $(T) \Rightarrow U$.
An argument type of the form $\Rightarrow T$
represents a [call-by-name parameter](04-basic-declarations-and-definitions.html#by-name-parameters) of type $T$.
Function types associate to the right, e.g.
-$S \Rightarrow T \Rightarrow U$ is the same as
+$S \Rightarrow T \Rightarrow U$ is the same as
$S \Rightarrow (T \Rightarrow U)$.
Function types are shorthands for class types that define `apply`
-functions. Specifically, the $n$-ary function type
+functions. Specifically, the $n$-ary function type
$(T_1 , \ldots , T_n) \Rightarrow U$ is a shorthand for the class type
`Function$_n$[T1 , … , $T_n$, U]`. Such class
types are defined in the Scala library for $n$ between 0 and 9 as follows.
```scala
-package scala
+package scala
trait Function_n[-T1 , … , -T$_n$, +R] {
- def apply(x1: T1 , … , x$_n$: T$_n$): R
- override def toString = "<function>"
+ def apply(x1: T1 , … , x$_n$: T$_n$): R
+ override def toString = "<function>"
}
```
@@ -409,28 +403,28 @@ result type and contravariant in their argument types.
```ebnf
Type ::= InfixType ExistentialClauses
-ExistentialClauses ::= ‘forSome’ ‘{’ ExistentialDcl
+ExistentialClauses ::= ‘forSome’ ‘{’ ExistentialDcl
{semi ExistentialDcl} ‘}’
-ExistentialDcl ::= ‘type’ TypeDcl
+ExistentialDcl ::= ‘type’ TypeDcl
| ‘val’ ValDcl
```
An existential type has the form `$T$ forSome { $Q$ }`
-where $Q$ is a sequence of
+where $Q$ is a sequence of
[type declarations](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases).
-Let
+Let
$t_1[\mathit{tps}\_1] >: L_1 <: U_1 , \ldots , t_n[\mathit{tps}\_n] >: L_n <: U_n$
be the types declared in $Q$ (any of the
type parameter sections `[ $\mathit{tps}_i$ ]` might be missing).
The scope of each type $t_i$ includes the type $T$ and the existential clause
-$Q$.
-The type variables $t_i$ are said to be _bound_ in the type
+$Q$.
+The type variables $t_i$ are said to be _bound_ in the type
`$T$ forSome { $Q$ }`.
Type variables which occur in a type $T$ but which are not bound in $T$ are said
to be _free_ in $T$.
-A _type instance_ of `$T$ forSome { $Q$ }`
+A _type instance_ of `$T$ forSome { $Q$ }`
is a type $\sigma T$ where $\sigma$ is a substitution over $t_1 , \ldots , t_n$
such that, for each $i$, $\sigma L_i <: \sigma t_i <: \sigma U_i$.
The set of values denoted by the existential type `$T$ forSome {$\,Q\,$}`
@@ -457,21 +451,20 @@ is equivalent to
1. An empty quantification can be dropped. E.g.,
`$T$ forSome { }` is equivalent to $T$.
1. An existential type `$T$ forSome { $Q$ }` where $Q$ contains
-a clause `type $t[\mathit{tps}] >: L <: U$` is equivalent
-to the type `$T'$ forSome { $Q$ }` where $T'$ results from $T$ by replacing
+a clause `type $t[\mathit{tps}] >: L <: U$` is equivalent
+to the type `$T'$ forSome { $Q$ }` where $T'$ results from $T$ by replacing
every [covariant occurrence](04-basic-declarations-and-definitions.html#variance-annotations) of $t$ in $T$ by $U$ and by
replacing every contravariant occurrence of $t$ in $T$ by $L$.
-
#### Existential Quantification over Values
As a syntactic convenience, the bindings clause
in an existential type may also contain
-value declarations `val $x$: $T$`.
+value declarations `val $x$: $T$`.
An existential type `$T$ forSome { $Q$; val $x$: $S\,$;$\,Q'$ }`
is treated as a shorthand for the type
-`$T'$ forSome { $Q$; type $t$ <: $S$ with Singleton; $Q'$ }`, where $t$ is a
-fresh type name and $T'$ results from $T$ by replacing every occurrence of
+`$T'$ forSome { $Q$; type $t$ <: $S$ with Singleton; $Q'$ }`, where $t$ is a
+fresh type name and $T'$ results from $T$ by replacing every occurrence of
`$x$.type` with $t$.
#### Placeholder Syntax for Existential Types
@@ -482,17 +475,17 @@ WildcardType ::= ‘_’ TypeBounds
Scala supports a placeholder syntax for existential types.
A _wildcard type_ is of the form `_$\;$>:$\,L\,$<:$\,U$`. Both bound
-clauses may be omitted. If a lower bound clause `>:$\,L$` is missing,
+clauses may be omitted. If a lower bound clause `>:$\,L$` is missing,
`>:$\,$scala.Nothing`
-is assumed. If an upper bound clause `<:$\,U$` is missing,
-`<:$\,$scala.Any` is assumed. A wildcard type is a shorthand for an
-existentially quantified type variable, where the existential quantification is
+is assumed. If an upper bound clause `<:$\,U$` is missing,
+`<:$\,$scala.Any` is assumed. A wildcard type is a shorthand for an
+existentially quantified type variable, where the existential quantification is
implicit.
A wildcard type must appear as type argument of a parameterized type.
-Let $T = p.c[\mathit{targs},T,\mathit{targs}']$ be a parameterized type where
+Let $T = p.c[\mathit{targs},T,\mathit{targs}']$ be a parameterized type where
$\mathit{targs}, \mathit{targs}'$ may be empty and
-$T$ is a wildcard type `_$\;$>:$\,L\,$<:$\,U$`. Then $T$ is equivalent to the
+$T$ is a wildcard type `_$\;$>:$\,L\,$<:$\,U$`. Then $T$ is equivalent to the
existential
type
@@ -500,7 +493,7 @@ type
$p.c[\mathit{targs},t,\mathit{targs}']$ forSome { type $t$ >: $L$ <: $U$ }
```
-where $t$ is some fresh type variable.
+where $t$ is some fresh type variable.
Wildcard types may also appear as parts of [infix types](#infix-types)
, [function types](#function-types),
or [tuple types](#tuple-types).
@@ -562,20 +555,18 @@ List[java.lang.Number] forSome { type T <: java.lang.Number }
which is in turn equivalent (by simplification rules 2 and 3 above) to
`List[java.lang.Number]`.
-
## Non-Value Types
The types explained in the following do not denote sets of values, nor
do they appear explicitly in programs. They are introduced in this
report as the internal types of defined identifiers.
-
### Method Types
-A method type is denoted internally as $(\mathit{Ps})U$, where $(\mathit{Ps})$
+A method type is denoted internally as $(\mathit{Ps})U$, where $(\mathit{Ps})$
is a sequence of parameter names and types $(p_1:T_1 , \ldots , p_n:T_n)$
for some $n \geq 0$ and $U$ is a (value or method) type. This type
-represents named methods that take arguments named $p_1 , \ldots , p_n$
+represents named methods that take arguments named $p_1 , \ldots , p_n$
of types $T_1 , \ldots , T_n$
and that return a result of type $U$.
@@ -594,7 +585,7 @@ corresponding function type.
###### Example
The declarations
-
+
```
def a: Int
def b (x: Int): Boolean
@@ -612,8 +603,8 @@ c: (Int) (String, String) String
### Polymorphic Method Types
A polymorphic method type is denoted internally as `[$\mathit{tps}\,$]$T$` where
-`[$\mathit{tps}\,$]` is a type parameter section
-`[$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]`
+`[$\mathit{tps}\,$]` is a type parameter section
+`[$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]`
for some $n \geq 0$ and $T$ is a
(value or method) type. This type represents named methods that
take type arguments `$S_1 , \ldots , S_n$` which
@@ -640,8 +631,8 @@ union : [A >: Nothing <: Comparable[A]] (x: Set[A], xs: Set[A]) Set[A]
### Type Constructors
A type constructor is represented internally much like a polymorphic method type.
-`[$\pm$ $a_1$ >: $L_1$ <: $U_1 , \ldots , \pm a_n$ >: $L_n$ <: $U_n$] $T$`
-represents a type that is expected by a
+`[$\pm$ $a_1$ >: $L_1$ <: $U_1 , \ldots , \pm a_n$ >: $L_n$ <: $U_n$] $T$`
+represents a type that is expected by a
[type constructor parameter](04-basic-declarations-and-definitions.html#type-parameters) or an
[abstract type constructor binding](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases) with
the corresponding type parameter clause.
@@ -649,7 +640,7 @@ the corresponding type parameter clause.
###### Example
Consider this fragment of the `Iterable[+X]` class:
-
+
```
trait Iterable[+X] {
def flatMap[newType[+X] <: Iterable[X], S](f: X => newType[S]): newType[S]
@@ -660,7 +651,6 @@ Conceptually, the type constructor `Iterable` is a name for the
anonymous type `[+X] Iterable[X]`, which may be passed to the
`newType` type constructor parameter in `flatMap`.
-
<!-- ### Overloaded Types
More than one values or methods are defined in the same scope with the
@@ -694,7 +684,6 @@ val f = 0
define a function `f} which has type `(x: T)T $\overload$ Int`.
-->
-
## Base Types and Member Definitions
Types of class members depend on the way the members are referenced.
@@ -704,7 +693,6 @@ Central here are three notions, namely:
prefix type $S$,
1. the notion of the set of member bindings of some type $T$.
-
These notions are defined mutually recursively as follows.
1. The set of _base types_ of a type is a set of class types,
@@ -714,25 +702,25 @@ These notions are defined mutually recursively as follows.
`$T_1$ with … with $T_n$ { $R$ }`.
- The base types of an aliased type are the base types of its alias.
- The base types of an abstract type are the base types of its upper bound.
- - The base types of a parameterized type
+ - The base types of a parameterized type
`$C$[$T_1 , \ldots , T_n$]` are the base types
- of type $C$, where every occurrence of a type parameter $a_i$
+ of type $C$, where every occurrence of a type parameter $a_i$
of $C$ has been replaced by the corresponding parameter type $T_i$.
- The base types of a singleton type `$p$.type` are the base types of
the type of $p$.
- - The base types of a compound type
+ - The base types of a compound type
`$T_1$ with $\ldots$ with $T_n$ { $R$ }`
are the _reduced union_ of the base
- classes of all $T_i$'s. This means:
+ classes of all $T_i$'s. This means:
Let the multi-set $\mathscr{S}$ be the multi-set-union of the
base types of all $T_i$'s.
If $\mathscr{S}$ contains several type instances of the same class, say
`$S^i$#$C$[$T^i_1 , \ldots , T^i_n$]` $(i \in I)$, then
- all those instances
+ all those instances
are replaced by one of them which conforms to all
- others. It is an error if no such instance exists. It follows that the
+ others. It is an error if no such instance exists. It follows that the
reduced union, if it exists,
- produces a set of class types, where different types are instances of
+ produces a set of class types, where different types are instances of
different classes.
- The base types of a type selection `$S$#$T$` are
determined as follows. If $T$ is an alias or abstract type, the
@@ -747,26 +735,26 @@ These notions are defined mutually recursively as follows.
makes sense only if the prefix type $S$
has a type instance of class $C$ as a base type, say
`$S'$#$C$[$T_1 , \ldots , T_n$]`. Then we define as follows.
- - If `$S$ = $\epsilon$.type`, then $T$ in $C$ seen from $S$ is
+ - If `$S$ = $\epsilon$.type`, then $T$ in $C$ seen from $S$ is
$T$ itself.
- Otherwise, if $S$ is an existential type `$S'$ forSome { $Q$ }`, and
- $T$ in $C$ seen from $S'$ is $T'$,
+ $T$ in $C$ seen from $S'$ is $T'$,
then $T$ in $C$ seen from $S$ is `$T'$ forSome {$\,Q\,$}`.
- Otherwise, if $T$ is the $i$'th type parameter of some class $D$, then
- - If $S$ has a base type `$D$[$U_1 , \ldots , U_n$]`, for some type
- parameters `[$U_1 , \ldots , U_n$]`, then $T$ in $C$ seen from $S$
+ - If $S$ has a base type `$D$[$U_1 , \ldots , U_n$]`, for some type
+ parameters `[$U_1 , \ldots , U_n$]`, then $T$ in $C$ seen from $S$
is $U_i$.
- Otherwise, if $C$ is defined in a class $C'$, then
$T$ in $C$ seen from $S$ is the same as $T$ in $C'$ seen from $S'$.
- - Otherwise, if $C$ is not defined in another class, then
+ - Otherwise, if $C$ is not defined in another class, then
$T$ in $C$ seen from $S$ is $T$ itself.
- Otherwise, if $T$ is the singleton type `$D$.this.type` for some class $D$
then
- - If $D$ is a subclass of $C$ and $S$ has a type instance of class $D$
+ - If $D$ is a subclass of $C$ and $S$ has a type instance of class $D$
among its base types, then $T$ in $C$ seen from $S$ is $S$.
- Otherwise, if $C$ is defined in a class $C'$, then
$T$ in $C$ seen from $S$ is the same as $T$ in $C'$ seen from $S'$.
- - Otherwise, if $C$ is not defined in another class, then
+ - Otherwise, if $C$ is not defined in another class, then
$T$ in $C$ seen from $S$ is $T$ itself.
- If $T$ is some other type, then the described mapping is performed
to all its type components.
@@ -787,8 +775,6 @@ These notions are defined mutually recursively as follows.
binding $d_T$ of the type `T` in `S`. In that case, we also say
that `S#T` _is defined by_ $d_T$.
-
-
## Relations between types
We define two relations between types.
@@ -798,7 +784,6 @@ We define two relations between types.
|Equivalence |$T \equiv U$ |$T$ and $U$ are interchangeable in all contexts. |
|Conformance |$T <: U$ |Type $T$ conforms to type $U$. |
-
### Equivalence
Equivalence $(\equiv)$ between types is the smallest congruence [^congruence] such that
@@ -812,7 +797,7 @@ the following holds:
consisting only of package or object selectors and ending in $O$, then
`$O$.this.type $\equiv p$.type`.
- Two [compound types](#compound-types) are equivalent if the sequences
- of their component are pairwise equivalent, and occur in the same order, and
+ of their component are pairwise equivalent, and occur in the same order, and
their refinements are equivalent. Two refinements are equivalent if they
bind the same names and the modifiers, types and bounds of every
declared entity are equivalent in both refinements.
@@ -822,43 +807,42 @@ the following holds:
- they have the same number of parameters; and
- corresponding parameters have equivalent types.
Note that the names of parameters do not matter for method type equivalence.
-- Two [polymorphic method types](#polymorphic-method-types) are equivalent if
- they have the same number of type parameters, and, after renaming one set of
+- Two [polymorphic method types](#polymorphic-method-types) are equivalent if
+ they have the same number of type parameters, and, after renaming one set of
type parameters by another, the result types as well as lower and upper bounds
of corresponding type parameters are equivalent.
-- Two [existential types](#existential-types)
+- Two [existential types](#existential-types)
are equivalent if they have the same number of
quantifiers, and, after renaming one list of type quantifiers by
another, the quantified types as well as lower and upper bounds of
corresponding quantifiers are equivalent.
-- Two [type constructors](#type-constructors) are equivalent if they have the
- same number of type parameters, and, after renaming one list of type
- parameters by another, the result types as well as variances, lower and upper
+- Two [type constructors](#type-constructors) are equivalent if they have the
+ same number of type parameters, and, after renaming one list of type
+ parameters by another, the result types as well as variances, lower and upper
bounds of corresponding type parameters are equivalent.
-
[^congruence]: A congruence is an equivalence relation which is closed under formation of contexts
[^implicit]: A method type is implicit if the parameter section that defines it starts with the `implicit` keyword.
### Conformance
-The conformance relation $(<:)$ is the smallest
+The conformance relation $(<:)$ is the smallest
transitive relation that satisfies the following conditions.
- Conformance includes equivalence. If $T \equiv U$ then $T <: U$.
-- For every value type $T$, `scala.Nothing <: $T$ <: scala.Any`.
-- For every type constructor $T$ (with any number of type parameters),
+- For every value type $T$, `scala.Nothing <: $T$ <: scala.Any`.
+- For every type constructor $T$ (with any number of type parameters),
`scala.Nothing <: $T$ <: scala.Any`.
-
-- For every class type $T$ such that `$T$ <: scala.AnyRef` and not
+
+- For every class type $T$ such that `$T$ <: scala.AnyRef` and not
`$T$ <: scala.NotNull` one has `scala.Null <: $T$`.
- A type variable or abstract type $t$ conforms to its upper bound and
- its lower bound conforms to $t$.
+ its lower bound conforms to $t$.
- A class type or parameterized type conforms to any of its base-types.
- A singleton type `$p$.type` conforms to the type of the path $p$.
- A singleton type `$p$.type` conforms to the type `scala.Singleton`.
- A type projection `$T$#$t$` conforms to `$U$#$t$` if $T$ conforms to $U$.
-- A parameterized type `$T$[$T_1$ , … , $T_n$]` conforms to
+- A parameterized type `$T$[$T_1$ , … , $T_n$]` conforms to
`$T$[$U_1$ , … , $U_n$]` if
the following three conditions hold for $i \in \{ 1 , \ldots , n \}$:
1. If the $i$'th type parameter of $T$ is declared covariant, then
@@ -873,63 +857,61 @@ transitive relation that satisfies the following conditions.
binding $d$ of a type or value $x$ in $R$ there exists a member
binding of $x$ in $T$ which subsumes $d$, then $T$ conforms to the
compound type `$U_1$ with $\ldots$ with $U_n$ {$R\,$}`.
-- The existential type `$T$ forSome {$\,Q\,$}` conforms to
+- The existential type `$T$ forSome {$\,Q\,$}` conforms to
$U$ if its [skolemization](#existential-types)
conforms to $U$.
-- The type $T$ conforms to the existential type `$U$ forSome {$\,Q\,$}`
- if $T$ conforms to one of the [type instances](#existential-types)
+- The type $T$ conforms to the existential type `$U$ forSome {$\,Q\,$}`
+ if $T$ conforms to one of the [type instances](#existential-types)
of `$U$ forSome {$\,Q\,$}`.
- If
- $T_i \equiv T'_i$ for $i \in \{ 1 , \ldots , n\}$ and $U$ conforms to $U'$
+ $T_i \equiv T'_i$ for $i \in \{ 1 , \ldots , n\}$ and $U$ conforms to $U'$
then the method type $(p_1:T_1 , \ldots , p_n:T_n) U$ conforms to
$(p'_1:T'_1 , \ldots , p'_n:T'_n) U'$.
- The polymorphic type
- $[a_1 >: L_1 <: U_1 , \ldots , a_n >: L_n <: U_n] T$ conforms to the
+ $[a_1 >: L_1 <: U_1 , \ldots , a_n >: L_n <: U_n] T$ conforms to the
polymorphic type
$[a_1 >: L'_1 <: U'_1 , \ldots , a_n >: L'_n <: U'_n] T'$ if, assuming
- $L'_1 <: a_1 <: U'_1 , \ldots , L'_n <: a_n <: U'_n$
+ $L'_1 <: a_1 <: U'_1 , \ldots , L'_n <: a_n <: U'_n$
one has $T <: T'$ and $L_i <: L'_i$ and $U'_i <: U_i$
for $i \in \{ 1 , \ldots , n \}$.
-- Type constructors $T$ and $T'$ follow a similar discipline. We characterize
+- Type constructors $T$ and $T'$ follow a similar discipline. We characterize
$T$ and $T'$ by their type parameter clauses
$[a_1 , \ldots , a_n]$ and
- $[a_1' , \ldots , a_n']$, where an $a_i$ or $a_i'$ may include a variance
- annotation, a higher-order type parameter clause, and bounds. Then, $T$
- conforms to $T'$ if any list $[t_1 , \ldots , t_n]$ -- with declared
- variances, bounds and higher-order type parameter clauses -- of valid type
- arguments for $T'$ is also a valid list of type arguments for $T$ and
- $T[t_1 , \ldots , t_n] <: T'[t_1 , \ldots , t_n]$. Note that this entails
+ $[a_1' , \ldots , a_n']$, where an $a_i$ or $a_i'$ may include a variance
+ annotation, a higher-order type parameter clause, and bounds. Then, $T$
+ conforms to $T'$ if any list $[t_1 , \ldots , t_n]$ -- with declared
+ variances, bounds and higher-order type parameter clauses -- of valid type
+ arguments for $T'$ is also a valid list of type arguments for $T$ and
+ $T[t_1 , \ldots , t_n] <: T'[t_1 , \ldots , t_n]$. Note that this entails
that:
- - The bounds on $a_i$ must be weaker than the corresponding bounds declared
- for $a'_i$.
- - The variance of $a_i$ must match the variance of $a'_i$, where covariance
+ - The bounds on $a_i$ must be weaker than the corresponding bounds declared
+ for $a'_i$.
+ - The variance of $a_i$ must match the variance of $a'_i$, where covariance
matches covariance, contravariance matches contravariance and any variance
matches invariance.
- Recursively, these restrictions apply to the corresponding higher-order
type parameter clauses of $a_i$ and $a'_i$.
-
A declaration or definition in some compound type of class type $C$
_subsumes_ another declaration of the same name in some compound type or class
type $C'$, if one of the following holds.
-- A value declaration or definition that defines a name $x$ with type $T$
- subsumes a value or method declaration that defines $x$ with type $T'$, provided
+- A value declaration or definition that defines a name $x$ with type $T$
+ subsumes a value or method declaration that defines $x$ with type $T'$, provided
$T <: T'$.
-- A method declaration or definition that defines a name $x$ with type $T$
- subsumes a method declaration that defines $x$ with type $T'$, provided
+- A method declaration or definition that defines a name $x$ with type $T$
+ subsumes a method declaration that defines $x$ with type $T'$, provided
$T <: T'$.
- A type alias
- `type $t$[$T_1$ , … , $T_n$] = $T$` subsumes a type alias
- `type $t$[$T_1$ , … , $T_n$] = $T'$` if $T \equiv T'$.
+ `type $t$[$T_1$ , … , $T_n$] = $T$` subsumes a type alias
+ `type $t$[$T_1$ , … , $T_n$] = $T'$` if $T \equiv T'$.
- A type declaration `type $t$[$T_1$ , … , $T_n$] >: $L$ <: $U$` subsumes
- a type declaration `type $t$[$T_1$ , … , $T_n$] >: $L'$ <: $U'$` if
+ a type declaration `type $t$[$T_1$ , … , $T_n$] >: $L'$ <: $U'$` if
$L' <: L$ and $U <: U'$.
- A type or class definition that binds a type name $t$ subsumes an abstract
type declaration `type t[$T_1$ , … , $T_n$] >: L <: U` if
$L <: t <: U$.
-
The $(<:)$ relation forms pre-order between types,
i.e. it is transitive and reflexive. _least upper bounds_ and
_greatest lower bounds_ of a set of types
@@ -961,23 +943,20 @@ greatest lower of `A` and `B`. If there are several
least upper bounds or greatest lower bounds, the Scala compiler is
free to pick any one of them.
-
[^4]: The current Scala compiler limits the nesting level
of parameterization in such bounds to be at most two deeper than the
maximum nesting level of the operand types
-
-
### Weak Conformance
-In some situations Scala uses a more general conformance relation. A
-type $S$ _weakly conforms_
+In some situations Scala uses a more general conformance relation. A
+type $S$ _weakly conforms_
to a type $T$, written $S <:_w
T$, if $S <: T$ or both $S$ and $T$ are primitive number types
and $S$ precedes $T$ in the following ordering.
```scala
-Byte $<:_w$ Short
+Byte $<:_w$ Short
Short $<:_w$ Int
Char $<:_w$ Int
Int $<:_w$ Long
@@ -988,14 +967,13 @@ Float $<:_w$ Double
A _weak least upper bound_ is a least upper bound with respect to
weak conformance.
-
## Volatile Types
-Type volatility approximates the possibility that a type parameter or abstract
+Type volatility approximates the possibility that a type parameter or abstract
type instance
-of a type does not have any non-null values. A value member of a volatile type
+of a type does not have any non-null values. A value member of a volatile type
cannot appear in a [path](#paths).
-
+
A type is _volatile_ if it falls into one of four categories:
A compound type `$T_1$ with … with $T_n$ {$R\,$}`
@@ -1007,14 +985,13 @@ is volatile if one of the following two conditions hold.
to the compound type, or
1. one of $T_1 , \ldots , T_n$ is a singleton type.
-
Here, a type $S$ _contributes an abstract member_ to a type $T$ if
$S$ contains an abstract member that is also a member of $T$.
A refinement $R$ contributes an abstract member to a type $T$ if $R$
contains an abstract declaration which is also a member of $T$.
A type designator is volatile if it is an alias of a volatile type, or
-if it designates a type parameter or abstract type that has a volatile type as
+if it designates a type parameter or abstract type that has a volatile type as
its upper bound.
A singleton type `$p$.type` is volatile, if the underlying
@@ -1023,7 +1000,6 @@ type of path $p$ is volatile.
An existential type `$T$ forSome {$\,Q\,$}` is volatile if
$T$ is volatile.
-
## Type Erasure
A type is called _generic_ if it contains type arguments or type variables.
@@ -1036,20 +1012,19 @@ The erasure mapping is defined as follows.
- The erasure of the parameterized type `scala.Array$[T_1]$` is
`scala.Array$[|T_1|]$`.
- The erasure of every other parameterized type $T[T_1 , \ldots , T_n]$ is $|T|$.
-- The erasure of a singleton type `$p$.type` is the
+- The erasure of a singleton type `$p$.type` is the
erasure of the type of $p$.
- The erasure of a type projection `$T$#$x$` is `|$T$|#$x$`.
-- The erasure of a compound type
- `$T_1$ with $\ldots$ with $T_n$ {$R\,$}` is the erasure of the intersection
+- The erasure of a compound type
+ `$T_1$ with $\ldots$ with $T_n$ {$R\,$}` is the erasure of the intersection
dominator of $T_1 , \ldots , T_n$.
- The erasure of an existential type `$T$ forSome {$\,Q\,$}` is $|T|$.
The _intersection dominator_ of a list of types $T_1 , \ldots , T_n$ is computed
as follows.
-Let $T_{i_1} , \ldots , T_{i_m}$ be the subsequence of types $T_i$
-which are not supertypes of some other type $T_j$.
+Let $T_{i_1} , \ldots , T_{i_m}$ be the subsequence of types $T_i$
+which are not supertypes of some other type $T_j$.
If this subsequence contains a type designator $T_c$ that refers to a class
-which is not a trait,
+which is not a trait,
the intersection dominator is $T_c$. Otherwise, the intersection
dominator is the first element of the subsequence, $T_{i_1}$.
-