summaryrefslogtreecommitdiff
path: root/spec/06-expressions.md
diff options
context:
space:
mode:
Diffstat (limited to 'spec/06-expressions.md')
-rw-r--r--spec/06-expressions.md432
1 files changed, 210 insertions, 222 deletions
diff --git a/spec/06-expressions.md b/spec/06-expressions.md
index c24ca01c3b..9e49dfa199 100644
--- a/spec/06-expressions.md
+++ b/spec/06-expressions.md
@@ -7,44 +7,44 @@ chapter: 6
# Expressions
```ebnf
-Expr ::= (Bindings | id | `_') `=>' Expr
+Expr ::= (Bindings | id | ‘_’) ‘=>’ Expr
| Expr1
-Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr]
- | `while' `(' Expr `)' {nl} Expr
- | `try' (`{' Block `}' | Expr) [`catch' `{' CaseClauses `}'] [`finally' Expr]
- | `do' Expr [semi] `while' `(' Expr ')'
- | `for' (`(' Enumerators `)' | `{' Enumerators `}') {nl} [`yield'] Expr
- | `throw' Expr
- | `return' [Expr]
- | [SimpleExpr `.'] id `=' Expr
- | SimpleExpr1 ArgumentExprs `=' Expr
+Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr]
+ | ‘while’ ‘(’ Expr ‘)’ {nl} Expr
+ | ‘try’ (‘{’ Block ‘}’ | Expr) [‘catch’ ‘{’ CaseClauses ‘}’] [‘finally’ Expr]
+ | ‘do’ Expr [semi] ‘while’ ‘(’ Expr ‘)’
+ | ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) {nl} [‘yield’] Expr
+ | ‘throw’ Expr
+ | ‘return’ [Expr]
+ | [SimpleExpr ‘.’] id ‘=’ Expr
+ | SimpleExpr1 ArgumentExprs ‘=’ Expr
| PostfixExpr
| PostfixExpr Ascription
- | PostfixExpr `match' `{' CaseClauses `}'
+ | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’
PostfixExpr ::= InfixExpr [id [nl]]
InfixExpr ::= PrefixExpr
| InfixExpr id [nl] InfixExpr
-PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr
-SimpleExpr ::= `new' (ClassTemplate | TemplateBody)
+PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr
+SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody)
| BlockExpr
- | SimpleExpr1 [`_']
+ | SimpleExpr1 [‘_’]
SimpleExpr1 ::= Literal
| Path
- | `_'
- | `(' [Exprs] `)'
- | SimpleExpr `.' id s
+ | ‘_’
+ | ‘(’ [Exprs] ‘)’
+ | SimpleExpr ‘.’ id s
| SimpleExpr TypeArgs
| SimpleExpr1 ArgumentExprs
| XmlExpr
-Exprs ::= Expr {`,' Expr}
+Exprs ::= Expr {‘,’ Expr}
BlockExpr ::= ‘{’ CaseClauses ‘}’
| ‘{’ Block ‘}’
Block ::= BlockStat {semi BlockStat} [ResultExpr]
ResultExpr ::= Expr1
- | (Bindings | ([`implicit'] id | `_') `:' CompoundType) `=>' Block
-Ascription ::= `:' InfixType
- | `:' Annotation {Annotation}
- | `:' `_' `*'
+ | (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
+Ascription ::= ‘:’ InfixType
+ | ‘:’ Annotation {Annotation}
+ | ‘:’ ‘_’ ‘*’
```
Expressions are composed of operators and operands. Expression forms are
@@ -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.
@@ -101,7 +100,7 @@ A reference to any other member of the "null" object causes a
```ebnf
SimpleExpr ::= Path
- | SimpleExpr `.' id
+ | SimpleExpr ‘.’ id
```
A designator refers to a named term. It can be a _simple name_ or
@@ -152,8 +151,8 @@ by a definition overriding $m$.
## This and Super
```ebnf
-SimpleExpr ::= [id `.'] `this'
- | [id '.'] `super' [ClassQualifier] `.' id
+SimpleExpr ::= [id ‘.’] ‘this’
+ | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id
```
The expression `this` can appear in the statement part of a
@@ -176,7 +175,9 @@ in the least proper supertype of the innermost template containing the
reference. It evaluates to the member $m'$ in the actual supertype of
that template which is equal to $m$ or which overrides $m$. The
statically referenced member $m$ must be a type or a
-method. <!-- explanation: so that we need not create several fields for overriding vals -->
+method.
+
+<!-- explanation: so that we need not create several fields for overriding vals -->
If it is
a method, it must be concrete, or the template
@@ -221,9 +222,14 @@ the linearization of class `D` is `{D, B, A, Root}`.
Then we have:
```scala
-(new A).superA == "Root",
- (new C).superB = "Root", (new C).superC = "B",
-(new D).superA == "Root", (new D).superB = "A", (new D).superD = "B",
+(new A).superA == "Root"
+
+(new C).superB == "Root"
+(new C).superC == "B"
+
+(new D).superA == "Root"
+(new D).superB == "A"
+(new D).superD == "B"
```
Note that the `superB` function returns different results
@@ -233,44 +239,27 @@ depending on whether `B` is mixed in with class `Root` or `A`.
```ebnf
SimpleExpr ::= SimpleExpr1 ArgumentExprs
-ArgumentExprs ::= `(' [Exprs] `)'
- | `(' [Exprs `,'] PostfixExpr `:' `_' `*' ')'
+ArgumentExprs ::= ‘(’ [Exprs] ‘)’
+ | ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’
| [nl] BlockExpr
-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.
+Exprs ::= Expr {‘,’ Expr}
+```
+
+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
@@ -336,7 +325,7 @@ would not typecheck.
### Named and Default Arguments
-If an application might uses named arguments $p = e$ or default
+If an application is to use named arguments $p = e$ or default
arguments, the following conditions must hold.
- For every named argument $p_i = e_i$ which appears left of a positional argument
@@ -346,7 +335,7 @@ arguments, the following conditions must hold.
argument defines a parameter which is already specified by a
positional argument.
- Every formal parameter $p_j:T_j$ which is not specified by either a positional
- or a named argument has a default argument.
+ or named argument has a default argument.
If the application uses named or default
arguments the following transformation is applied to convert it into
@@ -422,7 +411,7 @@ On the Java platform version 7 and later, the methods `invoke` and `invokeExact`
## Method Values
```ebnf
-SimpleExpr ::= SimpleExpr1 `_'
+SimpleExpr ::= SimpleExpr1 ‘_’
```
The expression `$e$ _` is well-formed if $e$ is of method
@@ -454,7 +443,7 @@ because otherwise the underscore would be considered part of the name.
SimpleExpr ::= SimpleExpr TypeArgs
```
-A type application `$e$[$T_1 , \ldots , T_n$]` instantiates
+A _type application_ `$e$[$T_1 , \ldots , T_n$]` instantiates
a polymorphic value $e$ of type
`[$a_1$ >: $L_1$ <: $U_1, \ldots , a_n$ >: $L_n$ <: $U_n$]$S$`
with argument types
@@ -471,16 +460,16 @@ $e$.
Type applications can be omitted if
[local type inference](#local-type-inference) can infer best type parameters
-for a polymorphic functions from the types of the actual function arguments
+for a polymorphic function from the types of the actual function arguments
and the expected result type.
## Tuples
```ebnf
-SimpleExpr ::= `(' [Exprs] `)'
+SimpleExpr ::= ‘(’ [Exprs] ‘)’
```
-A tuple expression `($e_1 , \ldots , e_n$)` is an alias
+A _tuple expression_ `($e_1 , \ldots , e_n$)` is an alias
for the class instance creation
`scala.Tuple$n$($e_1 , \ldots , e_n$)`, where $n \geq 2$.
The empty tuple
@@ -489,10 +478,10 @@ The empty tuple
## Instance Creation Expressions
```ebnf
-SimpleExpr ::= `new' (ClassTemplate | TemplateBody)
+SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody)
```
-A simple instance creation expression is of the form
+A _simple instance creation expression_ is of the form
`new $c$`
where $c$ is a [constructor invocation](05-classes-and-objects.html#constructor-invocations). Let $T$ be
the type of $c$. Then $T$ must
@@ -515,7 +504,7 @@ The expression is evaluated by creating a fresh
object of type $T$ which is initialized by evaluating $c$. The
type of the expression is $T$.
-A general instance creation expression is of the form
+A _general instance creation expression_ is of the form
`new $t$` for some [class template](05-classes-and-objects.html#templates) $t$.
Such an expression is equivalent to the block
@@ -560,7 +549,7 @@ BlockExpr ::= ‘{’ CaseClauses ‘}’
Block ::= BlockStat {semi BlockStat} [ResultExpr]
```
-A block expression `{$s_1$; $\ldots$; $s_n$; $e\,$}` is
+A _block expression_ `{$s_1$; $\ldots$; $s_n$; $e\,$}` is
constructed from a sequence of block statements $s_1 , \ldots , s_n$
and a final expression $e$. The statement sequence may not contain
two definitions or declarations that bind the same name in the same
@@ -621,7 +610,7 @@ the existentially quantified type
PostfixExpr ::= InfixExpr [id [nl]]
InfixExpr ::= PrefixExpr
| InfixExpr id [nl] InfixExpr
-PrefixExpr ::= [`-' | `+' | `!' | `~'] SimpleExpr
+PrefixExpr ::= [‘-’ | ‘+’ | ‘!’ | ‘~’] SimpleExpr
```
Expressions can be constructed from operands and operators.
@@ -671,7 +660,7 @@ precedence, with characters on the same line having the same precedence.
```
That is, operators starting with a letter have lowest precedence,
-followed by operators starting with ``|`', etc.
+followed by operators starting with ‘`|`’, etc.
There's one exception to this rule, which concerns
[_assignment operators_](#assignment-operators).
@@ -680,7 +669,7 @@ of simple assignment `(=)`. That is, it is lower than the
precedence of any other operator.
The _associativity_ of an operator is determined by the operator's
-last character. Operators ending in a colon ``:`' are
+last character. Operators ending in a colon ‘`:`’ are
right-associative. All other operators are left-associative.
Precedence and associativity of operators determine the grouping of
@@ -715,7 +704,7 @@ name.
### Assignment Operators
-An assignment operator is an operator symbol (syntax category
+An _assignment operator_ is an operator symbol (syntax category
`op` in [Identifiers](01-lexical-syntax.html#identifiers)) that ends in an equals character
“`=`”, with the exception of operators for which one of
the following conditions holds:
@@ -751,10 +740,10 @@ The re-interpretation occurs if the following two conditions are fulfilled.
## Typed Expressions
```ebnf
-Expr1 ::= PostfixExpr `:' CompoundType
+Expr1 ::= PostfixExpr ‘:’ CompoundType
```
-The typed expression $e: T$ has type $T$. The type of
+The _typed expression_ $e: T$ has type $T$. The type of
expression $e$ is expected to conform to $T$. The result of
the expression is the value of $e$ converted to type $T$.
@@ -770,18 +759,18 @@ Here are examples of well-typed and ill-typed expressions.
## Annotated Expressions
```ebnf
-Expr1 ::= PostfixExpr `:' Annotation {Annotation}
+Expr1 ::= PostfixExpr ‘:’ Annotation {Annotation}
```
-An annotated expression `$e$: @$a_1$ $\ldots$ @$a_n$`
+An _annotated expression_ `$e$: @$a_1$ $\ldots$ @$a_n$`
attaches [annotations](11-annotations.html#user-defined-annotations) $a_1 , \ldots , a_n$ to the
expression $e$.
## Assignments
```ebnf
-Expr1 ::= [SimpleExpr `.'] id `=' Expr
- | SimpleExpr1 ArgumentExprs `=' Expr
+Expr1 ::= [SimpleExpr ‘.’] id ‘=’ Expr
+ | SimpleExpr1 ArgumentExprs ‘=’ Expr
```
The interpretation of an assignment to a simple variable `$x$ = $e$`
@@ -865,10 +854,10 @@ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
## Conditional Expressions
```ebnf
-Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr]
+Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr]
```
-The conditional expression `if ($e_1$) $e_2$ else $e_3$` chooses
+The _conditional expression_ `if ($e_1$) $e_2$ else $e_3$` chooses
one of the values of $e_2$ and $e_3$, depending on the
value of $e_1$. The condition $e_1$ is expected to
conform to type `Boolean`. The then-part $e_2$ and the
@@ -891,10 +880,10 @@ evaluated as if it was `if ($e_1$) $e_2$ else ()`.
## While Loop Expressions
```ebnf
-Expr1 ::= `while' `(' Expr ')' {nl} Expr
+Expr1 ::= ‘while’ ‘(’ Expr ‘)’ {nl} Expr
```
-The while loop expression `while ($e_1$) $e_2$` is typed and
+The _while loop expression_ `while ($e_1$) $e_2$` is typed and
evaluated as if it was an application of `whileLoop ($e_1$) ($e_2$)` where
the hypothetical function `whileLoop` is defined as follows.
@@ -906,26 +895,26 @@ def whileLoop(cond: => Boolean)(body: => Unit): Unit =
## Do Loop Expressions
```ebnf
-Expr1 ::= `do' Expr [semi] `while' `(' Expr ')'
+Expr1 ::= ‘do’ Expr [semi] ‘while’ ‘(’ Expr ‘)’
```
-The do loop expression `do $e_1$ while ($e_2$)` is typed and
+The _do loop expression_ `do $e_1$ while ($e_2$)` is typed and
evaluated as if it was the expression `($e_1$ ; while ($e_2$) $e_1$)`.
A semicolon preceding the `while` symbol of a do loop expression is ignored.
## For Comprehensions and For Loops
```ebnf
-Expr1 ::= `for' (`(' Enumerators `)' | `{' Enumerators `}')
- {nl} [`yield'] Expr
+Expr1 ::= ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’)
+ {nl} [‘yield’] Expr
Enumerators ::= Generator {semi Generator}
-Generator ::= Pattern1 `<-' Expr {[semi] Guard | semi Pattern1 `=' Expr}
-Guard ::= `if' PostfixExpr
+Generator ::= Pattern1 ‘<-’ Expr {[semi] Guard | semi Pattern1 ‘=’ Expr}
+Guard ::= ‘if’ PostfixExpr
```
-A for loop `for ($\mathit{enums}\,$) $e$` executes expression $e$
-for each binding generated by the enumerators $\mathit{enums}$. A for
-comprehension `for ($\mathit{enums}\,$) yield $e$` evaluates
+A _for loop_ `for ($\mathit{enums}\,$) $e$` executes expression $e$
+for each binding generated by the enumerators $\mathit{enums}$.
+A _for comprehension_ `for ($\mathit{enums}\,$) yield $e$` evaluates
expression $e$ for each binding generated by the enumerators $\mathit{enums}$
and collects the results. An enumerator sequence always starts with a
generator; this can be followed by further generators, value
@@ -961,7 +950,7 @@ comprehensions have been eliminated.
`$e$.foreach { case $p$ => $e'$ }`.
- A for comprehension
- ```
+ ```scala
for ($p$ <- $e$; $p'$ <- $e'; \ldots$) yield $e''$
```
@@ -969,13 +958,13 @@ comprehensions have been eliminated.
sequence of generators, definitions, or guards,
is translated to
- ```
+ ```scala
$e$.flatMap { case $p$ => for ($p'$ <- $e'; \ldots$) yield $e''$ }
```
- A for loop
- ```
+ ```scala
for ($p$ <- $e$; $p'$ <- $e'; \ldots$) $e''$
```
@@ -983,7 +972,7 @@ comprehensions have been eliminated.
sequence of generators, definitions, or guards,
is translated to
- ```
+ ```scala
$e$.foreach { case $p$ => for ($p'$ <- $e'; \ldots$) $e''$ }
```
@@ -996,7 +985,7 @@ comprehensions have been eliminated.
`$p'$ = $e'$` is translated to the following generator of pairs of values, where
$x$ and $x'$ are fresh names:
- ```
+ ```scala
($p$, $p'$) <- for ($x @ p$ <- $e$) yield { val $x' @ p'$ = $e'$; ($x$, $x'$) }
```
@@ -1064,10 +1053,10 @@ The code above makes use of the fact that `map`, `flatMap`,
## Return Expressions
```ebnf
-Expr1 ::= `return' [Expr]
+Expr1 ::= ‘return’ [Expr]
```
-A return expression `return $e$` must occur inside the body of some
+A _return expression_ `return $e$` must occur inside the body of some
enclosing named method or function. The innermost enclosing named
method or function in a source program, $f$, must have an explicitly declared result type,
and the type of $e$ must conform to it.
@@ -1101,10 +1090,10 @@ and will propagate up the call stack.
## Throw Expressions
```ebnf
-Expr1 ::= `throw' Expr
+Expr1 ::= ‘throw’ Expr
```
-A throw expression `throw $e$` evaluates the expression
+A _throw expression_ `throw $e$` evaluates the expression
$e$. The type of this expression must conform to
`Throwable`. If $e$ evaluates to an exception
reference, evaluation is aborted with the thrown exception. If $e$
@@ -1118,11 +1107,11 @@ is `scala.Nothing`.
## Try Expressions
```ebnf
-Expr1 ::= `try' (`{' Block `}' | Expr) [`catch' `{' CaseClauses `}']
- [`finally' Expr]
+Expr1 ::= ‘try’ (‘{’ Block ‘}’ | Expr) [‘catch’ ‘{’ CaseClauses ‘}’]
+ [‘finally’ Expr]
```
-A try expression is of the form `try { $b$ } catch $h$`
+A _try expression_ is of the form `try { $b$ } catch $h$`
where the handler $h$ is a
[pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions)
@@ -1141,11 +1130,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
@@ -1172,32 +1159,32 @@ for `try { try { $b$ } catch $e_1$ } finally $e_2$`.
## Anonymous Functions
```ebnf
-Expr ::= (Bindings | [`implicit'] id | `_') `=>' Expr
-ResultExpr ::= (Bindings | ([`implicit'] id | `_') `:' CompoundType) `=>' Block
-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.
-
-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$.
-
-The anonymous function is evaluated as the instance creation expression
+Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr
+ResultExpr ::= (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
+Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’
+Binding ::= (id | ‘_’) [‘:’ Type]
+```
+
+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 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 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 +1192,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:
@@ -1244,7 +1220,7 @@ _ => 5 // The function that ignores its argument
### Placeholder Syntax for Anonymous Functions
```ebnf
-SimpleExpr1 ::= `_'
+SimpleExpr1 ::= ‘_’
```
An expression (of syntactic category `Expr`)
@@ -1290,11 +1266,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
@@ -1311,7 +1285,7 @@ TemplateStat ::= Import
|
```
-Statements occur as parts of blocks and templates. A statement can be
+Statements occur as parts of blocks and templates. A _statement_ can be
an import, a definition or an expression, or it can be empty.
Statements used in the template of a class definition can also be
declarations. An expression that is used as a statement can have an
@@ -1335,10 +1309,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 +1352,36 @@ 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;
+ - class `C` cannot be `final` or `sealed` (for simplicity we ignore the possibility of SAM conversion in the same compilation unit as the sealed class);
+ - `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 +1420,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 +1465,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 +1485,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 +1508,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 +1541,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