summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/01-lexical-syntax.md2
-rw-r--r--spec/02-identifiers-names-and-scopes.md91
-rw-r--r--spec/03-types.md99
-rw-r--r--spec/05-classes-and-objects.md4
-rw-r--r--spec/06-expressions.md244
-rw-r--r--spec/08-pattern-matching.md15
-rw-r--r--spec/11-annotations.md2
-rw-r--r--spec/13-syntax-summary.md6
-rw-r--r--spec/15-changelog.md4
-rw-r--r--spec/_layouts/default.yml2
10 files changed, 247 insertions, 222 deletions
diff --git a/spec/01-lexical-syntax.md b/spec/01-lexical-syntax.md
index 0232ed9a34..4e92c7cf7b 100644
--- a/spec/01-lexical-syntax.md
+++ b/spec/01-lexical-syntax.md
@@ -49,6 +49,8 @@ classes (Unicode general category given in parentheses):
```ebnf
op ::= opchar {opchar}
varid ::= lower idrest
+boundvarid ::= varid
+ | ‘`’ varid ‘`’
plainid ::= upper idrest
| varid
| op
diff --git a/spec/02-identifiers-names-and-scopes.md b/spec/02-identifiers-names-and-scopes.md
index 0a9c5dfe77..6653be2ce5 100644
--- a/spec/02-identifiers-names-and-scopes.md
+++ b/spec/02-identifiers-names-and-scopes.md
@@ -17,12 +17,12 @@ which are collectively called _bindings_.
Bindings of different kinds have a precedence defined on them:
1. Definitions and declarations that are local, inherited, or made
- available by a package clause in the same compilation unit where the
- definition occurs have highest precedence.
+ available by a package clause and also defined in the same compilation unit
+ as the reference, have highest precedence.
1. Explicit imports have next highest precedence.
1. Wildcard imports have next highest precedence.
-1. Definitions made available by a package clause not in the
- compilation unit where the definition occurs have lowest precedence.
+1. Definitions made available by a package clause, but not also defined in the
+ same compilation unit as the reference, have lowest precedence.
There are two different name spaces, one for [types](03-types.html#types)
and one for [terms](06-expressions.html#expressions). The same name may designate a
@@ -34,22 +34,18 @@ in some inner scope _shadows_ bindings of lower precedence in the
same scope as well as bindings of the same or lower precedence in outer
scopes.
-<!-- TODO: either the example, the spec, or the compiler is wrong
-
-Note that shadowing is only a partial order. In a situation like
+Note that shadowing is only a partial order. In the following example,
+neither binding of `x` shadows the other. Consequently, the
+reference to `x` in the last line of the block is ambiguous.
```scala
val x = 1
-{
- import p.x
+locally {
+ import p.X.x
x
}
```
-neither binding of `x` shadows the other. Consequently, the
-reference to `x` in the last line of the block above would be ambiguous.
--->
-
A reference to an unqualified (type- or term-) identifier $x$ is bound
by the unique binding, which
@@ -69,17 +65,36 @@ the member of the type $T$ of $e$ which has the name $x$ in the same
namespace as the identifier. It is an error if $T$ is not a [value type](03-types.html#value-types).
The type of $e.x$ is the member type of the referenced entity in $T$.
+Binding precedence implies that the way source is bundled in files affects name resolution.
+In particular, imported names have higher precedence than names, defined in other files,
+that might otherwise be visible because they are defined in
+either the current package or an enclosing package.
+
+Note that a package definition is taken as lowest precedence, since packages
+are open and can be defined across arbitrary compilation units.
+
+```scala
+package util {
+ import scala.util
+ class Random
+ object Test extends App {
+ println(new util.Random) // scala.util.Random
+ }
+}
+```
+
###### Example
-Assume the following two definitions of objects named `X` in packages `P` and `Q`.
+Assume the following two definitions of objects named `X` in packages `p` and `q`
+in separate compilation units.
```scala
-package P {
+package p {
object X { val x = 1; val y = 2 }
}
-package Q {
- object X { val x = true; val y = "" }
+package q {
+ object X { val x = true; val y = false }
}
```
@@ -87,25 +102,27 @@ The following program illustrates different kinds of bindings and
precedences between them.
```scala
-package P { // `X' bound by package clause
-import Console._ // `println' bound by wildcard import
-object A {
- println("L4: "+X) // `X' refers to `P.X' here
- object B {
- import Q._ // `X' bound by wildcard import
- println("L7: "+X) // `X' refers to `Q.X' here
- import X._ // `x' and `y' bound by wildcard import
- println("L8: "+x) // `x' refers to `Q.X.x' here
- object C {
- val x = 3 // `x' bound by local definition
- println("L12: "+x) // `x' refers to constant `3' here
- { import Q.X._ // `x' and `y' bound by wildcard import
-// println("L14: "+x) // reference to `x' is ambiguous here
- import X.y // `y' bound by explicit import
- println("L16: "+y) // `y' refers to `Q.X.y' here
- { val x = "abc" // `x' bound by local definition
- import P.X._ // `x' and `y' bound by wildcard import
-// println("L19: "+y) // reference to `y' is ambiguous here
- println("L20: "+x) // `x' refers to string "abc" here
+package p { // `X' bound by package clause
+import Console._ // `println' bound by wildcard import
+object Y {
+ println(s"L4: $X") // `X' refers to `p.X' here
+ locally {
+ import q._ // `X' bound by wildcard import
+ println(s"L7: $X") // `X' refers to `q.X' here
+ import X._ // `x' and `y' bound by wildcard import
+ println(s"L9: $x") // `x' refers to `q.X.x' here
+ locally {
+ val x = 3 // `x' bound by local definition
+ println(s"L12: $x") // `x' refers to constant `3' here
+ locally {
+ import q.X._ // `x' and `y' bound by wildcard import
+// println(s"L15: $x") // reference to `x' is ambiguous here
+ import X.y // `y' bound by explicit import
+ println(s"L17: $y") // `y' refers to `q.X.y' here
+ locally {
+ val x = "abc" // `x' bound by local definition
+ import p.X._ // `x' and `y' bound by wildcard import
+// println(s"L21: $y") // reference to `y' is ambiguous here
+ println(s"L22: $x") // `x' refers to string "abc" here
}}}}}}
```
diff --git a/spec/03-types.md b/spec/03-types.md
index 3f433b4d90..2ad16e50cb 100644
--- a/spec/03-types.md
+++ b/spec/03-types.md
@@ -778,25 +778,22 @@ These notions are defined mutually recursively as follows.
## Relations between types
-We define two relations between types.
+We define the following relations between types.
-|Name | Symbolically |Interpretation |
-|-----------------|----------------|-------------------------------------------------|
-|Equivalence |$T \equiv U$ |$T$ and $U$ are interchangeable in all contexts. |
-|Conformance |$T <: U$ |Type $T$ conforms to type $U$. |
+| Name | Symbolically | Interpretation |
+|------------------|----------------|----------------------------------------------------|
+| Equivalence | $T \equiv U$ | $T$ and $U$ are interchangeable in all contexts. |
+| Conformance | $T <: U$ | Type $T$ conforms to ("is a subtype of") type $U$. |
+| Weak Conformance | $T <:_w U$ | Augments conformance for primitive numeric types. |
+| Compatibility | | Type $T$ conforms to type $U$ after conversions. |
### Equivalence
-Equivalence $(\equiv)$ between types is the smallest congruence [^congruence] such that
-the following holds:
+Equivalence $(\equiv)$ between types is the smallest congruence [^congruence] such that the following holds:
-- If $t$ is defined by a type alias `type $t$ = $T$`, then $t$ is
- equivalent to $T$.
-- If a path $p$ has a singleton type `$q$.type`, then
- `$p$.type $\equiv q$.type`.
-- If $O$ is defined by an object definition, and $p$ is a path
- consisting only of package or object selectors and ending in $O$, then
- `$O$.this.type $\equiv p$.type`.
+- If $t$ is defined by a type alias `type $t$ = $T$`, then $t$ is equivalent to $T$.
+- If a path $p$ has a singleton type `$q$.type`, then `$p$.type $\equiv q$.type`.
+- If $O$ is defined by an object definition, and $p$ is a path 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
their refinements are equivalent. Two refinements are equivalent if they
@@ -827,14 +824,11 @@ the following holds:
### Conformance
-The conformance relation $(<:)$ is the smallest
-transitive relation that satisfies the following conditions.
+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),
- `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` one has `scala.Null <: $T$`.
- A type variable or abstract type $t$ conforms to its upper bound and
its lower bound conforms to $t$.
@@ -912,15 +906,12 @@ type $C'$, if one of the following holds.
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
-are understood to be relative to that order.
-###### Note
-The least upper bound or greatest lower bound
-of a set of types does not always exist. For instance, consider
-the class definitions
+#### Least upper bounds and greatest lower bounds
+The $(<:)$ relation forms pre-order between types, i.e. it is transitive and reflexive.
+This allows us to define _least upper bounds_ and _greatest lower bounds_ of a set of types in terms of that order.
+The least upper bound or greatest lower bound of a set of types does not always exist.
+For instance, consider the class definitions:
```scala
class A[+T] {}
@@ -949,11 +940,9 @@ free to pick any one of them.
### Weak Conformance
-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.
+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
@@ -964,15 +953,49 @@ Long $<:_w$ Float
Float $<:_w$ Double
```
-A _weak least upper bound_ is a least upper bound with respect to
-weak conformance.
+A _weak least upper bound_ is a least upper bound with respect to weak conformance.
+
+### Compatibility
+A type $T$ is _compatible_ to a type $U$ if $T$ (or its corresponding function type) [weakly conforms](#weak-conformance) to $U$
+after applying [eta-expansion](06-expressions.html#eta-expansion). If $T$ is a method type, it's converted to the corresponding function type. If the types do not weakly conform, the following alternatives are checked in order:
+ - [view application](07-implicits.html#views): there's an implicit view from $T$ to $U$;
+ - dropping by-name modifiers: if $U$ is of the shape `$=> U'$` (and $T$ is not), `$T <:_w U'$`;
+ - SAM conversion: if $T$ corresponds to a function type, and $U$ declares a single abstract method whose type [corresponds](06-expressions.html#sam-conversion) to the function type $U'$, `$T <:_w U'$`.
+
+<!--- TODO: include other implicit conversions in addition to view application?
+
+ trait Proc { def go(x: Any): Unit }
+
+ def foo(x: Any => Unit): Unit = ???
+ def foo(x: Proc): Unit = ???
+
+ foo((x: Any) => 1) // works when you drop either foo overload since value discarding is applied
+
+-->
+
+#### Examples
+
+##### Function compatibility via SAM conversion
+
+Given the definitions
+
+```
+def foo(x: Int => String): Unit
+def foo(x: ToString): Unit
+
+trait ToString { def convert(x: Int): String }
+```
+
+The application `foo((x: Int) => x.toString)` [resolves](06-expressions.html#overloading-resolution) to the first overload,
+as it's more specific:
+ - `Int => String` is compatible to `ToString` -- when expecting a value of type `ToString`, you may pass a function literal from `Int` to `String`, as it will be SAM-converted to said function;
+ - `ToString` is not compatible to `Int => String` -- when expecting a function from `Int` to `String`, you may not pass a `ToString`.
## Volatile Types
-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
-cannot appear in a [path](#paths).
+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 cannot appear in a [path](#paths).
A type is _volatile_ if it falls into one of four categories:
diff --git a/spec/05-classes-and-objects.md b/spec/05-classes-and-objects.md
index cff5174297..d1a1a8739d 100644
--- a/spec/05-classes-and-objects.md
+++ b/spec/05-classes-and-objects.md
@@ -344,8 +344,8 @@ $M'$:
- If $M$ and $M'$ are both concrete value definitions, then either none
of them is marked `lazy` or both must be marked `lazy`.
-A stable member can only be overridden by a stable member.
-For example, this is not allowed:
+- A stable member can only be overridden by a stable member.
+ For example, this is not allowed:
```scala
class X { val stable = 1}
diff --git a/spec/06-expressions.md b/spec/06-expressions.md
index 2deb5f5eec..9df9249373 100644
--- a/spec/06-expressions.md
+++ b/spec/06-expressions.md
@@ -81,10 +81,9 @@ evaluation is immediate.
## The _Null_ Value
-The `null` value is of type `scala.Null`, and is thus
-compatible with every reference type. It denotes a reference value
-which refers to a special “`null`” object. This object
-implements methods in class `scala.AnyRef` as follows:
+The `null` value is of type `scala.Null`, and thus conforms to every reference type.
+It denotes a reference value which refers to a special `null` object.
+This object implements methods in class `scala.AnyRef` as follows:
- `eq($x\,$)` and `==($x\,$)` return `true` iff the
argument $x$ is also the "null" object.
@@ -239,38 +238,21 @@ ArgumentExprs ::= `(' [Exprs] `)'
Exprs ::= Expr {`,' Expr}
```
-An application `$f$($e_1 , \ldots , e_m$)` applies the
-function $f$ to the argument expressions $e_1 , \ldots , e_m$. If $f$
-has a method type `($p_1$:$T_1 , \ldots , p_n$:$T_n$)$U$`, the type of
-each argument expression $e_i$ is typed with the
-corresponding parameter type $T_i$ as expected type. Let $S_i$ be type
-type of argument $e_i$ $(i = 1 , \ldots , m)$. If $f$ is a polymorphic method,
-[local type inference](#local-type-inference) is used to determine
-type arguments for $f$. If $f$ has some value type, the application is taken to
-be equivalent to `$f$.apply($e_1 , \ldots , e_m$)`,
-i.e. the application of an `apply` method defined by $f$.
-
-The function $f$ must be _applicable_ to its arguments $e_1
-, \ldots , e_n$ of types $S_1 , \ldots , S_n$.
-
-If $f$ has a method type $(p_1:T_1 , \ldots , p_n:T_n)U$
-we say that an argument expression $e_i$ is a _named_ argument if
-it has the form $x_i=e'_i$ and $x_i$ is one of the parameter names
-$p_1 , \ldots , p_n$. The function $f$ is applicable if all of the following conditions
-hold:
-
-- For every named argument $x_i=e_i'$ the type $S_i$
- is compatible with the parameter type $T_j$ whose name $p_j$ matches $x_i$.
-- For every positional argument $e_i$ the type $S_i$
-is compatible with $T_i$.
-- If the expected type is defined, the result type $U$ is
- compatible to it.
-
-If $f$ is a polymorphic method it is applicable if
-[local type inference](#local-type-inference) can
-determine type arguments so that the instantiated method is applicable. If
-$f$ has some value type it is applicable if it has a method member named
-`apply` which is applicable.
+An application `$f(e_1 , \ldots , e_m)$` applies the function `$f$` to the argument expressions `$e_1, \ldots , e_m$`. For this expression to be well-typed, the function must be *applicable* to its arguments, which is defined next by case analysis on $f$'s type.
+
+If $f$ has a method type `($p_1$:$T_1 , \ldots , p_n$:$T_n$)$U$`, each argument expression $e_i$ is typed with the corresponding parameter type $T_i$ as expected type. Let $S_i$ be the type of argument $e_i$ $(i = 1 , \ldots , m)$. The function $f$ must be _applicable_ to its arguments $e_1, \ldots , e_n$ of types $S_1 , \ldots , S_n$. We say that an argument expression $e_i$ is a _named_ argument if it has the form `$x_i=e'_i$` and `$x_i$` is one of the parameter names `$p_1, \ldots, p_n$`.
+
+Once the types $S_i$ have been determined, the function $f$ of the above method type is said to be applicable if all of the following conditions hold:
+ - for every named argument $p_j=e_i'$ the type $S_i$ is [compatible](03-types.html#compatibility) with the parameter type $T_j$;
+ - for every positional argument $e_i$ the type $S_i$ is [compatible](03-types.html#compatibility) with $T_i$;
+ - if the expected type is defined, the result type $U$ is [compatible](03-types.html#compatibility) to it.
+
+If $f$ is a polymorphic method, [local type inference](#local-type-inference) is used to instantiate $f$'s type parameters.
+The polymorphic method is applicable if type inference can determine type arguments so that the instantiated method is applicable.
+
+If $f$ has some value type, the application is taken to be equivalent to `$f$.apply($e_1 , \ldots , e_m$)`,
+i.e. the application of an `apply` method defined by $f$. The value `$f$` is applicable to the given arguments if `$f$.apply` is applicable.
+
Evaluation of `$f$($e_1 , \ldots , e_n$)` usually entails evaluation of
$f$ and $e_1 , \ldots , e_n$ in that order. Each argument expression
@@ -1141,11 +1123,9 @@ re-thrown.
Let $\mathit{pt}$ be the expected type of the try expression. The block
$b$ is expected to conform to $\mathit{pt}$. The handler $h$
-is expected conform to type
-`scala.PartialFunction[scala.Throwable, $\mathit{pt}\,$]`. The
-type of the try expression is the [weak least upper bound](03-types.html#weak-conformance)
-of the type of $b$
-and the result type of $h$.
+is expected conform to type `scala.PartialFunction[scala.Throwable, $\mathit{pt}\,$]`.
+The type of the try expression is the [weak least upper bound](03-types.html#weak-conformance)
+of the type of $b$ and the result type of $h$.
A try expression `try { $b$ } finally $e$` evaluates the block
$b$. If evaluation of $b$ does not cause an exception to be
@@ -1178,26 +1158,26 @@ Bindings ::= `(' Binding {`,' Binding} `)'
Binding ::= (id | `_') [`:' Type]
```
-The anonymous function `($x_1$: $T_1 , \ldots , x_n$: $T_n$) => e`
-maps parameters $x_i$ of types $T_i$ to a result given
-by expression $e$. The scope of each formal parameter
-$x_i$ is $e$. Formal parameters must have pairwise distinct names.
+The anonymous function of arity $n$, `($x_1$: $T_1 , \ldots , x_n$: $T_n$) => e` maps parameters $x_i$ of types $T_i$ to a result given by expression $e$. The scope of each formal parameter $x_i$ is $e$. Formal parameters must have pairwise distinct names.
+
+In the case of a single untyped formal parameter, `($x\,$) => $e$` can be abbreviated to `$x$ => $e$`. If an anonymous function `($x$: $T\,$) => $e$` with a single typed parameter appears as the result expression of a block, it can be abbreviated to `$x$: $T$ => e`.
+
+A formal parameter may also be a wildcard represented by an underscore `_`. In that case, a fresh name for the parameter is chosen arbitrarily.
+
+A named parameter of an anonymous function may be optionally preceded by an `implicit` modifier. In that case the parameter is labeled [`implicit`](07-implicits.html#implicit-parameters-and-views); however the parameter section itself does not count as an [implicit parameter section](07-implicits.html#implicit-parameters). Hence, arguments to anonymous functions always have to be given explicitly.
+
+### Translation
+If the expected type of the anonymous function is of the shape `scala.Function$n$[$S_1 , \ldots , S_n$, $R\,$]`, or can be [SAM-converted](#sam-conversion) to such a function type, the type `$T_i$` of a parameter `$x_i$` can be omitted, as far as `$S_i$` is defined in the expected type, and `$T_i$ = $S_i$` is assumed. Furthermore, the expected type when type checking $e$ is $R$.
-If the expected type of the anonymous function is of the form
-`scala.Function$n$[$S_1 , \ldots , S_n$, $R\,$]`, the
-expected type of $e$ is $R$ and the type $T_i$ of any of the
-parameters $x_i$ can be omitted, in which
-case`$T_i$ = $S_i$` is assumed.
-If the expected type of the anonymous function is
-some other type, all formal parameter types must be explicitly given,
-and the expected type of $e$ is undefined. The type of the anonymous
-function
-is`scala.Function$n$[$S_1 , \ldots , S_n$, $T\,$]`,
-where $T$ is the [packed type](#expression-typing)
-of $e$. $T$ must be equivalent to a
-type which does not refer to any of the formal parameters $x_i$.
+If there is no expected type for the function literal, all formal parameter types `$T_i$` must be specified explicitly, and the expected type of $e$ is undefined. The type of the anonymous function is `scala.Function$n$[$T_1 , \ldots , T_n$, $R\,$]`, where $R$ is the [packed type](#expression-typing) of $e$. $R$ must be equivalent to a type which does not refer to any of the formal parameters $x_i$.
-The anonymous function is evaluated as the instance creation expression
+The eventual run-time value of an anonymous function is determined by the expected type:
+ - a subclass of one of the builtin function types, `scala.Function$n$[$S_1 , \ldots , S_n$, $R\,$]` (with $S_i$ and $R$ fully defined),
+ - a [single-abstract-method (SAM) type](#sam-conversion);
+ - `PartialFunction[$T$, $U$]`, if the function literal is of the shape `x => x match { $\ldots$ }`
+ - some other type.
+
+The standard anonymous function evaluates in the same way as the following instance creation expression:
```scala
new scala.Function$n$[$T_1 , \ldots , T_n$, $T$] {
@@ -1205,22 +1185,11 @@ new scala.Function$n$[$T_1 , \ldots , T_n$, $T$] {
}
```
-In the case of a single untyped formal parameter,
-`($x\,$) => $e$`
-can be abbreviated to `$x$ => $e$`. If an
-anonymous function `($x$: $T\,$) => $e$` with a single
-typed parameter appears as the result expression of a block, it can be
-abbreviated to `$x$: $T$ => e`.
+The same evaluation holds for a SAM type, except that the instantiated type is given by the SAM type, and the implemented method is the single abstract method member of this type.
-A formal parameter may also be a wildcard represented by an underscore `_`.
-In that case, a fresh name for the parameter is chosen arbitrarily.
+The underlying platform may provide more efficient ways of constructing these instances, such as Java 8's `invokedynamic` bytecode and `LambdaMetaFactory` class.
-A named parameter of an anonymous function may be optionally preceded
-by an `implicit` modifier. In that case the parameter is
-labeled [`implicit`](07-implicits.html#implicit-parameters-and-views); however the
-parameter section itself does not count as an implicit parameter
-section in the sense defined [here](07-implicits.html#implicit-parameters). Hence, arguments to
-anonymous functions always have to be given explicitly.
+A `PartialFunction`'s value receives an additional `isDefinedAt` member, which is derived from the pattern match in the function literal, with each case's body being replaced by `true`, and an added default (if none was given) that evaluates to `false`.
###### Example
Examples of anonymous functions:
@@ -1290,11 +1259,9 @@ include at least the expressions of the following forms:
- A string literal
- A class constructed with [`Predef.classOf`](12-the-scala-standard-library.html#the-predef-object)
- An element of an enumeration from the underlying platform
-- A literal array, of the form
- `Array$(c_1 , \ldots , c_n)$`,
+- A literal array, of the form `Array$(c_1 , \ldots , c_n)$`,
where all of the $c_i$'s are themselves constant expressions
-- An identifier defined by a
- [constant value definition](04-basic-declarations-and-definitions.html#value-declarations-and-definitions).
+- An identifier defined by a [constant value definition](04-basic-declarations-and-definitions.html#value-declarations-and-definitions).
## Statements
@@ -1335,10 +1302,6 @@ Implicit conversions can be applied to expressions whose type does not
match their expected type, to qualifiers in selections, and to unapplied methods. The
available implicit conversions are given in the next two sub-sections.
-We say, a type $T$ is _compatible_ to a type $U$ if $T$ weakly conforms
-to $U$ after applying [eta-expansion](#eta-expansion) and
-[view applications](07-implicits.html#views).
-
### Value Conversions
The following seven implicit conversions can be applied to an
@@ -1382,12 +1345,35 @@ If $e$ has some value type and the expected type is `Unit`,
$e$ is converted to the expected type by embedding it in the
term `{ $e$; () }`.
+###### SAM conversion
+An expression `(p1, ..., pN) => body` of function type `(T1, ..., TN) => T` is sam-convertible to the expected type `S` if the following holds:
+ - the class `C` of `S` declares an abstract method `m` with signature `(p1: A1, ..., pN: AN): R`;
+ - besides `m`, `C` must not declare or inherit any other deferred value members;
+ - the method `m` must have a single argument list;
+ - there must be a type `U` that is a subtype of `S`, so that the expression
+ `new U { final def m(p1: A1, ..., pN: AN): R = body }` is well-typed (conforming to the expected type `S`);
+ - for the purpose of scoping, `m` should be considered a static member (`U`'s members are not in scope in `body`);
+ - `(A1, ..., AN) => R` is a subtype of `(T1, ..., TN) => T` (satisfying this condition drives type inference of unknown type parameters in `S`);
+
+Note that a function literal that targets a SAM is not necessarily compiled to the above instance creation expression. This is platform-dependent.
+
+It follows that:
+ - if class `C` defines a constructor, it must be accessible and must define exactly one, empty, argument list;
+ - `m` cannot be polymorphic;
+ - it must be possible to derive a fully-defined type `U` from `S` by inferring any unknown type parameters of `C`.
+
+Finally, we impose some implementation restrictions (these may be lifted in future releases):
+ - `C` must not be nested or local (it must not capture its environment, as that results in a zero-argument constructor)
+ - `C`'s constructor must not have an implicit argument list (this simplifies type inference);
+ - `C` must not declare a self type (this simplifies type inference);
+ - `C` must not be `@specialized`.
+
###### View Application
If none of the previous conversions applies, and $e$'s type
does not conform to the expected type $\mathit{pt}$, it is attempted to convert
$e$ to the expected type with a [view](07-implicits.html#views).
-###### Dynamic Member Selection
+###### Selection on `Dynamic`
If none of the previous conversions applies, and $e$ is a prefix
of a selection $e.x$, and $e$'s type conforms to class `scala.Dynamic`,
then the selection is rewritten according to the rules for
@@ -1426,34 +1412,36 @@ a function. Let $\mathscr{A}$ be the set of members referenced by $e$.
Assume first that $e$ appears as a function in an application, as in
`$e$($e_1 , \ldots , e_m$)`.
-One first determines the set of functions that is potentially
-applicable based on the _shape_ of the arguments.
+One first determines the set of functions that is potentially [applicable](#function-applications)
+based on the _shape_ of the arguments.
-The shape of an argument expression $e$, written $\mathit{shape}(e)$, is
+The *shape* of an argument expression $e$, written $\mathit{shape}(e)$, is
a type that is defined as follows:
+ - For a function expression `($p_1$: $T_1 , \ldots , p_n$: $T_n$) => $b$: (Any $, \ldots ,$ Any) => $\mathit{shape}(b)$`,
+ where `Any` occurs $n$ times in the argument type.
+ - For a named argument `$n$ = $e$`: $\mathit{shape}(e)$.
+ - For all other expressions: `Nothing`.
+
+Let $\mathscr{B}$ be the set of alternatives in $\mathscr{A}$ that are [_applicable_](#function-applications)
+to expressions $(e_1 , \ldots , e_n)$ of types $(\mathit{shape}(e_1) , \ldots , \mathit{shape}(e_n))$.
+If there is precisely one alternative in $\mathscr{B}$, that alternative is chosen.
+
+Otherwise, let $S_1 , \ldots , S_m$ be the list of types obtained by typing each argument as follows.
+An argument `$e_i$` of the shape `($p_1$: $T_1 , \ldots , p_n$: $T_n$) => $b$` where one of the `$T_i$` is missing,
+i.e., a function literal with a missing parameter type, is typed with an expected function type that
+propagates the least upper bound of the fully defined types of the corresponding parameters of
+the ([SAM-converted](#sam-conversion)) function types specified by the `$i$`th argument type found in each alternative.
+All other arguments are typed with an undefined expected type.
+
+For every member $m$ in $\mathscr{B}$ one determines whether it is applicable
+to expressions ($e_1 , \ldots , e_m$) of types $S_1, \ldots , S_m$.
-- For a function expression `($p_1$: $T_1 , \ldots , p_n$: $T_n$) => $b$`:
- `(Any $, \ldots ,$ Any) => $\mathit{shape}(b)$`, where `Any` occurs $n$ times
- in the argument type.
-- For a named argument `$n$ = $e$`: $\mathit{shape}(e)$.
-- For all other expressions: `Nothing`.
-
-Let $\mathscr{B}$ be the set of alternatives in $\mathscr{A}$ that are
-[_applicable_](#function-applications)
-to expressions $(e_1 , \ldots , e_n)$ of types
-$(\mathit{shape}(e_1) , \ldots , \mathit{shape}(e_n))$.
-If there is precisely one
-alternative in $\mathscr{B}$, that alternative is chosen.
-
-Otherwise, let $S_1 , \ldots , S_m$ be the vector of types obtained by
-typing each argument with an undefined expected type. For every
-member $m$ in $\mathscr{B}$ one determines whether it is
-applicable to expressions ($e_1 , \ldots , e_m$) of types $S_1
-, \ldots , S_m$.
It is an error if none of the members in $\mathscr{B}$ is applicable. If there is one
single applicable alternative, that alternative is chosen. Otherwise, let $\mathscr{CC}$
be the set of applicable alternatives which don't employ any default argument
-in the application to $e_1 , \ldots , e_m$. It is again an error if $\mathscr{CC}$ is empty.
+in the application to $e_1 , \ldots , e_m$.
+
+It is again an error if $\mathscr{CC}$ is empty.
Otherwise, one chooses the _most specific_ alternative among the alternatives
in $\mathscr{CC}$, according to the following definition of being "as specific as", and
"more specific than":
@@ -1469,21 +1457,17 @@ question: given
so the method is not more specific than the value.
-->
-- A parameterized method $m$ of type `($p_1:T_1, \ldots , p_n:T_n$)$U$` is _as specific as_ some other
- member $m'$ of type $S$ if $m'$ is applicable to arguments
- `($p_1 , \ldots , p_n\,$)` of
- types $T_1 , \ldots , T_n$.
-- A polymorphic method of type
- `[$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]$T$` is
- as specific as some other member of type $S$ if $T$ is as
- specific as $S$ under the assumption that for
- $i = 1 , \ldots , n$ each $a_i$ is an abstract type name
+- A parameterized method $m$ of type `($p_1:T_1, \ldots , p_n:T_n$)$U$` is
+ _as specific as_ some other member $m'$ of type $S$ if $m'$ is [applicable](#function-applications)
+ to arguments `($p_1 , \ldots , p_n$)` of types $T_1 , \ldots , T_n$.
+- A polymorphic method of type `[$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]$T$` is
+ as specific as some other member of type $S$ if $T$ is as specific as $S$
+ under the assumption that for $i = 1 , \ldots , n$ each $a_i$ is an abstract type name
bounded from below by $L_i$ and from above by $U_i$.
-- A member of any other type is always as specific as a parameterized method
- or a polymorphic method.
-- Given two members of types $T$ and $U$ which are
- neither parameterized nor polymorphic method types, the member of type $T$ is as specific as
- the member of type $U$ if the existential dual of $T$ conforms to the existential dual of $U$.
+- A member of any other type is always as specific as a parameterized method or a polymorphic method.
+- Given two members of types $T$ and $U$ which are neither parameterized nor polymorphic method types,
+ the member of type $T$ is as specific as the member of type $U$ if
+ the existential dual of $T$ conforms to the existential dual of $U$.
Here, the existential dual of a polymorphic type
`[$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]$T$` is
`$T$ forSome { type $a_1$ >: $L_1$ <: $U_1$ $, \ldots ,$ type $a_n$ >: $L_n$ <: $U_n$}`.
@@ -1493,8 +1477,7 @@ The _relative weight_ of an alternative $A$ over an alternative $B$ is a
number from 0 to 2, defined as the sum of
- 1 if $A$ is as specific as $B$, 0 otherwise, and
-- 1 if $A$ is defined in a class or object which is derived
- from the class or object defining $B$, 0 otherwise.
+- 1 if $A$ is defined in a class or object which is derived from the class or object defining $B$, 0 otherwise.
A class or object $C$ is _derived_ from a class or object $D$ if one of
the following holds:
@@ -1517,15 +1500,13 @@ arguments in $\mathit{targs}$ are chosen. It is an error if no such alternative
If there are several such alternatives, overloading resolution is
applied again to the whole expression `$e$[$\mathit{targs}\,$]`.
-Assume finally that $e$ does not appear as a function in either
-an application or a type application. If an expected type is given,
-let $\mathscr{B}$ be the set of those alternatives in $\mathscr{A}$ which are
-[compatible](#implicit-conversions) to it. Otherwise, let $\mathscr{B}$ be the same
-as $\mathscr{A}$.
-We choose in this case the most specific alternative among all
-alternatives in $\mathscr{B}$. It is an error if there is no
-alternative in $\mathscr{B}$ which is more specific than all other
-alternatives in $\mathscr{B}$.
+Assume finally that $e$ does not appear as a function in either an application or a type application.
+If an expected type is given, let $\mathscr{B}$ be the set of those alternatives
+in $\mathscr{A}$ which are [compatible](03-types.html#compatibility) to it.
+Otherwise, let $\mathscr{B}$ be the same as $\mathscr{A}$.
+In this last case we choose the most specific alternative among all alternatives in $\mathscr{B}$.
+It is an error if there is no alternative in $\mathscr{B}$ which is
+more specific than all other alternatives in $\mathscr{B}$.
###### Example
Consider the following definitions:
@@ -1552,9 +1533,8 @@ no most specific applicable signature exists.
### Local Type Inference
Local type inference infers type arguments to be passed to expressions
-of polymorphic type. Say $e$ is of type [$a_1$ >: $L_1$ <: $U_1
-, \ldots , a_n$ >: $L_n$ <: $U_n$]$T$ and no explicit type parameters
-are given.
+of polymorphic type. Say $e$ is of type [$a_1$ >: $L_1$ <: $U_1, \ldots , a_n$ >: $L_n$ <: $U_n$]$T$
+and no explicit type parameters are given.
Local type inference converts this expression to a type
application `$e$[$T_1 , \ldots , T_n$]`. The choice of the
diff --git a/spec/08-pattern-matching.md b/spec/08-pattern-matching.md
index d2a84b09db..00f9099bea 100644
--- a/spec/08-pattern-matching.md
+++ b/spec/08-pattern-matching.md
@@ -10,10 +10,10 @@ chapter: 8
```ebnf
Pattern ::= Pattern1 { ‘|’ Pattern1 }
- Pattern1 ::= varid ‘:’ TypePat
+ Pattern1 ::= boundvarid ‘:’ TypePat
| ‘_’ ‘:’ TypePat
| Pattern2
- Pattern2 ::= varid [‘@’ Pattern3]
+ Pattern2 ::= id [‘@’ Pattern3]
| Pattern3
Pattern3 ::= SimplePattern
| SimplePattern {id [nl] SimplePattern}
@@ -22,7 +22,7 @@ chapter: 8
| Literal
| StableId
| StableId ‘(’ [Patterns] ‘)’
- | StableId ‘(’ [Patterns ‘,’] [varid ‘@’] ‘_’ ‘*’ ‘)’
+ | StableId ‘(’ [Patterns ‘,’] [id ‘@’] ‘_’ ‘*’ ‘)’
| ‘(’ [Patterns] ‘)’
| XmlPattern
Patterns ::= Pattern {‘,’ Patterns}
@@ -328,10 +328,12 @@ A type pattern $T$ is of one of the following forms:
* A reference to a class $C$, $p.C$, or `$T$#$C$`. This
type pattern matches any non-null instance of the given class.
- Note that the prefix of the class, if it is given, is relevant for determining
+ Note that the prefix of the class, if it exists, is relevant for determining
class instances. For instance, the pattern $p.C$ matches only
instances of classes $C$ which were created with the path $p$ as
- prefix.
+ prefix. This also applies to prefixes which are not given syntactically.
+ For example, if $C$ refers to a class defined in the nearest enclosing
+ class and is thus equivalent to $this.C$, it is considered to have a prefix.
The bottom types `scala.Nothing` and `scala.Null` cannot
be used as type patterns, because they would match nothing in any case.
@@ -652,7 +654,8 @@ or `scala.PartialFunction[$S_1$, $R$]`, where the
argument type(s) $S_1 , \ldots , S_k$ must be fully determined, but the result type
$R$ may be undetermined.
-If the expected type is `scala.Function$k$[$S_1 , \ldots , S_k$, $R$]`,
+If the expected type is [SAM-convertible](06-expressions.html#sam-conversion)
+to `scala.Function$k$[$S_1 , \ldots , S_k$, $R$]`,
the expression is taken to be equivalent to the anonymous function:
```scala
diff --git a/spec/11-annotations.md b/spec/11-annotations.md
index d66f24abf8..e54a0dd2b0 100644
--- a/spec/11-annotations.md
+++ b/spec/11-annotations.md
@@ -94,7 +94,7 @@ Java platform, the following annotations have a standard meaning.
* `@deprecatedName(name: <symbollit>)`<br/>
Marks a formal parameter name as deprecated. Invocations of this entity
- using named parameter syntax refering to the deprecated parameter name cause a deprecation warning.
+ using named parameter syntax referring to the deprecated parameter name cause a deprecation warning.
### Scala Compiler Annotations
diff --git a/spec/13-syntax-summary.md b/spec/13-syntax-summary.md
index a4b4aae570..44c481f9f6 100644
--- a/spec/13-syntax-summary.md
+++ b/spec/13-syntax-summary.md
@@ -132,7 +132,7 @@ grammar:
Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr]
| `while' `(' Expr `)' {nl} Expr
| `try' (`{' Block `}' | Expr) [`catch' `{' CaseClauses `}'] [`finally' Expr]
- | `do' Expr [semi] `while' `(' Expr ')'
+ | `do' Expr [semi] `while' `(' Expr `)'
| `for' (`(' Enumerators `)' | `{' Enumerators `}') {nl} [`yield'] Expr
| `throw' Expr
| `return' [Expr]
@@ -190,12 +190,12 @@ grammar:
| varid
| Literal
| StableId
- | StableId ‘(’ [Patterns ‘)’
+ | StableId ‘(’ [Patterns] ‘)’
| StableId ‘(’ [Patterns ‘,’] [varid ‘@’] ‘_’ ‘*’ ‘)’
| ‘(’ [Patterns] ‘)’
| XmlPattern
Patterns ::= Pattern [‘,’ Patterns]
- | ‘_’ *
+ | ‘_’ ‘*’
TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’
FunTypeParamClause::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’
diff --git a/spec/15-changelog.md b/spec/15-changelog.md
index 751a571ecc..c88408682b 100644
--- a/spec/15-changelog.md
+++ b/spec/15-changelog.md
@@ -441,7 +441,7 @@ In the example, `Twice` is an extractor object with two methods:
- The `unapply` method is used to decompose an even number; it is in a sense
the reverse of `apply`. `unapply` methods return option types:
- `Some(...)` for a match that suceeds, `None` for a match that fails.
+ `Some(...)` for a match that succeeds, `None` for a match that fails.
Pattern variables are returned as the elements of `Some`.
If there are several variables, they are grouped in a tuple.
@@ -532,7 +532,7 @@ In particular, one can now simulate package protected access as in Java writing
where would name the package containing `X`.
-#### Relaxation of Private Acess
+#### Relaxation of Private Access
[Private members of a class](05-classes-and-objects.html#private) can now be
referenced from the companion module of the class and vice versa.
diff --git a/spec/_layouts/default.yml b/spec/_layouts/default.yml
index 69791d26ad..7e205f8835 100644
--- a/spec/_layouts/default.yml
+++ b/spec/_layouts/default.yml
@@ -15,7 +15,7 @@
}
});
</script>
- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/2.3-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.2/styles/default.min.css">
<!-- need to use include to see value of page.chapter variable -->