summaryrefslogtreecommitdiff
path: root/08-expressions.md
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-03-26 21:40:02 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-03-26 21:40:48 -0700
commit71c1716ae4f16a05825695a33d480ac194c5ae09 (patch)
tree9f6002559be84e32fa3a983f3bbf5dbab199aae5 /08-expressions.md
parentabd0895322985dd4a590f3dd96a488f4e4ff87bf (diff)
downloadscala-71c1716ae4f16a05825695a33d480ac194c5ae09.tar.gz
scala-71c1716ae4f16a05825695a33d480ac194c5ae09.tar.bz2
scala-71c1716ae4f16a05825695a33d480ac194c5ae09.zip
Add language to code blocks. Shorter Example title.
Diffstat (limited to '08-expressions.md')
-rw-r--r--08-expressions.md146
1 files changed, 73 insertions, 73 deletions
diff --git a/08-expressions.md b/08-expressions.md
index 1c72e4734e..db1bd182cd 100644
--- a/08-expressions.md
+++ b/08-expressions.md
@@ -6,7 +6,7 @@ chapter: 6
# Expressions
-```
+```ebnf
Expr ::= (Bindings | id | `_') `=>' Expr
| Expr1
Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr]
@@ -66,14 +66,14 @@ type $T$ and let $t_1[\mathit{tps}_1] >: L_1 <: U_1 , \ldots , t_n[\mathit{tps}_
all the type variables created by skolemization of some part of $e$ which are free in $T$.
Then the _packed type_ of $e$ is
-```
+```scala
$T$ forSome { type $t_1[\mathit{tps}_1] >: L_1 <: U_1$; $\ldots$; type $t_n[\mathit{tps}_n] >: L_n <: U_n$ }.
```
## Literals
-```
+```ebnf
SimpleExpr ::= Literal
```
@@ -102,7 +102,7 @@ A reference to any other member of the "null" object causes a
## Designators
-```
+```ebnf
SimpleExpr ::= Path
| SimpleExpr `.' id
```
@@ -160,7 +160,7 @@ is thrown.
## This and Super
-```
+```ebnf
SimpleExpr ::= [id `.'] `this'
| [id '.'] `super' [ClassQualifier] `.' id
```
@@ -210,10 +210,10 @@ to the type or method of $x$ in the parent trait of $C$ whose simple
name is $T$. That member must be uniquely defined. If it is a method,
it must be concrete.
-### Example:
+### Example
Consider the following class definitions
-```
+```scala
class Root { def x = "Root" }
class A extends Root { override def x = "A" ; def superA = super.x }
trait B extends Root { override def x = "B" ; def superB = super.x }
@@ -229,7 +229,7 @@ The linearization of class `C` is `{C, B, Root}` and
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",
@@ -241,7 +241,7 @@ depending on whether `B` is mixed in with class `Root` or `A`.
## Function Applications
-```
+```ebnf
SimpleExpr ::= SimpleExpr1 ArgumentExprs
ArgumentExprs ::= `(' [Exprs] `)'
| `(' [Exprs `,'] PostfixExpr `:' `_' `*' ')'
@@ -326,20 +326,20 @@ of the caller.
Assume the following function which computes the sum of a
variable number of arguments:
-```
+```scala
def sum(xs: Int*) = (0 /: xs) ((x, y) => x + y)
```
Then
-```
+```scala
sum(1, 2, 3, 4)
sum(List(1, 2, 3, 4): _*)
```
both yield `10` as result. On the other hand,
-```
+```scala
sum(List(1, 2, 3, 4))
```
@@ -369,7 +369,7 @@ If the function $f$
has the form `$p.m$[$\mathit{targs}$]` it is transformed into the
block
-```
+```scala
{ val q = $p$
q.$m$[$\mathit{targs}$]
}
@@ -379,7 +379,7 @@ If the function $f$ is itself an application expression the transformation
is applied recursively on $f$. The result of transforming $f$ is a block of
the form
-```
+```scala
{ val q = $p$
val $x_1$ = expr$_1$
$\ldots$
@@ -404,7 +404,7 @@ that the position of each name matches the position of its corresponding
parameter in the method type `($p_1:T_1 , \ldots , p_n:T_n$)$U$`.
The final result of the transformation is a block of the form
-```
+```scala
{ val q = $p$
val $x_1$ = expr$_1$
$\ldots$
@@ -422,7 +422,7 @@ The final result of the transformation is a block of the form
## Method Values
-```
+```ebnf
SimpleExpr ::= SimpleExpr1 `_'
```
@@ -455,7 +455,7 @@ because otherwise the underscore would be considered part of the name.
## Type Applications
-```
+```ebnf
SimpleExpr ::= SimpleExpr TypeArgs
```
@@ -482,7 +482,7 @@ and the expected result type.
## Tuples
-```
+```ebnf
SimpleExpr ::= `(' [Exprs] `)'
```
@@ -495,7 +495,7 @@ The empty tuple
## Instance Creation Expressions
-```
+```ebnf
SimpleExpr ::= `new' (ClassTemplate | TemplateBody)
```
@@ -510,7 +510,7 @@ $T$. The concrete self type is normally
$T$, except if the expression `new $c$` appears as the
right hand side of a value definition
-```
+```scala
val $x$: $S$ = new $c$
```
@@ -526,7 +526,7 @@ A general instance creation expression is of the form
`new $t$` for some [class template](07-classes-and-objects.html#templates) $t$.
Such an expression is equivalent to the block
-```
+```scala
{ class $a$ extends $t$; new $a$ }
```
@@ -541,19 +541,19 @@ types: If `{$D$}` is a class body, then
###### Example
Consider the following structural instance creation expression:
-```
+```scala
new { def getName() = "aaron" }
```
This is a shorthand for the general instance creation expression
-```
+```scala
new AnyRef{ def getName() = "aaron" }
```
The latter is in turn a shorthand for the block
-```
+```scala
{ class anon\$X extends AnyRef{ def getName() = "aaron" }; new anon\$X }
```
@@ -562,7 +562,7 @@ where `anon\$X` is some freshly created name.
## Blocks
-```
+```ebnf
BlockExpr ::= ‘{’ CaseClauses ‘}’
| ‘{’ Block ‘}’
Block ::= BlockStat {semi BlockStat} [ResultExpr]
@@ -609,14 +609,14 @@ $e$, which defines the result of the block.
###### Example
Assuming a class `Ref[T](x: T)`, the block
-```
+```scala
{ class C extends B {$\ldots$} ; new Ref(new C) }
```
has the type `Ref[_1] forSome { type _1 <: B }`.
The block
-```
+```scala
{ class C extends B {$\ldots$} ; new C }
```
@@ -627,7 +627,7 @@ the existentially quantified type
## Prefix, Infix, and Postfix Operations
-```
+```ebnf
PostfixExpr ::= InfixExpr [id [nl]]
InfixExpr ::= PrefixExpr
| InfixExpr id [nl] InfixExpr
@@ -668,7 +668,7 @@ The _precedence_ of an infix operator is determined by the operator's first
character. Characters are listed below in increasing order of
precedence, with characters on the same line having the same precedence.
-```
+```scala
(all letters)
|
^
@@ -742,7 +742,7 @@ operation `$l$ += $r$`, where $l$, $r$ are expressions.
This operation can be re-interpreted as an operation which corresponds
to the assignment
-```
+```scala
$l$ = $l$ + $r$
```
@@ -762,7 +762,7 @@ The re-interpretation occurs if the following two conditions are fulfilled.
## Typed Expressions
-```
+```ebnf
Expr1 ::= PostfixExpr `:' CompoundType
```
@@ -773,7 +773,7 @@ the expression is the value of $e$ converted to type $T$.
###### Example
Here are examples of well-typed and ill-typed expressions.
-```
+```scala
1: Int // legal, of type Int
1: Long // legal, of type Long
// 1: string // ***** illegal
@@ -782,7 +782,7 @@ Here are examples of well-typed and ill-typed expressions.
## Annotated Expressions
-```
+```ebnf
Expr1 ::= PostfixExpr `:' Annotation {Annotation}
```
@@ -793,7 +793,7 @@ expression $e$.
## Assignments
-```
+```ebnf
Expr1 ::= [SimpleExpr `.'] id `=' Expr
| SimpleExpr1 ArgumentExprs `=' Expr
```
@@ -825,11 +825,11 @@ Here are some assignment expressions and their equivalent expansions.
`x.f(i, j) = e` x.f.update(i, j, e)
-------------------------- ---------------------
-### Example:
+### Example
Here is the usual imperative code for matrix multiplication.
-```
+```scala
def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
val zss: Array[Array[Double]] = new Array(xss.length, yss(0).length)
var i = 0
@@ -854,7 +854,7 @@ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
Desugaring the array accesses and assignments yields the following
expanded version:
-```
+```scala
def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
val zss: Array[Array[Double]] = new Array(xss.length, yss.apply(0).length)
var i = 0
@@ -879,7 +879,7 @@ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
## Conditional Expressions
-```
+```ebnf
Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr]
```
@@ -905,7 +905,7 @@ evaluated as if it was `if ($e_1$) $e_2$ else ()`.
## While Loop Expressions
-```
+```ebnf
Expr1 ::= `while' `(' Expr ')' {nl} Expr
```
@@ -913,7 +913,7 @@ 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.
-```
+```scala
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
if (cond) { body ; whileLoop(cond)(body) } else {}
```
@@ -921,7 +921,7 @@ def whileLoop(cond: => Boolean)(body: => Unit): Unit =
## Do Loop Expressions
-```
+```ebnf
Expr1 ::= `do' Expr [semi] `while' `(' Expr ')'
```
@@ -932,7 +932,7 @@ 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
Enumerators ::= Generator {semi Generator}
@@ -961,7 +961,7 @@ The translation scheme is as follows. In a first step, every
generator `$p$ <- $e$`, where $p$ is not [irrefutable](10-pattern-matching.html#patterns)
for the type of $e$ is replaced by
-```
+```scala
$p$ <- $e$.withFilter { case $p$ => true; case _ => false }
```
@@ -1022,7 +1022,7 @@ comprehensions have been eliminated.
The following code produces all pairs of numbers between $1$ and $n-1$
whose sums are prime.
-```
+```scala
for { i <- 1 until n
j <- 1 until i
if isPrime(i+j)
@@ -1031,7 +1031,7 @@ for { i <- 1 until n
The for comprehension is translated to:
-```
+```scala
(1 until n)
.flatMap {
case i => (1 until i)
@@ -1046,7 +1046,7 @@ For instance, here is a function to compute the transpose of a given matrix:
<!-- see test/files/run/t0421.scala -->
-```
+```scala
def transpose[A](xss: Array[Array[A]]) = {
for (i <- Array.range(0, xss(0).length)) yield
for (xs <- xss) yield xs(i)
@@ -1055,7 +1055,7 @@ def transpose[A](xss: Array[Array[A]]) = {
Here is a function to compute the scalar product of two vectors:
-```
+```scala
def scalprod(xs: Array[Double], ys: Array[Double]) = {
var acc = 0.0
for ((x, y) <- xs zip ys) acc = acc + x * y
@@ -1066,7 +1066,7 @@ def scalprod(xs: Array[Double], ys: Array[Double]) = {
Finally, here is a function to compute the product of two matrices.
Compare with the [imperative version](#example-imperative-matrix-multiplication).
-```
+```scala
def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
val ysst = transpose(yss)
for (xs <- xss) yield
@@ -1082,7 +1082,7 @@ The code above makes use of the fact that `map`, `flatMap`,
## Return Expressions
-```
+```ebnf
Expr1 ::= `return' [Expr]
```
@@ -1120,7 +1120,7 @@ and will propagate up the call stack.
## Throw Expressions
-```
+```ebnf
Expr1 ::= `throw' Expr
```
@@ -1138,7 +1138,7 @@ is `scala.Nothing`.
## Try Expressions
-```
+```ebnf
Expr1 ::= `try' `{' Block `}' [`catch' `{' CaseClauses `}']
[`finally' Expr]
```
@@ -1147,7 +1147,7 @@ A try expression is of the form `try { $b$ } catch $h$`
where the handler $h$ is a
[pattern matching anonymous function](#pattern-matching-anonymous-functions)
-```
+```scala
{ case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ }
```
@@ -1193,7 +1193,7 @@ 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} `)'
@@ -1221,7 +1221,7 @@ type which does not refer to any of the formal parameters $x_i$.
The anonymous function is evaluated as the instance creation expression
-```
+```scala
new scala.Function$n$[$T_1 , \ldots , T_n$, $T$] {
def apply($x_1$: $T_1 , \ldots , x_n$: $T_n$): $T$ = $e$
}
@@ -1247,7 +1247,7 @@ anonymous functions always have to be given explicitly.
###### Example
Examples of anonymous functions:
-```
+```scala
x => x // The identity function
f => g => x => f(g(x)) // Curried function composition
@@ -1266,7 +1266,7 @@ _ => 5 // The function that ignores its argument
### Placeholder Syntax for Anonymous Functions
-```
+```ebnf
SimpleExpr1 ::= `_'
```
@@ -1323,7 +1323,7 @@ include at least the expressions of the following forms:
## Statements
-```
+```ebnf
BlockStat ::= Import
| {Annotation} [‘implicit’ | ‘lazy’] Def
| {Annotation} {LocalModifier} TmplDef
@@ -1380,7 +1380,7 @@ is applied to pick a unique member.
###### Type Instantiation
An expression $e$ of polymorphic type
-```
+```scala
[$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]$T$
```
@@ -1557,7 +1557,7 @@ alternatives in $\mathscr{B}$.
###### Example
Consider the following definitions:
-```
+```scala
class A extends B {}
def f(x: B, y: B) = $\ldots$
def f(x: A, y: B) = $\ldots$
@@ -1569,7 +1569,7 @@ Then the application `f(b, b)` refers to the first
definition of $f$ whereas the application `f(a, a)`
refers to the second. Assume now we add a third overloaded definition
-```
+```scala
def f(x: B, y: A) = $\ldots$
```
@@ -1670,14 +1670,14 @@ any one of them.
###### Example
Consider the two methods:
-```
+```scala
def cons[A](x: A, xs: List[A]): List[A] = x :: xs
def nil[B]: List[B] = Nil
```
and the definition
-```
+```scala
val xs = cons(1, nil)
```
@@ -1693,7 +1693,7 @@ has type `Int` whereas the second argument `nil` is
itself polymorphic. One tries to type-check `nil` with an
expected type `List[a]`. This leads to the constraint system
-```
+```scala
List[b?] <: List[a]
```
@@ -1702,14 +1702,14 @@ that it is a variable in the constraint system.
Because class `List` is covariant, the optimal
solution of this constraint is
-```
+```scala
b = scala.Nothing
```
In a second step, one solves the following constraint system for
the type parameter `a` of `cons`:
-```
+```scala
Int <: a?
List[scala.Nothing] <: List[a?]
List[a?] <: $\mathit{undefined}$
@@ -1717,7 +1717,7 @@ List[a?] <: $\mathit{undefined}$
The optimal solution of this constraint system is
-```
+```scala
a = Int
```
@@ -1728,7 +1728,7 @@ so `Int` is the type inferred for `a`.
Consider now the definition
-```
+```scala
val ys = cons("abc", xs)
```
@@ -1746,7 +1746,7 @@ the second strategy is tried; `xs` is now typed with expected type
In a second step, one solves the following constraint system for
the type parameter `a` of `cons`:
-```
+```scala
String <: a?
List[Int] <: List[a?]
List[a?] <: $\mathit{undefined}$
@@ -1754,7 +1754,7 @@ List[a?] <: $\mathit{undefined}$
The optimal solution of this constraint system is
-```
+```scala
a = scala.Any
```
@@ -1774,7 +1774,7 @@ corresponding fresh name $x_i$. Second, one creates a fresh name $y_i$
for every argument type $T_i$ of the method ($i = 1 , \ldots ,
n$). The result of eta-conversion is then:
-```
+```scala
{ val $x_1$ = $e_1$;
$\ldots$
val $x_m$ = $e_m$;
@@ -1787,7 +1787,7 @@ n$). The result of eta-conversion is then:
The standard Scala library defines a trait `scala.Dynamic` which defines a member
\@invokeDynamic@ as follows:
-```
+```scala
package scala
trait Dynamic {
def applyDynamic (name: String, args: Any*): Any
@@ -1798,14 +1798,14 @@ trait Dynamic {
Assume a selection of the form $e.x$ where the type of $e$ conforms to `scala.Dynamic`.
Further assuming the selection is not followed by any function arguments, such an expression can be rewitten under the conditions given [here](#implicit-conversions) to:
-```
+```scala
$e$.applyDynamic("$x$")
```
If the selection is followed by some arguments, e.g. $e.x(\mathit{args})$, then that expression
is rewritten to
-```
+```scala
$e$.applyDynamic("$x$", $\mathit{args}$)
```