summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--03-lexical-syntax.md237
-rw-r--r--04-identifiers-names-and-scopes.md78
-rw-r--r--05-types.md324
-rw-r--r--06-basic-declarations-and-definitions.md526
-rw-r--r--07-classes-and-objects.md570
-rw-r--r--08-expressions.md571
-rw-r--r--09-implicit-parameters-and-views.md182
-rw-r--r--10-pattern-matching.md342
-rw-r--r--11-top-level-definitions.md84
-rw-r--r--12-xml-expressions-and-patterns.md5
-rw-r--r--14-the-scala-standard-library.md114
11 files changed, 1561 insertions, 1472 deletions
diff --git a/03-lexical-syntax.md b/03-lexical-syntax.md
index 30b4ffdade..ea82d257f0 100644
--- a/03-lexical-syntax.md
+++ b/03-lexical-syntax.md
@@ -95,19 +95,19 @@ _ : = => <- <: <% >: # @
The Unicode operators \\u21D2 ‘$\Rightarrow$’ and \\u2190 ‘$\leftarrow$’, which have the ASCII
equivalents ‘=>’ and ‘<-’, are also reserved.
-(@) Here are examples of identifiers:
+###### Example: here are some identifiers:
- ```
- x Object maxIndex p2p empty_?
- + `yield` αρετη _y dot_product_*
- __system _MAX_LEN_
- ```
+```
+ x Object maxIndex p2p empty_?
+ + `yield` αρετη _y dot_product_*
+ __system _MAX_LEN_
+```
-(@) Backquote-enclosed strings are a solution when one needs to
- access Java identifiers that are reserved words in Scala. For
- instance, the statement `Thread.yield()` is illegal, since
- `yield` is a reserved word in Scala. However, here's a
- work-around: `` Thread.`yield`() ``
+###### Example: backquote-enclosed strings
+When one needs to access Java identifiers that are reserved words in Scala, use backquote-enclosed strings.
+For instance, the statement `Thread.yield()` is illegal, since
+`yield` is a reserved word in Scala. However, here's a
+work-around: `` Thread.`yield`() ``
## Newline Characters
@@ -202,96 +202,97 @@ A single new line token is accepted
- in front of a [parameter clause](#function-declarations-and-definitions), and
- after an [annotation](#user-defined-annotations).
-(@) The following code contains four well-formed statements, each
- on two lines. The newline tokens between the two lines are not
- treated as statement separators.
+###### Example: four well-formed statements, each on two lines
- ```
- if (x > 0)
- x = x - 1
+The newline tokens between the two lines are not
+treated as statement separators.
- while (x > 0)
- x = x / 2
+```
+if (x > 0)
+ x = x - 1
- for (x <- 1 to 10)
- println(x)
+while (x > 0)
+ x = x / 2
- type
- IntList = List[Int]
- ```
+for (x <- 1 to 10)
+ println(x)
-(@) The following code designates an anonymous class:
+type
+ IntList = List[Int]
+```
- ```
- new Iterator[Int]
- {
- private var x = 0
- def hasNext = true
- def next = { x += 1; x }
- }
- ```
+###### Example: an anonymous class
- With an additional newline character, the same code is interpreted as
- an object creation followed by a local block:
+```
+new Iterator[Int]
+{
+ private var x = 0
+ def hasNext = true
+ def next = { x += 1; x }
+}
+```
- ```
- new Iterator[Int]
+With an additional newline character, the same code is interpreted as
+an object creation followed by a local block:
- {
- private var x = 0
- def hasNext = true
- def next = { x += 1; x }
- }
- ```
+```
+new Iterator[Int]
-(@) The following code designates a single expression:
+{
+ private var x = 0
+ def hasNext = true
+ def next = { x += 1; x }
+}
+```
- ```
- x < 0 ||
- x > 10
- ```
+###### Example: a single expression
- With an additional newline character, the same code is interpreted as
- two expressions:
+```
+ x < 0 ||
+ x > 10
+```
- ```
- x < 0 ||
+With an additional newline character, the same code is interpreted as
+two expressions:
- x > 10
- ```
+```
+ x < 0 ||
-(@) The following code designates a single, curried function definition:
+ x > 10
+```
- ```
- def func(x: Int)
- (y: Int) = x + y
- ```
+###### Example: a single, curried function definition
- With an additional newline character, the same code is interpreted as
- an abstract function definition and a syntactically illegal statement:
+```
+def func(x: Int)
+ (y: Int) = x + y
+```
+
+With an additional newline character, the same code is interpreted as
+an abstract function definition and a syntactically illegal statement:
- ```
- def func(x: Int)
+```
+def func(x: Int)
- (y: Int) = x + y
- ```
+ (y: Int) = x + y
+```
-(@) The following code designates an attributed definition:
+###### Example: an attributed definition
- ```
- @serializable
- protected class Data { ... }
- ```
+```
+@serializable
+protected class Data { ... }
+```
- With an additional newline character, the same code is interpreted as
- an attribute and a separate statement (which is syntactically
- illegal).
+With an additional newline character, the same code is interpreted as
+an attribute and a separate statement (which is syntactically
+illegal).
- ```
- @serializable
+```
+@serializable
- protected class Data { ... }
- ```
+protected class Data { ... }
+```
## Literals
@@ -349,7 +350,7 @@ is _pt_. The numeric ranges given by these types are:
`Char` $0$ to $2^{16}-1$
--------------- -----------------------
-(@) Here are some integer literals:
+###### Example: some integer literals
```
0 21 0xFFFFFFFF -42L
@@ -378,17 +379,20 @@ If a floating point literal in a program is followed by a token
starting with a letter, there must be at least one intervening
whitespace character between the two tokens.
-(@) Here are some floating point literals:
+###### Example: some floating point literals
+
+```
+0.0 1e30f 3.14159f 1.0e-100 .1
+```
+
+###### Example: tokenizing
- ```
- 0.0 1e30f 3.14159f 1.0e-100 .1
- ```
+The phrase `1.toString` parses as three different tokens:
+the integer literal `1`, a `.`, and the identifier `toString`.
-(@) The phrase `1.toString` parses as three different tokens:
- the integer literal `1`, a `.`, and the identifier `toString`.
+###### Example: invalid floating point literal
-(@) `1.` is not a valid floating point literal, because the
- mandatory digit after the `.` is missing.
+`1.` is not a valid floating point literal because the mandatory digit after the `.` is missing.
### Boolean Literals
@@ -411,11 +415,11 @@ A character literal is a single character enclosed in quotes.
The character is either a printable unicode character or is described
by an [escape sequence](#escape-sequences).
-(@) Here are some character literals:
+###### Example: some character literals
- ```
- 'a' '\u0041' '\n' '\t'
- ```
+```
+'a' '\u0041' '\n' '\t'
+```
Note that `'\u000A'` is _not_ a valid character literal because
Unicode conversion is done before literal parsing and the Unicode
@@ -438,12 +442,12 @@ contains a double quote character, it must be escaped,
i.e. `"\""`. The value of a string literal is an instance of
class `String`.
-(@) Here are some string literals:
+###### Example: some string literals
- ```
- "Hello,\nWorld!"
- "This string contains a \" character."
- ```
+```
+"Hello,\nWorld!"
+"This string contains a \" character."
+```
#### Multi-Line String Literals
@@ -460,21 +464,21 @@ must not necessarily be printable; newlines or other
control characters are also permitted. Unicode escapes work as everywhere else, but none
of the escape sequences [here](#escape-sequences) are interpreted.
-(@) Here is a multi-line string literal:
+###### Example: a multi-line string literal:
- ```
- """the present string
- spans three
- lines."""
- ```
+```
+ """the present string
+ spans three
+ lines."""
+```
- This would produce the string:
+This would produce the string:
- ```
- the present string
- spans three
- lines.
- ```
+```
+the present string
+ spans three
+ lines.
+```
The Scala library contains a utility method `stripMargin`
which can be used to strip leading whitespace from multi-line strings.
@@ -591,14 +595,15 @@ The scanner switches from XML mode to Scala mode if either
Note that no Scala tokens are constructed in XML mode, and that comments are interpreted
as text.
-(@) The following value definition uses an XML literal with two embedded
-Scala expressions
+###### Example: XML literals
- ```
- val b = <book>
- <title>The Scala Language Specification</title>
- <version>{scalaBook.version}</version>
- <authors>{scalaBook.authors.mkList("", ", ", "")}</authors>
- </book>
- ```
+The following value definition uses an XML literal with two embedded
+Scala expressions:
+```
+val b = <book>
+ <title>The Scala Language Specification</title>
+ <version>{scalaBook.version}</version>
+ <authors>{scalaBook.authors.mkList("", ", ", "")}</authors>
+ </book>
+```
diff --git a/04-identifiers-names-and-scopes.md b/04-identifiers-names-and-scopes.md
index 1e74e52b5f..7caedb0241 100644
--- a/04-identifiers-names-and-scopes.md
+++ b/04-identifiers-names-and-scopes.md
@@ -54,44 +54,46 @@ is bound by a definition or declaration, then $x$ refers to the entity
introduced by that binding. In that case, the type of $x$ is the type
of the referenced entity.
-(@) Assume the following two definitions of a objects named `X` in packages `P` and `Q`.
-
- ```
- package P {
- object X { val x = 1; val y = 2 }
- }
-
- package Q {
- object X { val x = true; val y = "" }
- }
- ```
-
- The following program illustrates different kinds of bindings and
- precedences between them.
-
- ```
- 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
- }}}}}}
- ```
+###### Example: bindings
+
+Assume the following two definitions of a objects named `X` in packages `P` and `Q`.
+
+```
+package P {
+ object X { val x = 1; val y = 2 }
+}
+
+package Q {
+ object X { val x = true; val y = "" }
+}
+```
+
+The following program illustrates different kinds of bindings and
+precedences between them.
+
+```
+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
+}}}}}}
+```
A reference to a qualified (type- or term-) identifier $e.x$ refers to
the member of the type $T$ of $e$ which has the name $x$ in the same
diff --git a/05-types.md b/05-types.md
index 25210294ea..294b87a71d 100644
--- a/05-types.md
+++ b/05-types.md
@@ -143,16 +143,18 @@ A qualified type designator has the form `p.t` where `p` is
a [path](#paths) and _t_ is a type name. Such a type designator is
equivalent to the type projection `p.type#t`.
-(@) Some type designators and their expansions are listed below. We assume
- a local type parameter $t$, a value `maintable`
- with a type member `Node` and the standard class `scala.Int`,
+###### Example: fully qualified type designators
- -------------------- --------------------------
- t ε.type#t
- Int scala.type#Int
- scala.Int scala.type#Int
- data.maintable.Node data.maintable.type#Node
- -------------------- --------------------------
+Some type designators and their expansions are listed below. We assume
+a local type parameter $t$, a value `maintable`
+with a type member `Node` and the standard class `scala.Int`,
+
+|-------------------- | --------------------------|
+|t | ε.type#t |
+|Int | scala.type#Int |
+|scala.Int | scala.type#Int |
+|data.maintable.Node | data.maintable.type#Node |
+|-------------------- | --------------------------|
### Parameterized Types
@@ -173,44 +175,47 @@ well-formed if each actual type parameter
_conforms to its bounds_, i.e. $\sigma L_i <: T_i <: \sigma U_i$ where $\sigma$ is the
substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$.
-(@param-types) Given the partial type definitions:
+###### Example: parameterized types
+Given the partial type definitions:
- ```
- class TreeMap[A <: Comparable[A], B] { … }
- class List[A] { … }
- class I extends Comparable[I] { … }
-
- class F[M[_], X] { … }
- class S[K <: String] { … }
- class G[M[ Z <: I ], I] { … }
- ```
+```
+class TreeMap[A <: Comparable[A], B] { … }
+class List[A] { … }
+class I extends Comparable[I] { … }
- the following parameterized types are well formed:
+class F[M[_], X] { … }
+class S[K <: String] { … }
+class G[M[ Z <: I ], I] { … }
+```
- ```
- TreeMap[I, String]
- List[I]
- List[List[Boolean]]
-
- F[List, Int]
- G[S, String]
- ```
+the following parameterized types are well formed:
-(@) Given the type definitions of (@param-types),
- the following types are ill-formed:
+```
+TreeMap[I, String]
+List[I]
+List[List[Boolean]]
- ```
- TreeMap[I] // illegal: wrong number of parameters
- TreeMap[List[I], Int] // illegal: type parameter not within bound
-
- F[Int, Boolean] // illegal: Int is not a type constructor
- F[TreeMap, Int] // illegal: TreeMap takes two parameters,
- // F expects a constructor taking one
- G[S, Int] // illegal: S constrains its parameter to
- // conform to String,
- // G expects type constructor with a parameter
- // that conforms to Int
- ```
+F[List, Int]
+G[S, String]
+```
+
+###### Example: ill-formed types
+
+Given the [above type definitions](example-parameterized-types),
+the following types are ill-formed:
+
+```
+TreeMap[I] // illegal: wrong number of parameters
+TreeMap[List[I], Int] // illegal: type parameter not within bound
+
+F[Int, Boolean] // illegal: Int is not a type constructor
+F[TreeMap, Int] // illegal: TreeMap takes two parameters,
+ // F expects a constructor taking one
+G[S, Int] // illegal: S constrains its parameter to
+ // conform to String,
+ // G expects type constructor with a parameter
+ // that conforms to Int
+```
### Tuple Types
@@ -250,12 +255,13 @@ An annotated type $T$ `$a_1 , \ldots , a_n$`
attaches [annotations](#user-defined-annotations)
$a_1 , \ldots , a_n$ to the type $T$.
-(@) The following type adds the `@suspendable` annotation to the type
- `String`:
+###### Example: annotated type
- ```
- String @suspendable
- ```
+The following type adds the `@suspendable` annotation to the type `String`:
+
+```
+String @suspendable
+```
### Compound Types
@@ -287,7 +293,7 @@ any value parameter may only refer to type parameters or abstract
types that are contained inside the refinement. That is, it must refer
either to a type parameter of the method itself, or to a type
definition within the refinement. This restriction does not apply to
-the function's result type.
+the method's result type.
If no refinement is given, the empty refinement is implicitly added,
i.e.\ `$T_1$ with … with $T_n$` is a shorthand for
@@ -297,35 +303,37 @@ A compound type may also consist of just a refinement
`{ $R$ }` with no preceding component types. Such a type is
equivalent to `AnyRef{ R }`.
-(@) The following example shows how to declare and use a function which
- parameter's type contains a refinement with structural declarations.
-
- ```
- case class Bird (val name: String) extends Object {
- def fly(height: Int) = …
- …
- }
- case class Plane (val callsign: String) extends Object {
- def fly(height: Int) = …
- …
- }
- def takeoff(
- runway: Int,
- r: { val callsign: String; def fly(height: Int) }) = {
- tower.print(r.callsign + " requests take-off on runway " + runway)
- tower.read(r.callsign + " is clear for take-off")
- r.fly(1000)
- }
- val bird = new Bird("Polly the parrot"){ val callsign = name }
- val a380 = new Plane("TZ-987")
- takeoff(42, bird)
- takeoff(89, a380)
- ```
-
- Although `Bird` and `Plane` do not share any parent class other than
- `Object`, the parameter _r_ of function `takeoff` is defined using a
- refinement with structural declarations to accept any object that declares
- a value `callsign` and a `fly` function.
+###### Example: structural refinement in a method's parameter type
+
+The following example shows how to declare and use a method which
+a parameter type that contains a refinement with structural declarations.
+
+```
+case class Bird (val name: String) extends Object {
+ def fly(height: Int) = …
+…
+}
+case class Plane (val callsign: String) extends Object {
+ def fly(height: Int) = …
+…
+}
+def takeoff(
+ runway: Int,
+ r: { val callsign: String; def fly(height: Int) }) = {
+ tower.print(r.callsign + " requests take-off on runway " + runway)
+ tower.read(r.callsign + " is clear for take-off")
+ r.fly(1000)
+}
+val bird = new Bird("Polly the parrot"){ val callsign = name }
+val a380 = new Plane("TZ-987")
+takeoff(42, bird)
+takeoff(89, a380)
+```
+
+Although `Bird` and `Plane` do not share any parent class other than
+`Object`, the parameter _r_ of method `takeoff` is defined using a
+refinement with structural declarations to accept any object that declares
+a value `callsign` and a `fly` method.
### Infix Types
@@ -495,54 +503,60 @@ or [tuple types](#tuple-types).
Their expansion is then the expansion in the equivalent parameterized
type.
-(@) Assume the class definitions
-
- ```
- class Ref[T]
- abstract class Outer { type T } .
- ```
+###### Example: existential types
- Here are some examples of existential types:
-
- ```
- Ref[T] forSome { type T <: java.lang.Number }
- Ref[x.T] forSome { val x: Outer }
- Ref[x_type # T] forSome { type x_type <: Outer with Singleton }
- ```
-
- The last two types in this list are equivalent.
- An alternative formulation of the first type above using wildcard syntax is:
-
- ```
- Ref[_ <: java.lang.Number]
- ```
+Assume the class definitions
-(@) The type `List[List[_]]` is equivalent to the existential type
-
- ```
- List[List[t] forSome { type t }] .
- ```
+```
+class Ref[T]
+abstract class Outer { type T } .
+```
-(@) Assume a covariant type
-
- ```
- class List[+T]
- ```
+Here are some examples of existential types:
- The type
-
- ```
- List[T] forSome { type T <: java.lang.Number }
- ```
+```
+Ref[T] forSome { type T <: java.lang.Number }
+Ref[x.T] forSome { val x: Outer }
+Ref[x_type # T] forSome { type x_type <: Outer with Singleton }
+```
+
+The last two types in this list are equivalent.
+An alternative formulation of the first type above using wildcard syntax is:
- is equivalent (by simplification rule 4 above) to
+```
+Ref[_ <: java.lang.Number]
+```
+
+###### Example: abbreviating an existential type with the underscore
+
+The type `List[List[_]]` is equivalent to the existential type
+
+```
+List[List[t] forSome { type t }] .
+```
+
+###### Example: existential type equivalence
+
+Assume a covariant type
- ```
- List[java.lang.Number] forSome { type T <: java.lang.Number }
- ```
+```
+class List[+T]
+```
+
+The type
- which is in turn equivalent (by simplification rules 2 and 3 above) to
- `List[java.lang.Number]`.
+```
+List[T] forSome { type T <: java.lang.Number }
+```
+
+is equivalent (by simplification rule 4 above) to
+
+```
+List[java.lang.Number] forSome { type T <: java.lang.Number }
+```
+
+which is in turn equivalent (by simplification rules 2 and 3 above) to
+`List[java.lang.Number]`.
## Non-Value Types
@@ -573,21 +587,23 @@ Method types do not exist as types of values. If a method name is used
as a value, its type is [implicitly converted](#implicit-conversions) to a
corresponding function type.
-(@) The declarations
-
- ```
- def a: Int
- def b (x: Int): Boolean
- def c (x: Int) (y: String, z: String): String
- ```
+###### Example
- produce the typings
+The declarations
- ```
- a: => Int
- b: (Int) Boolean
- c: (Int) (String, String) String
- ```
+```
+def a: Int
+def b (x: Int): Boolean
+def c (x: Int) (y: String, z: String): String
+```
+
+produce the typings
+
+```
+a: => Int
+b: (Int) Boolean
+c: (Int) (String, String) String
+```
### Polymorphic Method Types
@@ -601,19 +617,21 @@ take type arguments `$S_1 , \ldots , S_n$` which
`$L_1 , \ldots , L_n$` and the upper bounds
`$U_1 , \ldots , U_n$` and that yield results of type $T$.
-(@) The declarations
+###### Example
- ```
- def empty[A]: List[A]
- def union[A <: Comparable[A]] (x: Set[A], xs: Set[A]): Set[A]
- ```
+The declarations
- produce the typings
+```
+def empty[A]: List[A]
+def union[A <: Comparable[A]] (x: Set[A], xs: Set[A]): Set[A]
+```
+
+produce the typings
- ```
- empty : [A >: Nothing <: Any] List[A]
- union : [A >: Nothing <: Comparable[A]] (x: Set[A], xs: Set[A]) Set[A] .
- ```
+```
+empty : [A >: Nothing <: Any] List[A]
+union : [A >: Nothing <: Comparable[A]] (x: Set[A], xs: Set[A]) Set[A] .
+```
### Type Constructors
@@ -624,17 +642,19 @@ represents a type that is expected by a
[abstract type constructor binding](#type-declarations-and-type-aliases) with
the corresponding type parameter clause.
-(@) Consider this fragment of the `Iterable[+X]` class:
+###### Example
+
+Consider this fragment of the `Iterable[+X]` class:
- ```
- trait Iterable[+X] {
- def flatMap[newType[+X] <: Iterable[X], S](f: X => newType[S]): newType[S]
- }
- ```
+```
+trait Iterable[+X] {
+ def flatMap[newType[+X] <: Iterable[X], S](f: X => newType[S]): newType[S]
+}
+```
- Conceptually, the type constructor `Iterable` is a name for the
- anonymous type `[+X] Iterable[X]`, which may be passed to the
- `newType` type constructor parameter in `flatMap`.
+Conceptually, the type constructor `Iterable` is a name for the
+anonymous type `[+X] Iterable[X]`, which may be passed to the
+`newType` type constructor parameter in `flatMap`.
<!-- ### Overloaded Types
@@ -644,7 +664,7 @@ same name, we model
An overloaded type consisting of type alternatives $T_1 \commadots T_n (n \geq 2)$ is denoted internally $T_1 \overload \ldots \overload T_n$.
-(@) The definitions
+###### Example: The definitions
```
def println: Unit
def println(s: String): Unit = $\ldots$
@@ -662,7 +682,7 @@ println: => Unit $\overload$
[A] (A) (A => String) Unit
```
-(@) The definitions
+###### Example: The definitions
```
def f(x: T): T = $\ldots$
val f = 0
diff --git a/06-basic-declarations-and-definitions.md b/06-basic-declarations-and-definitions.md
index 5d8f6aee78..b8eb226d3d 100644
--- a/06-basic-declarations-and-definitions.md
+++ b/06-basic-declarations-and-definitions.md
@@ -160,24 +160,26 @@ val $x$ = $e$ match { case $p$ => $x$ }
$e$ match { case $p$ => ()}
```
-(@) The following are examples of value definitions
+###### Example
- ```
- val pi = 3.1415
- val pi: Double = 3.1415 // equivalent to first definition
- val Some(x) = f() // a pattern definition
- val x :: xs = mylist // an infix pattern definition
- ```
+The following are examples of value definitions
- The last two definitions have the following expansions.
+```
+val pi = 3.1415
+val pi: Double = 3.1415 // equivalent to first definition
+val Some(x) = f() // a pattern definition
+val x :: xs = mylist // an infix pattern definition
+```
+
+The last two definitions have the following expansions.
- ```
- val x = f() match { case Some(x) => x }
+```
+val x = f() match { case Some(x) => x }
- val x$\$$ = mylist match { case x :: xs => (x, xs) }
- val x = x$\$$._1
- val xs = x$\$$._2
- ```
+val x$\$$ = mylist match { case x :: xs => (x, xs) }
+val x = x$\$$._1
+val xs = x$\$$._2
+```
The name of any declared or defined value may not end in `_=`.
@@ -253,35 +255,37 @@ The template then has these getter and setter functions as
members, whereas the original variable cannot be accessed directly as
a template member.
-(@) The following example shows how _properties_ can be
- simulated in Scala. It defines a class `TimeOfDayVar` of time
- values with updatable integer fields representing hours, minutes, and
- seconds. Its implementation contains tests that allow only legal
- values to be assigned to these fields. The user code, on the other
- hand, accesses these fields just like normal variables.
-
- ```
- class TimeOfDayVar {
- private var h: Int = 0
- private var m: Int = 0
- private var s: Int = 0
-
- def hours = h
- def hours_= (h: Int) = if (0 <= h && h < 24) this.h = h
- else throw new DateError()
-
- def minutes = m
- def minutes_= (m: Int) = if (0 <= m && m < 60) this.m = m
- else throw new DateError()
-
- def seconds = s
- def seconds_= (s: Int) = if (0 <= s && s < 60) this.s = s
- else throw new DateError()
- }
- val d = new TimeOfDayVar
- d.hours = 8; d.minutes = 30; d.seconds = 0
- d.hours = 25 // throws a DateError exception
- ```
+###### Example
+
+The following example shows how _properties_ can be
+simulated in Scala. It defines a class `TimeOfDayVar` of time
+values with updatable integer fields representing hours, minutes, and
+seconds. Its implementation contains tests that allow only legal
+values to be assigned to these fields. The user code, on the other
+hand, accesses these fields just like normal variables.
+
+```
+class TimeOfDayVar {
+ private var h: Int = 0
+ private var m: Int = 0
+ private var s: Int = 0
+
+ def hours = h
+ def hours_= (h: Int) = if (0 <= h && h < 24) this.h = h
+ else throw new DateError()
+
+ def minutes = m
+ def minutes_= (m: Int) = if (0 <= m && m < 60) this.m = m
+ else throw new DateError()
+
+ def seconds = s
+ def seconds_= (s: Int) = if (0 <= s && s < 60) this.s = s
+ else throw new DateError()
+}
+val d = new TimeOfDayVar
+d.hours = 8; d.minutes = 30; d.seconds = 0
+d.hours = 25 // throws a DateError exception
+```
A variable declaration `var $x_1 , \ldots , x_n$: $T$` is a shorthand for the
@@ -342,51 +346,55 @@ That is, the type $T$ in a type alias `type $t$[$\mathit{tps}\,$] = $T$` may not
refer directly or indirectly to the name $t$. It is also an error if
an abstract type is directly or indirectly its own upper or lower bound.
-(@) The following are legal type declarations and definitions:
+###### Example
+
+The following are legal type declarations and definitions:
- ```
- type IntList = List[Integer]
- type T <: Comparable[T]
- type Two[A] = Tuple2[A, A]
- type MyCollection[+X] <: Iterable[X]
- ```
+```
+type IntList = List[Integer]
+type T <: Comparable[T]
+type Two[A] = Tuple2[A, A]
+type MyCollection[+X] <: Iterable[X]
+```
- The following are illegal:
+The following are illegal:
- ```
- type Abs = Comparable[Abs] // recursive type alias
+```
+type Abs = Comparable[Abs] // recursive type alias
- type S <: T // S, T are bounded by themselves.
- type T <: S
+type S <: T // S, T are bounded by themselves.
+type T <: S
- type T >: Comparable[T.That] // Cannot select from T.
- // T is a type, not a value
- type MyCollection <: Iterable // Type constructor members must explicitly
- // state their type parameters.
- ```
+type T >: Comparable[T.That] // Cannot select from T.
+ // T is a type, not a value
+type MyCollection <: Iterable // Type constructor members must explicitly
+ // state their type parameters.
+```
If a type alias `type $t$[$\mathit{tps}\,$] = $S$` refers to a class type
$S$, the name $t$ can also be used as a constructor for
objects of type $S$.
-(@) The `Predef` object contains a definition which establishes `Pair`
- as an alias of the parameterized class `Tuple2`:
+###### Example
- ```
- type Pair[+A, +B] = Tuple2[A, B]
- object Pair {
- def apply[A, B](x: A, y: B) = Tuple2(x, y)
- def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
- }
- ```
+The `Predef` object contains a definition which establishes `Pair`
+as an alias of the parameterized class `Tuple2`:
+
+```
+type Pair[+A, +B] = Tuple2[A, B]
+object Pair {
+ def apply[A, B](x: A, y: B) = Tuple2(x, y)
+ def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
+}
+```
- As a consequence, for any two types $S$ and $T$, the type
- `Pair[$S$, $T\,$]` is equivalent to the type `Tuple2[$S$, $T\,$]`.
- `Pair` can also be used as a constructor instead of `Tuple2`, as in:
+As a consequence, for any two types $S$ and $T$, the type
+`Pair[$S$, $T\,$]` is equivalent to the type `Tuple2[$S$, $T\,$]`.
+`Pair` can also be used as a constructor instead of `Tuple2`, as in:
- ```
- val x: Pair[Int, String] = new Pair(1, "abc")
- ```
+```
+val x: Pair[Int, String] = new Pair(1, "abc")
+```
## Type Parameters
@@ -428,28 +436,29 @@ A type constructor parameter adds a nested type parameter clause to the type par
The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. Higher-order type parameters (the type parameters of a type parameter $t$) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of $t$. Therefore, their names must only be pairwise different from the names of other visible parameters. Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a ‘_’, which is nowhere visible.
-(@) Here are some well-formed type parameter clauses:
+###### Example
+Here are some well-formed type parameter clauses:
- ```
- [S, T]
- [@specialized T, U]
- [Ex <: Throwable]
- [A <: Comparable[B], B <: A]
- [A, B >: A, C >: A <: B]
- [M[X], N[X]]
- [M[_], N[_]] // equivalent to previous clause
- [M[X <: Bound[X]], Bound[_]]
- [M[+X] <: Iterable[X]]
- ```
+```
+[S, T]
+[@specialized T, U]
+[Ex <: Throwable]
+[A <: Comparable[B], B <: A]
+[A, B >: A, C >: A <: B]
+[M[X], N[X]]
+[M[_], N[_]] // equivalent to previous clause
+[M[X <: Bound[X]], Bound[_]]
+[M[+X] <: Iterable[X]]
+```
- The following type parameter clauses are illegal:
+The following type parameter clauses are illegal:
- ```
- [A >: A] // illegal, `A' has itself as bound
- [A <: B, B <: C, C <: A] // illegal, `A' has itself as bound
- [A, B, C >: A <: B] // illegal lower bound `A' of `C' does
- // not conform to upper bound `B'.
- ```
+```
+[A >: A] // illegal, `A' has itself as bound
+[A <: B, B <: C, C <: A] // illegal, `A' has itself as bound
+[A, B, C >: A <: B] // illegal lower bound `A' of `C' does
+ // not conform to upper bound `B'.
+```
## Variance Annotations
@@ -502,75 +511,78 @@ References to the type parameters in
checked for their variance position. In these members the type parameter may
appear anywhere without restricting its legal variance annotations.
-(@) The following variance annotation is legal.
-
- ```
- abstract class P[+A, +B] {
- def fst: A; def snd: B
- }
- ```
-
- With this variance annotation, type instances
- of $P$ subtype covariantly with respect to their arguments.
- For instance,
-
- ```
- P[IOException, String] <: P[Throwable, AnyRef]
- ```
-
- If the members of $P$ are mutable variables,
- the same variance annotation becomes illegal.
-
- ```
- abstract class Q[+A, +B](x: A, y: B) {
- var fst: A = x // **** error: illegal variance:
- var snd: B = y // `A', `B' occur in invariant position.
- }
- ```
-
- If the mutable variables are object-private, the class definition
- becomes legal again:
-
- ```
- abstract class R[+A, +B](x: A, y: B) {
- private[this] var fst: A = x // OK
- private[this] var snd: B = y // OK
- }
- ```
-
-(@) The following variance annotation is illegal, since $a$ appears
- in contravariant position in the parameter of `append`:
-
- ```
- abstract class Sequence[+A] {
- def append(x: Sequence[A]): Sequence[A]
- // **** error: illegal variance:
- // `A' occurs in contravariant position.
- }
- ```
-
- The problem can be avoided by generalizing the type of `append`
- by means of a lower bound:
-
- ```
- abstract class Sequence[+A] {
- def append[B >: A](x: Sequence[B]): Sequence[B]
- }
- ```
-
-(@) Here is a case where a contravariant type parameter is useful.
-
- ```
- abstract class OutputChannel[-A] {
- def write(x: A): Unit
- }
- ```
-
- With that annotation, we have that
- `OutputChannel[AnyRef]` conforms to `OutputChannel[String]`.
- That is, a
- channel on which one can write any object can substitute for a channel
- on which one can write only strings.
+###### Example
+The following variance annotation is legal.
+
+```
+abstract class P[+A, +B] {
+ def fst: A; def snd: B
+}
+```
+
+With this variance annotation, type instances
+of $P$ subtype covariantly with respect to their arguments.
+For instance,
+
+```
+P[IOException, String] <: P[Throwable, AnyRef]
+```
+
+If the members of $P$ are mutable variables,
+the same variance annotation becomes illegal.
+
+```
+abstract class Q[+A, +B](x: A, y: B) {
+ var fst: A = x // **** error: illegal variance:
+ var snd: B = y // `A', `B' occur in invariant position.
+}
+```
+
+If the mutable variables are object-private, the class definition
+becomes legal again:
+
+```
+abstract class R[+A, +B](x: A, y: B) {
+ private[this] var fst: A = x // OK
+ private[this] var snd: B = y // OK
+}
+```
+
+###### Example
+
+The following variance annotation is illegal, since $a$ appears
+in contravariant position in the parameter of `append`:
+
+```
+abstract class Sequence[+A] {
+ def append(x: Sequence[A]): Sequence[A]
+ // **** error: illegal variance:
+ // `A' occurs in contravariant position.
+}
+```
+
+The problem can be avoided by generalizing the type of `append`
+by means of a lower bound:
+
+```
+abstract class Sequence[+A] {
+ def append[B >: A](x: Sequence[B]): Sequence[B]
+}
+```
+
+###### Example: Here is a case where a contravariant type parameter is useful.
+
+```
+abstract class OutputChannel[-A] {
+ def write(x: A): Unit
+}
+```
+
+With that annotation, we have that
+`OutputChannel[AnyRef]` conforms to `OutputChannel[String]`.
+That is, a
+channel on which one can write any object can substitute for a channel
+on which one can write only strings.
## Function Declarations and Definitions
@@ -636,21 +648,22 @@ parameter clauses, as well as the method return type and the function body, if
they are given. Both type parameter names and value parameter names must
be pairwise distinct.
-(@) In the method
+###### Example
+In the method
- ```
- def compare[T](a: T = 0)(b: T = a) = (a == b)
- ```
+```
+def compare[T](a: T = 0)(b: T = a) = (a == b)
+```
- the default expression `0` is type-checked with an undefined expected
- type. When applying `compare()`, the default value `0` is inserted
- and `T` is instantiated to `Int`. The methods computing the default
- arguments have the form:
+the default expression `0` is type-checked with an undefined expected
+type. When applying `compare()`, the default value `0` is inserted
+and `T` is instantiated to `Int`. The methods computing the default
+arguments have the form:
- ```
- def compare$\$$default$\$$1[T]: Int = 0
- def compare$\$$default$\$$2[T](a: T): T = a
- ```
+```
+def compare$\$$default$\$$1[T]: Int = 0
+def compare$\$$default$\$$2[T](a: T): T = a
+```
### By-Name Parameters
@@ -673,14 +686,15 @@ classes for which a `val` prefix is implicitly generated. The
by-name modifier is also disallowed for
[implicit parameters](#implicit-parameters).
-(@) The declaration
+###### Example
+The declaration
- ```
- def whileLoop (cond: => Boolean) (stat: => Unit): Unit
- ```
+```
+def whileLoop (cond: => Boolean) (stat: => Unit): Unit
+```
- indicates that both parameters of `whileLoop` are evaluated using
- call-by-name.
+indicates that both parameters of `whileLoop` are evaluated using
+call-by-name.
### Repeated Parameters
@@ -710,44 +724,45 @@ that application is taken to be
It is not allowed to define any default arguments in a parameter section
with a repeated parameter.
-(@) The following method definition computes the sum of the squares of a
- variable number of integer arguments.
+###### Example
+The following method definition computes the sum of the squares of a
+variable number of integer arguments.
- ```
- def sum(args: Int*) = {
- var result = 0
- for (arg <- args) result += arg * arg
- result
- }
- ```
+```
+def sum(args: Int*) = {
+ var result = 0
+ for (arg <- args) result += arg * arg
+ result
+}
+```
- The following applications of this method yield `0`, `1`,
- `6`, in that order.
+The following applications of this method yield `0`, `1`,
+`6`, in that order.
- ```
- sum()
- sum(1)
- sum(1, 2, 3)
- ```
+```
+sum()
+sum(1)
+sum(1, 2, 3)
+```
- Furthermore, assume the definition:
+Furthermore, assume the definition:
- ```
- val xs = List(1, 2, 3)
- ```
+```
+val xs = List(1, 2, 3)
+```
- The following application of method `sum` is ill-formed:
+The following application of method `sum` is ill-formed:
- ```
- sum(xs) // ***** error: expected: Int, found: List[Int]
- ```
+```
+sum(xs) // ***** error: expected: Int, found: List[Int]
+```
- By contrast, the following application is well formed and yields again
- the result `6`:
+By contrast, the following application is well formed and yields again
+the result `6`:
- ```
- sum(xs: _*)
- ```
+```
+sum(xs: _*)
+```
### Procedures
@@ -769,27 +784,28 @@ and the equals sign are omitted; its defining expression must be a block.
E.g., `def $f$($\mathit{ps}$) {$\mathit{stats}$}` is equivalent to
`def $f$($\mathit{ps}$): Unit = {$\mathit{stats}$}`.
-(@) Here is a declaration and a definition of a procedure named `write`:
+###### Example
+Here is a declaration and a definition of a procedure named `write`:
- ```
- trait Writer {
- def write(str: String)
- }
- object Terminal extends Writer {
- def write(str: String) { System.out.println(str) }
- }
- ```
+```
+trait Writer {
+ def write(str: String)
+}
+object Terminal extends Writer {
+ def write(str: String) { System.out.println(str) }
+}
+```
- The code above is implicitly completed to the following code:
+The code above is implicitly completed to the following code:
- ```
- trait Writer {
- def write(str: String): Unit
- }
- object Terminal extends Writer {
- def write(str: String): Unit = { System.out.println(str) }
- }
- ```
+```
+trait Writer {
+ def write(str: String): Unit
+}
+object Terminal extends Writer {
+ def write(str: String): Unit = { System.out.println(str) }
+}
+```
### Method Return Type Inference
@@ -803,19 +819,20 @@ right-hand side of $m$ can be determined, which is then taken as the
return type of $m$. Note that $R$ may be different from $R'$, as long
as $R$ conforms to $R'$.
-(@) Assume the following definitions:
+###### Example
+Assume the following definitions:
- ```
- trait I {
- def factorial(x: Int): Int
- }
- class C extends I {
- def factorial(x: Int) = if (x == 0) 1 else x * factorial(x - 1)
- }
- ```
+```
+trait I {
+ def factorial(x: Int): Int
+}
+class C extends I {
+ def factorial(x: Int) = if (x == 0) 1 else x * factorial(x - 1)
+}
+```
- Here, it is OK to leave out the result type of `factorial`
- in `C`, even though the method is recursive.
+Here, it is OK to leave out the result type of `factorial`
+in `C`, even though the method is recursive.
@@ -901,23 +918,24 @@ An import clause with multiple import expressions
sequence of import clauses
`import $p_1$.$I_1$; $\ldots$; import $p_n$.$I_n$`.
-(@) Consider the object definition:
+###### Example
+Consider the object definition:
- ```
- object M {
- def z = 0, one = 1
- def add(x: Int, y: Int): Int = x + y
- }
- ```
- Then the block
+```
+object M {
+ def z = 0, one = 1
+ def add(x: Int, y: Int): Int = x + y
+}
+```
- ```
- { import M.{one, z => zero, _}; add(zero, one) }
- ```
+Then the block
- is equivalent to the block
+```
+{ import M.{one, z => zero, _}; add(zero, one) }
+```
- ```
- { M.add(M.z, M.one) }
- ```
+is equivalent to the block
+```
+{ M.add(M.z, M.one) }
+```
diff --git a/07-classes-and-objects.md b/07-classes-and-objects.md
index 292f6eaa53..392da29d0f 100644
--- a/07-classes-and-objects.md
+++ b/07-classes-and-objects.md
@@ -87,19 +87,20 @@ A second form of self type annotation reads just
`this: $S$ =>`. It prescribes the type $S$ for `this`
without introducing an alias name for it.
-(@) Consider the following class definitions:
+###### Example
+Consider the following class definitions:
- ```
- class Base extends Object {}
- trait Mixin extends Base {}
- object O extends Mixin {}
- ```
+```
+class Base extends Object {}
+trait Mixin extends Base {}
+object O extends Mixin {}
+```
- In this case, the definition of `O` is expanded to:
+In this case, the definition of `O` is expanded to:
- ```
- object O extends Base with Mixin {}
- ```
+```
+object O extends Base with Mixin {}
+```
<!-- TODO: Make all references to Java generic -->
@@ -203,42 +204,43 @@ linearization of this graph is defined as follows.
> ```
-(@) Consider the following class definitions.
+###### Example
+Consider the following class definitions.
- ```
- abstract class AbsIterator extends AnyRef { ... }
- trait RichIterator extends AbsIterator { ... }
- class StringIterator extends AbsIterator { ... }
- class Iter extends StringIterator with RichIterator { ... }
- ```
+```
+abstract class AbsIterator extends AnyRef { ... }
+trait RichIterator extends AbsIterator { ... }
+class StringIterator extends AbsIterator { ... }
+class Iter extends StringIterator with RichIterator { ... }
+```
- Then the linearization of class `Iter` is
+Then the linearization of class `Iter` is
- ```
- { Iter, RichIterator, StringIterator, AbsIterator, AnyRef, Any }
- ```
+```
+{ Iter, RichIterator, StringIterator, AbsIterator, AnyRef, Any }
+```
- Note that the linearization of a class refines the inheritance
- relation: if $C$ is a subclass of $D$, then $C$ precedes $D$ in any
- linearization where both $C$ and $D$ occur.
- \ref{def:lin} also satisfies the property that a linearization
- of a class always contains the linearization of its direct superclass
- as a suffix. For instance, the linearization of
- `StringIterator` is
+Note that the linearization of a class refines the inheritance
+relation: if $C$ is a subclass of $D$, then $C$ precedes $D$ in any
+linearization where both $C$ and $D$ occur.
+\ref{def:lin} also satisfies the property that a linearization
+of a class always contains the linearization of its direct superclass
+as a suffix. For instance, the linearization of
+`StringIterator` is
- ```
- { StringIterator, AbsIterator, AnyRef, Any }
- ```
+```
+{ StringIterator, AbsIterator, AnyRef, Any }
+```
- which is a suffix of the linearization of its subclass `Iter`.
- The same is not true for the linearization of mixins.
- For instance, the linearization of `RichIterator` is
+which is a suffix of the linearization of its subclass `Iter`.
+The same is not true for the linearization of mixins.
+For instance, the linearization of `RichIterator` is
- ```
- { RichIterator, AbsIterator, AnyRef, Any }
- ```
+```
+{ RichIterator, AbsIterator, AnyRef, Any }
+```
- which is not a suffix of the linearization of `Iter`.
+which is not a suffix of the linearization of `Iter`.
### Class Members
@@ -306,18 +308,19 @@ Finally, a template is not allowed to contain two methods (directly
defined or inherited) with the same name which both define default arguments.
-(@) Consider the trait definitions:
+###### Example
+Consider the trait definitions:
- ```
- trait A { def f: Int }
- trait B extends A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 }
- trait C extends A { override def f: Int = 4 ; def g: Int }
- trait D extends B with C { def h: Int }
- ```
+```
+trait A { def f: Int }
+trait B extends A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 }
+trait C extends A { override def f: Int = 4 ; def g: Int }
+trait D extends B with C { def h: Int }
+```
- Then trait `D` has a directly defined abstract member `h`. It
- inherits member `f` from trait `C` and member `g` from
- trait `B`.
+Then trait `D` has a directly defined abstract member `h`. It
+inherits member `f` from trait `C` and member `g` from
+trait `B`.
### Overriding
@@ -366,25 +369,27 @@ it is possible to add new defaults (if the corresponding parameter in the
superclass does not have a default) or to override the defaults of the
superclass (otherwise).
-(@compounda) Consider the definitions:
+###### Example: compound types
- ```
- trait Root { type T <: Root }
- trait A extends Root { type T <: A }
- trait B extends Root { type T <: B }
- trait C extends A with B
- ```
+Consider the definitions:
- Then the class definition `C` is not well-formed because the
- binding of `T` in `C` is
- `type T <: B`,
- which fails to subsume the binding `type T <: A` of `T`
- in type `A`. The problem can be solved by adding an overriding
- definition of type `T` in class `C`:
+```
+trait Root { type T <: Root }
+trait A extends Root { type T <: A }
+trait B extends Root { type T <: B }
+trait C extends A with B
+```
- ```
- class C extends A with B { type T <: C }
- ```
+Then the class definition `C` is not well-formed because the
+binding of `T` in `C` is
+`type T <: B`,
+which fails to subsume the binding `type T <: A` of `T`
+in type `A`. The problem can be solved by adding an overriding
+definition of type `T` in class `C`:
+
+```
+class C extends A with B { type T <: C }
+```
### Inheritance Closure
@@ -444,31 +449,32 @@ definitions.
Early definitions are evaluated in the order they are being defined
before the superclass constructor of the template is called.
-(@) Early definitions are particularly useful for
- traits, which do not have normal constructor parameters. Example:
+###### Example
+Early definitions are particularly useful for
+traits, which do not have normal constructor parameters. Example:
- ```
- trait Greeting {
- val name: String
- val msg = "How are you, "+name
- }
- class C extends {
- val name = "Bob"
- } with Greeting {
- println(msg)
- }
- ```
+```
+trait Greeting {
+ val name: String
+ val msg = "How are you, "+name
+}
+class C extends {
+ val name = "Bob"
+} with Greeting {
+ println(msg)
+}
+```
+
+In the code above, the field `name` is initialized before the
+constructor of `Greeting` is called. Therefore, field `msg` in
+class `Greeting` is properly initialized to `"How are you, Bob"`.
+
+If `name` had been initialized instead in `C`'s normal class
+body, it would be initialized after the constructor of
+`Greeting`. In that case, `msg` would be initialized to
+`"How are you, <null>"`.
- In the code above, the field `name` is initialized before the
- constructor of `Greeting` is called. Therefore, field `msg` in
- class `Greeting` is properly initialized to `"How are you, Bob"`.
- If `name` had been initialized instead in `C`'s normal class
- body, it would be initialized after the constructor of
- `Greeting`. In that case, `msg` would be initialized to
- `"How are you, <null>"`.
-
-
## Modifiers
```
@@ -609,53 +615,55 @@ the validity and meaning of a modifier are as follows.
and a later access will retry to evaluate its right hand side.
-(@) The following code illustrates the use of qualified private:
+###### Example
+The following code illustrates the use of qualified private:
- ```
- package outerpkg.innerpkg
- class Outer {
- class Inner {
- private[Outer] def f()
- private[innerpkg] def g()
- private[outerpkg] def h()
- }
- }
- ```
+```
+package outerpkg.innerpkg
+class Outer {
+ class Inner {
+ private[Outer] def f()
+ private[innerpkg] def g()
+ private[outerpkg] def h()
+ }
+}
+```
- Here, accesses to the method `f` can appear anywhere within
- `OuterClass`, but not outside it. Accesses to method
- `g` can appear anywhere within the package
- `outerpkg.innerpkg`, as would be the case for
- package-private methods in Java. Finally, accesses to method
- `h` can appear anywhere within package `outerpkg`,
- including packages contained in it.
+Here, accesses to the method `f` can appear anywhere within
+`OuterClass`, but not outside it. Accesses to method
+`g` can appear anywhere within the package
+`outerpkg.innerpkg`, as would be the case for
+package-private methods in Java. Finally, accesses to method
+`h` can appear anywhere within package `outerpkg`,
+including packages contained in it.
-(@) A useful idiom to prevent clients of a class from
- constructing new instances of that class is to declare the class
- `abstract` and `sealed`:
+###### Example
+A useful idiom to prevent clients of a class from
+constructing new instances of that class is to declare the class
+`abstract` and `sealed`:
- ```
- object m {
- abstract sealed class C (x: Int) {
- def nextC = new C(x + 1) {}
- }
- val empty = new C(0) {}
- }
- ```
+```
+object m {
+ abstract sealed class C (x: Int) {
+ def nextC = new C(x + 1) {}
+ }
+ val empty = new C(0) {}
+}
+```
- For instance, in the code above clients can create instances of class
- `m.C` only by calling the `nextC` method of an existing `m.C`
- object; it is not possible for clients to create objects of class
- `m.C` directly. Indeed the following two lines are both in error:
+For instance, in the code above clients can create instances of class
+`m.C` only by calling the `nextC` method of an existing `m.C`
+object; it is not possible for clients to create objects of class
+`m.C` directly. Indeed the following two lines are both in error:
- ```
- new m.C(0) // **** error: C is abstract, so it cannot be instantiated.
- new m.C(0) {} // **** error: illegal inheritance from sealed class.
- ```
+```
+new m.C(0) // **** error: C is abstract, so it cannot be instantiated.
+new m.C(0) {} // **** error: illegal inheritance from sealed class.
+```
- A similar access restriction can be achieved by marking the primary
- constructor `private` (see \ref{ex:private-constr}).
+A similar access restriction can be achieved by marking the primary
+constructor `private` (see \ref{ex:private-constr}).
## Class Definitions
@@ -741,28 +749,27 @@ which when applied to parameters conforming to types $\mathit{ps}$
initializes instances of type `$c$[$\mathit{tps}\,$]` by evaluating the template
$t$.
-(@) The following example illustrates `val` and `var`
- parameters of a class `C`:
+###### Example
+The following example illustrates `val` and `var` parameters of a class `C`:
- ```
- class C(x: Int, val y: String, var z: List[String])
- val c = new C(1, "abc", List())
- c.z = c.y :: c.z
- ```
+```
+class C(x: Int, val y: String, var z: List[String])
+val c = new C(1, "abc", List())
+c.z = c.y :: c.z
+```
-(@privateconstr) The following class can be created only from its companion
- module.
+The following class can be created only from its companion module.
- ```
- object Sensitive {
- def makeSensitive(credentials: Certificate): Sensitive =
- if (credentials == Admin) new Sensitive()
- else throw new SecurityViolationException
- }
- class Sensitive private () {
- ...
- }
- ```
+```
+object Sensitive {
+ def makeSensitive(credentials: Certificate): Sensitive =
+ if (credentials == Admin) new Sensitive()
+ else throw new SecurityViolationException
+}
+class Sensitive private () {
+ ...
+}
+```
### Constructor Definitions
@@ -817,21 +824,22 @@ invocation must refer to a constructor definition which precedes it
primary constructor of the class).
-(@) Consider the class definition
+###### Example
+Consider the class definition
- ```
- class LinkedList[A]() {
- var head = _
- var tail = null
- def isEmpty = tail != null
- def this(head: A) = { this(); this.head = head }
- def this(head: A, tail: List[A]) = { this(head); this.tail = tail }
- }
- ```
+```
+class LinkedList[A]() {
+ var head = _
+ var tail = null
+ def isEmpty = tail != null
+ def this(head: A) = { this(); this.head = head }
+ def this(head: A, tail: List[A]) = { this(head); this.tail = tail }
+}
+```
- This defines a class `LinkedList` with three constructors. The
- second constructor constructs an singleton list, while the
- third one constructs a list with a given head and tail.
+This defines a class `LinkedList` with three constructors. The
+second constructor constructs an singleton list, while the
+third one constructs a list with a given head and tail.
## Case Classes
@@ -924,46 +932,47 @@ class different from `AnyRef`. In particular:
contains the name of the class and its elements.
-(@) Here is the definition of abstract syntax for lambda calculus:
+###### Example
+Here is the definition of abstract syntax for lambda calculus:
- ```
- class Expr
- case class Var (x: String) extends Expr
- case class Apply (f: Expr, e: Expr) extends Expr
- case class Lambda(x: String, e: Expr) extends Expr
- ```
+```
+class Expr
+case class Var (x: String) extends Expr
+case class Apply (f: Expr, e: Expr) extends Expr
+case class Lambda(x: String, e: Expr) extends Expr
+```
- This defines a class `Expr` with case classes
- `Var`, `Apply` and `Lambda`. A call-by-value evaluator
- for lambda expressions could then be written as follows.
+This defines a class `Expr` with case classes
+`Var`, `Apply` and `Lambda`. A call-by-value evaluator
+for lambda expressions could then be written as follows.
- ```
- type Env = String => Value
- case class Value(e: Expr, env: Env)
-
- def eval(e: Expr, env: Env): Value = e match {
- case Var (x) =>
- env(x)
- case Apply(f, g) =>
- val Value(Lambda (x, e1), env1) = eval(f, env)
- val v = eval(g, env)
- eval (e1, (y => if (y == x) v else env1(y)))
- case Lambda(_, _) =>
- Value(e, env)
- }
- ```
+```
+type Env = String => Value
+case class Value(e: Expr, env: Env)
+
+def eval(e: Expr, env: Env): Value = e match {
+ case Var (x) =>
+ env(x)
+ case Apply(f, g) =>
+ val Value(Lambda (x, e1), env1) = eval(f, env)
+ val v = eval(g, env)
+ eval (e1, (y => if (y == x) v else env1(y)))
+ case Lambda(_, _) =>
+ Value(e, env)
+}
+```
- It is possible to define further case classes that extend type
- `Expr` in other parts of the program, for instance
+It is possible to define further case classes that extend type
+`Expr` in other parts of the program, for instance
- ```
- case class Number(x: Int) extends Expr
- ```
+```
+case class Number(x: Int) extends Expr
+```
- This form of extensibility can be excluded by declaring the base class
- `Expr` `sealed`; in this case, all classes that
- directly extend `Expr` must be in the same source file as
- `Expr`.
+This form of extensibility can be excluded by declaring the base class
+`Expr` `sealed`; in this case, all classes that
+directly extend `Expr` must be in the same source file as
+`Expr`.
### Traits
@@ -992,83 +1001,85 @@ statically known at the time the trait is defined.
If $D$ is not a trait, then its actual supertype is simply its
least proper supertype (which is statically known).
-(@comparable) The following trait defines the property
- of being comparable to objects of some type. It contains an abstract
- method `<` and default implementations of the other
- comparison operators `<=`, `>`, and
- `>=`.
+###### Example: `Comparable`
+The following trait defines the property
+of being comparable to objects of some type. It contains an abstract
+method `<` and default implementations of the other
+comparison operators `<=`, `>`, and
+`>=`.
- ```
- trait Comparable[T <: Comparable[T]] { self: T =>
- def < (that: T): Boolean
- def <=(that: T): Boolean = this < that || this == that
- def > (that: T): Boolean = that < this
- def >=(that: T): Boolean = that <= this
- }
- ```
+```
+trait Comparable[T <: Comparable[T]] { self: T =>
+ def < (that: T): Boolean
+ def <=(that: T): Boolean = this < that || this == that
+ def > (that: T): Boolean = that < this
+ def >=(that: T): Boolean = that <= this
+}
+```
-(@) Consider an abstract class `Table` that implements maps
- from a type of keys `A` to a type of values `B`. The class
- has a method `set` to enter a new key / value pair into the table,
- and a method `get` that returns an optional value matching a
- given key. Finally, there is a method `apply` which is like
- `get`, except that it returns a given default value if the table
- is undefined for the given key. This class is implemented as follows.
+###### Example
+Consider an abstract class `Table` that implements maps
+from a type of keys `A` to a type of values `B`. The class
+has a method `set` to enter a new key / value pair into the table,
+and a method `get` that returns an optional value matching a
+given key. Finally, there is a method `apply` which is like
+`get`, except that it returns a given default value if the table
+is undefined for the given key. This class is implemented as follows.
- ```
- abstract class Table[A, B](defaultValue: B) {
- def get(key: A): Option[B]
- def set(key: A, value: B)
- def apply(key: A) = get(key) match {
- case Some(value) => value
- case None => defaultValue
- }
- }
- ```
+```
+abstract class Table[A, B](defaultValue: B) {
+ def get(key: A): Option[B]
+ def set(key: A, value: B)
+ def apply(key: A) = get(key) match {
+ case Some(value) => value
+ case None => defaultValue
+ }
+}
+```
- Here is a concrete implementation of the `Table` class.
+Here is a concrete implementation of the `Table` class.
- ```
- class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) {
- private var elems: List[(A, B)]
- def get(key: A) = elems.find(._1.==(key)).map(._2)
- def set(key: A, value: B) = { elems = (key, value) :: elems }
- }
- ```
+```
+class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) {
+ private var elems: List[(A, B)]
+ def get(key: A) = elems.find(._1.==(key)).map(._2)
+ def set(key: A, value: B) = { elems = (key, value) :: elems }
+}
+```
- Here is a trait that prevents concurrent access to the
- `get` and `set` operations of its parent class:
+Here is a trait that prevents concurrent access to the
+`get` and `set` operations of its parent class:
- ```
- trait SynchronizedTable[A, B] extends Table[A, B] {
- abstract override def get(key: A): B =
- synchronized { super.get(key) }
- abstract override def set((key: A, value: B) =
- synchronized { super.set(key, value) }
- }
- ```
+```
+trait SynchronizedTable[A, B] extends Table[A, B] {
+ abstract override def get(key: A): B =
+ synchronized { super.get(key) }
+ abstract override def set((key: A, value: B) =
+ synchronized { super.set(key, value) }
+}
+```
- Note that `SynchronizedTable` does not pass an argument to
- its superclass, `Table`, even though `Table` is defined with a
- formal parameter. Note also that the `super` calls
- in `SynchronizedTable`'s `get` and `set` methods
- statically refer to abstract methods in class `Table`. This is
- legal, as long as the calling method is labeled
- [`abstract override`](#modifiers).
+Note that `SynchronizedTable` does not pass an argument to
+its superclass, `Table`, even though `Table` is defined with a
+formal parameter. Note also that the `super` calls
+in `SynchronizedTable`'s `get` and `set` methods
+statically refer to abstract methods in class `Table`. This is
+legal, as long as the calling method is labeled
+[`abstract override`](#modifiers).
- Finally, the following mixin composition creates a synchronized list
- table with strings as keys and integers as values and with a default
- value `0`:
+Finally, the following mixin composition creates a synchronized list
+table with strings as keys and integers as values and with a default
+value `0`:
- ```
- object MyTable extends ListTable[String, Int](0) with SynchronizedTable
- ```
+```
+object MyTable extends ListTable[String, Int](0) with SynchronizedTable
+```
- The object `MyTable` inherits its `get` and `set`
- method from `SynchronizedTable`. The `super` calls in these
- methods are re-bound to refer to the corresponding implementations in
- `ListTable`, which is the actual supertype of `SynchronizedTable`
- in `MyTable`.
+The object `MyTable` inherits its `get` and `set`
+method from `SynchronizedTable`. The `super` calls in these
+methods are re-bound to refer to the corresponding implementations in
+`ListTable`, which is the actual supertype of `SynchronizedTable`
+in `MyTable`.
## Object Definitions
@@ -1117,31 +1128,32 @@ cannot be because variable and method definition cannot appear on the
top-level outside of a [package object](#package-objects). Instead,
top-level objects are translated to static fields.
-(@) Classes in Scala do not have static members; however, an equivalent
- effect can be achieved by an accompanying object definition
- E.g.
+###### Example
+Classes in Scala do not have static members; however, an equivalent
+effect can be achieved by an accompanying object definition
+E.g.
- ```
- abstract class Point {
- val x: Double
- val y: Double
- def isOrigin = (x == 0.0 && y == 0.0)
- }
- object Point {
- val origin = new Point() { val x = 0.0; val y = 0.0 }
- }
- ```
+```
+abstract class Point {
+ val x: Double
+ val y: Double
+ def isOrigin = (x == 0.0 && y == 0.0)
+}
+object Point {
+ val origin = new Point() { val x = 0.0; val y = 0.0 }
+}
+```
- This defines a class `Point` and an object `Point` which
- contains `origin` as a member. Note that the double use of the
- name `Point` is legal, since the class definition defines the
- name `Point` in the type name space, whereas the object
- definition defines a name in the term namespace.
+This defines a class `Point` and an object `Point` which
+contains `origin` as a member. Note that the double use of the
+name `Point` is legal, since the class definition defines the
+name `Point` in the type name space, whereas the object
+definition defines a name in the term namespace.
- This technique is applied by the Scala compiler when interpreting a
- Java class with static members. Such a class $C$ is conceptually seen
- as a pair of a Scala class that contains all instance members of $C$
- and a Scala object that contains all static members of $C$.
+This technique is applied by the Scala compiler when interpreting a
+Java class with static members. Such a class $C$ is conceptually seen
+as a pair of a Scala class that contains all instance members of $C$
+and a Scala object that contains all static members of $C$.
Generally, a _companion module_ of a class is an object which has
the same name as the class and is defined in the same scope and
diff --git a/08-expressions.md b/08-expressions.md
index 1fe82e9b95..4adf23c63e 100644
--- a/08-expressions.md
+++ b/08-expressions.md
@@ -209,32 +209,33 @@ 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.
-(@super) Consider the following class definitions
+###### Example: `super`
+Consider the following class definitions
- ```
- 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 }
- class C extends Root with B {
- override def x = "C" ; def superC = super.x
- }
- class D extends A with B {
- override def x = "D" ; def superD = super.x
- }
- ```
+```
+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 }
+class C extends Root with B {
+ override def x = "C" ; def superC = super.x
+}
+class D extends A with B {
+ override def x = "D" ; def superD = super.x
+}
+```
- The linearization of class `C` is `{C, B, Root}` and
- the linearization of class `D` is `{D, B, A, Root}`.
- Then we have:
+The linearization of class `C` is `{C, B, Root}` and
+the linearization of class `D` is `{D, B, A, Root}`.
+Then we have:
- ```
- (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
- depending on whether `B` is mixed in with class `Root` or `A`.
+Note that the `superB` function returns different results
+depending on whether `B` is mixed in with class `Root` or `A`.
## Function Applications
@@ -320,27 +321,28 @@ run-time stack. However, if a local function or a final method calls
itself as its last action, the call is executed using the stack-frame
of the caller.
-(@) Assume the following function which computes the sum of a
- variable number of arguments:
+###### Example
+Assume the following function which computes the sum of a
+variable number of arguments:
- ```
- def sum(xs: Int*) = (0 /: xs) ((x, y) => x + y)
- ```
+```
+def sum(xs: Int*) = (0 /: xs) ((x, y) => x + y)
+```
- Then
+Then
- ```
- sum(1, 2, 3, 4)
- sum(List(1, 2, 3, 4): _*)
- ```
+```
+sum(1, 2, 3, 4)
+sum(List(1, 2, 3, 4): _*)
+```
- both yield `10` as result. On the other hand,
+both yield `10` as result. On the other hand,
- ```
- sum(List(1, 2, 3, 4))
- ```
+```
+sum(List(1, 2, 3, 4))
+```
- would not typecheck.
+would not typecheck.
### Named and Default Arguments
@@ -432,18 +434,19 @@ parameterless method or call-by-name parameter of type
`() => $T$`, which evaluates $e$ when it is applied to the empty
parameterlist `()`.
-(@) The method values in the left column are each equivalent to the
- [anonymous functions](#anonymous-functions) on their right.
+###### Example
+The method values in the left column are each equivalent to the
+[anonymous functions](#anonymous-functions) on their right.
- ------------------------------ -----------------------------------------------------
- `Math.sin _` `x => Math.sin(x)`
- `Array.range _` `(x1, x2) => Array.range(x1, x2)`
- `List.map2 _` `(x1, x2) => (x3) => List.map2(x1, x2)(x3)`
- `List.map2(xs, ys)_` `x => List.map2(xs, ys)(x)`
- ------------------------------ -----------------------------------------------------
+|------------------------------ | --------------------------------------------|
+|`Math.sin _` | `x => Math.sin(x)` |
+|`Array.range _` | `(x1, x2) => Array.range(x1, x2)` |
+|`List.map2 _` | `(x1, x2) => (x3) => List.map2(x1, x2)(x3)` |
+|`List.map2(xs, ys)_` | `x => List.map2(xs, ys)(x)` |
+|------------------------------ | --------------------------------------------|
- Note that a space is necessary between a method name and the trailing underscore
- because otherwise the underscore would be considered part of the name.
+Note that a space is necessary between a method name and the trailing underscore
+because otherwise the underscore would be considered part of the name.
## Type Applications
@@ -531,25 +534,26 @@ types: If `{$D$}` is a class body, then
`new {$D$}` is equivalent to the general instance creation expression
`new AnyRef{$D$}`.
-(@) Consider the following structural instance creation expression:
+###### Example
+Consider the following structural instance creation expression:
- ```
- new { def getName() = "aaron" }
- ```
+```
+new { def getName() = "aaron" }
+```
- This is a shorthand for the general instance creation expression
+This is a shorthand for the general instance creation expression
- ```
- new AnyRef{ def getName() = "aaron" }
- ```
+```
+new AnyRef{ def getName() = "aaron" }
+```
- The latter is in turn a shorthand for the block
+The latter is in turn a shorthand for the block
- ```
- { class anon\$X extends AnyRef{ def getName() = "aaron" }; new anon\$X }
- ```
+```
+{ class anon\$X extends AnyRef{ def getName() = "aaron" }; new anon\$X }
+```
- where `anon\$X` is some freshly created name.
+where `anon\$X` is some freshly created name.
## Blocks
@@ -597,22 +601,23 @@ Evaluation of the block entails evaluation of its
statement sequence, followed by an evaluation of the final expression
$e$, which defines the result of the block.
-(@) Assuming a class `Ref[T](x: T)`, the block
+###### Example
+Assuming a class `Ref[T](x: T)`, the block
- ```
- { class C extends B {$\ldots$} ; new Ref(new C) }
- ```
+```
+{ class C extends B {$\ldots$} ; new Ref(new C) }
+```
- has the type `Ref[_1] forSome { type _1 <: B }`.
- The block
+has the type `Ref[_1] forSome { type _1 <: B }`.
+The block
- ```
- { class C extends B {$\ldots$} ; new C }
- ```
+```
+{ class C extends B {$\ldots$} ; new C }
+```
- simply has type `B`, because with the rules [here](#simplification-rules)
- the existentially quantified type
- `_1 forSome { type _1 <: B }` can be simplified to `B`.
+simply has type `B`, because with the rules [here](#simplification-rules)
+the existentially quantified type
+`_1 forSome { type _1 <: B }` can be simplified to `B`.
## Prefix, Infix, and Postfix Operations
@@ -760,13 +765,14 @@ 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$.
-(@) Here are examples of well-typed and illegally typed expressions.
+###### Example
+Here are examples of well-typed and ill-typed expressions.
- ```
- 1: Int // legal, of type Int
- 1: Long // legal, of type Long
- // 1: string // ***** illegal
- ```
+```
+1: Int // legal, of type Int
+1: Long // legal, of type Long
+// 1: string // ***** illegal
+```
## Annotated Expressions
@@ -804,63 +810,66 @@ left of the ‘`=`’ operator is interpreted as
`$f.$update($\mathit{args}$, $e\,$)`, i.e.\
the invocation of an `update` function defined by $f$.
-(@) Here are some assignment expressions and their equivalent expansions.
+###### Example
+Here are some assignment expressions and their equivalent expansions.
- -------------------------- ---------------------
- `x.f = e` x.f_=(e)
- `x.f() = e` x.f.update(e)
- `x.f(i) = e` x.f.update(i, e)
- `x.f(i, j) = e` x.f.update(i, j, e)
- -------------------------- ---------------------
+-------------------------- ---------------------
+`x.f = e` x.f_=(e)
+`x.f() = e` x.f.update(e)
+`x.f(i) = e` x.f.update(i, e)
+`x.f(i, j) = e` x.f.update(i, j, e)
+-------------------------- ---------------------
-(@imp-mat-mul) Here is the usual imperative code for matrix multiplication.
+###### Example: imperative matrix multiplication
- ```
- 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
- while (i < xss.length) {
- var j = 0
- while (j < yss(0).length) {
- var acc = 0.0
- var k = 0
- while (k < yss.length) {
- acc = acc + xss(i)(k) * yss(k)(j)
- k += 1
- }
- zss(i)(j) = acc
- j += 1
- }
- i += 1
+Here is the usual imperative code for matrix multiplication.
+
+```
+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
+ while (i < xss.length) {
+ var j = 0
+ while (j < yss(0).length) {
+ var acc = 0.0
+ var k = 0
+ while (k < yss.length) {
+ acc = acc + xss(i)(k) * yss(k)(j)
+ k += 1
}
- zss
+ zss(i)(j) = acc
+ j += 1
}
- ```
+ i += 1
+ }
+ zss
+}
+```
- Desugaring the array accesses and assignments yields the following
- expanded version:
+Desugaring the array accesses and assignments yields the following
+expanded version:
- ```
- 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
- while (i < xss.length) {
- var j = 0
- while (j < yss.apply(0).length) {
- var acc = 0.0
- var k = 0
- while (k < yss.length) {
- acc = acc + xss.apply(i).apply(k) * yss.apply(k).apply(j)
- k += 1
- }
- zss.apply(i).update(j, acc)
- j += 1
- }
- i += 1
+```
+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
+ while (i < xss.length) {
+ var j = 0
+ while (j < yss.apply(0).length) {
+ var acc = 0.0
+ var k = 0
+ while (k < yss.length) {
+ acc = acc + xss.apply(i).apply(k) * yss.apply(k).apply(j)
+ k += 1
}
- zss
+ zss.apply(i).update(j, acc)
+ j += 1
}
- ```
+ i += 1
+ }
+ zss
+}
+```
## Conditional Expressions
@@ -1007,64 +1016,66 @@ comprehensions have been eliminated.
```
-(@) The following code produces all pairs of numbers between $1$ and $n-1$
- whose sums are prime.
+###### Example
+The following code produces all pairs of numbers between $1$ and $n-1$
+whose sums are prime.
- ```
- for { i <- 1 until n
- j <- 1 until i
- if isPrime(i+j)
- } yield (i, j)
- ```
+```
+for { i <- 1 until n
+ j <- 1 until i
+ if isPrime(i+j)
+} yield (i, j)
+```
- The for comprehension is translated to:
+The for comprehension is translated to:
- ```
- (1 until n)
- .flatMap {
- case i => (1 until i)
- .withFilter { j => isPrime(i+j) }
- .map { case j => (i, j) } }
- ```
+```
+(1 until n)
+ .flatMap {
+ case i => (1 until i)
+ .withFilter { j => isPrime(i+j) }
+ .map { case j => (i, j) } }
+```
-(@) For comprehensions can be used to express vector
- and matrix algorithms concisely.
- For instance, here is a function to compute the transpose of a given matrix:
+###### Example
+For comprehensions can be used to express vector
+and matrix algorithms concisely.
+For instance, here is a function to compute the transpose of a given matrix:
- <!-- see test/files/run/t0421.scala -->
+<!-- see test/files/run/t0421.scala -->
- ```
- def transpose[A](xss: Array[Array[A]]) = {
- for (i <- Array.range(0, xss(0).length)) yield
- for (xs <- xss) yield xs(i)
- }
- ```
+```
+def transpose[A](xss: Array[Array[A]]) = {
+ for (i <- Array.range(0, xss(0).length)) yield
+ for (xs <- xss) yield xs(i)
+}
+```
- Here is a function to compute the scalar product of two vectors:
+Here is a function to compute the scalar product of two vectors:
- ```
- def scalprod(xs: Array[Double], ys: Array[Double]) = {
- var acc = 0.0
- for ((x, y) <- xs zip ys) acc = acc + x * y
- acc
- }
- ```
+```
+def scalprod(xs: Array[Double], ys: Array[Double]) = {
+ var acc = 0.0
+ for ((x, y) <- xs zip ys) acc = acc + x * y
+ acc
+}
+```
- Finally, here is a function to compute the product of two matrices.
- Compare with the imperative version of \ref{ex:imp-mat-mul}.
+Finally, here is a function to compute the product of two matrices.
+Compare with the [imperative version](#example-imperative-matrix-multiplication).
- ```
- def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
- val ysst = transpose(yss)
- for (xs <- xss) yield
- for (yst <- ysst) yield
- scalprod(xs, yst)
- }
- ```
+```
+def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = {
+ val ysst = transpose(yss)
+ for (xs <- xss) yield
+ for (yst <- ysst) yield
+ scalprod(xs, yst)
+}
+```
- The code above makes use of the fact that `map`, `flatMap`,
- `withFilter`, and `foreach` are defined for instances of class
- `scala.Array`.
+The code above makes use of the fact that `map`, `flatMap`,
+`withFilter`, and `foreach` are defined for instances of class
+`scala.Array`.
## Return Expressions
@@ -1231,23 +1242,24 @@ parameter section itself does not count as an implicit parameter
section in the sense defined [here](#implicit-parameters). Hence, arguments to
anonymous functions always have to be given explicitly.
-(@) Examples of anonymous functions:
+###### Example
+Examples of anonymous functions:
- ```
- x => x // The identity function
+```
+x => x // The identity function
- f => g => x => f(g(x)) // Curried function composition
+f => g => x => f(g(x)) // Curried function composition
- (x: Int,y: Int) => x + y // A summation function
+(x: Int,y: Int) => x + y // A summation function
- () => { count += 1; count } // The function which takes an
- // empty parameter list $()$,
- // increments a non-local variable
- // `count' and returns the new value.
+() => { count += 1; count } // The function which takes an
+ // empty parameter list $()$,
+ // increments a non-local variable
+ // `count' and returns the new value.
- _ => 5 // The function that ignores its argument
- // and always returns 5.
- ```
+_ => 5 // The function that ignores its argument
+ // and always returns 5.
+```
### Placeholder Syntax for Anonymous Functions
@@ -1276,17 +1288,18 @@ the anonymous function `($u'_1$, ... $u'_n$) => $e'$`
where each $u_i'$ results from $u_i$ by replacing the underscore with a fresh identifier and
$e'$ results from $e$ by replacing each underscore section $u_i$ by $u_i'$.
-(@) The anonymous functions in the left column use placeholder
- syntax. Each of these is equivalent to the anonymous function on its right.
+###### Example
+The anonymous functions in the left column use placeholder
+syntax. Each of these is equivalent to the anonymous function on its right.
- --------------------------- ------------------------------------
- `_ + 1` `x => x + 1`
- `_ * _` `(x1, x2) => x1 * x2`
- `(_: Int) * 2` `(x: Int) => (x: Int) * 2`
- `if (_) x else y` `z => if (z) x else y`
- `_.map(f)` `x => x.map(f)`
- `_.map(_ + 1)` `x => x.map(y => y + 1)`
- --------------------------- ------------------------------------
+|---------------------------|----------------------------|
+|`_ + 1` | `x => x + 1` |
+|`_ * _` | `(x1, x2) => x1 * x2` |
+|`(_: Int) * 2` | `(x: Int) => (x: Int) * 2` |
+|`if (_) x else y` | `z => if (z) x else y` |
+|`_.map(f)` | `x => x.map(f)` |
+|`_.map(_ + 1)` | `x => x.map(y => y + 1)` |
+|---------------------------|----------------------------|
## Constant Expressions
@@ -1539,26 +1552,27 @@ 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}$.
-(@) Consider the following definitions:
+###### Example
+Consider the following definitions:
- ```
- class A extends B {}
- def f(x: B, y: B) = $\ldots$
- def f(x: A, y: B) = $\ldots$
- val a: A
- val b: B
- ```
+```
+class A extends B {}
+def f(x: B, y: B) = $\ldots$
+def f(x: A, y: B) = $\ldots$
+val a: A
+val b: B
+```
- 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
+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
- ```
- def f(x: B, y: A) = $\ldots$
- ```
+```
+def f(x: B, y: A) = $\ldots$
+```
- Then the application `f(a, a)` is rejected for being ambiguous, since
- no most specific applicable signature exists.
+Then the application `f(a, a)` is rejected for being ambiguous, since
+no most specific applicable signature exists.
### Local Type Inference
@@ -1653,95 +1667,98 @@ pre-order, it is also possible that a solution set has several optimal
solutions for a type. In that case, a Scala compiler is free to pick
any one of them.
-(@) Consider the two methods:
+###### Example
+Consider the two methods:
- ```
- def cons[A](x: A, xs: List[A]): List[A] = x :: xs
- def nil[B]: List[B] = Nil
- ```
+```
+def cons[A](x: A, xs: List[A]): List[A] = x :: xs
+def nil[B]: List[B] = Nil
+```
- and the definition
+and the definition
- ```
- val xs = cons(1, nil)
- ```
+```
+val xs = cons(1, nil)
+```
- The application of `cons` is typed with an undefined expected
- type. This application is completed by local type inference to
- `cons[Int](1, nil)`.
- Here, one uses the following
- reasoning to infer the type argument `Int` for the type
- parameter `a`:
+The application of `cons` is typed with an undefined expected
+type. This application is completed by local type inference to
+`cons[Int](1, nil)`.
+Here, one uses the following
+reasoning to infer the type argument `Int` for the type
+parameter `a`:
- First, the argument expressions are typed. The first argument `1`
- 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
+First, the argument expressions are typed. The first argument `1`
+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
- ```
- List[b?] <: List[a]
- ```
+```
+List[b?] <: List[a]
+```
- where we have labeled `b?` with a question mark to indicate
- that it is a variable in the constraint system.
- Because class `List` is covariant, the optimal
- solution of this constraint is
+where we have labeled `b?` with a question mark to indicate
+that it is a variable in the constraint system.
+Because class `List` is covariant, the optimal
+solution of this constraint is
- ```
- b = scala.Nothing
- ```
+```
+b = scala.Nothing
+```
- In a second step, one solves the following constraint system for
- the type parameter `a` of `cons`:
+In a second step, one solves the following constraint system for
+the type parameter `a` of `cons`:
- ```
- Int <: a?
- List[scala.Nothing] <: List[a?]
- List[a?] <: $\mbox{\sl undefined}$
- ```
+```
+Int <: a?
+List[scala.Nothing] <: List[a?]
+List[a?] <: $\mbox{\sl undefined}$
+```
- The optimal solution of this constraint system is
+The optimal solution of this constraint system is
- ```
- a = Int
- ```
+```
+a = Int
+```
- so `Int` is the type inferred for `a`.
+so `Int` is the type inferred for `a`.
-(@) Consider now the definition
+###### Example
- ```
- val ys = cons("abc", xs)
- ```
+Consider now the definition
- where `xs` is defined of type `List[Int]` as before.
- In this case local type inference proceeds as follows.
+```
+val ys = cons("abc", xs)
+```
- First, the argument expressions are typed. The first argument
- `"abc"` has type `String`. The second argument `xs` is
- first tried to be typed with expected type `List[a]`. This fails,
- as `List[Int]` is not a subtype of `List[a]`. Therefore,
- the second strategy is tried; `xs` is now typed with expected type
- `List[$\mbox{\sl undefined}$]`. This succeeds and yields the argument type
- `List[Int]`.
+where `xs` is defined of type `List[Int]` as before.
+In this case local type inference proceeds as follows.
- In a second step, one solves the following constraint system for
- the type parameter `a` of `cons`:
+First, the argument expressions are typed. The first argument
+`"abc"` has type `String`. The second argument `xs` is
+first tried to be typed with expected type `List[a]`. This fails,
+as `List[Int]` is not a subtype of `List[a]`. Therefore,
+the second strategy is tried; `xs` is now typed with expected type
+`List[$\mbox{\sl undefined}$]`. This succeeds and yields the argument type
+`List[Int]`.
- ```
- String <: a?
- List[Int] <: List[a?]
- List[a?] <: $\mbox{\sl undefined}$
- ```
+In a second step, one solves the following constraint system for
+the type parameter `a` of `cons`:
- The optimal solution of this constraint system is
+```
+String <: a?
+List[Int] <: List[a?]
+List[a?] <: $\mbox{\sl undefined}$
+```
- ```
- a = scala.Any
- ```
+The optimal solution of this constraint system is
+
+```
+a = scala.Any
+```
- so `scala.Any` is the type inferred for `a`.
+so `scala.Any` is the type inferred for `a`.
### Eta Expansion
diff --git a/09-implicit-parameters-and-views.md b/09-implicit-parameters-and-views.md
index 845d21e579..e4b8b5956c 100644
--- a/09-implicit-parameters-and-views.md
+++ b/09-implicit-parameters-and-views.md
@@ -13,26 +13,27 @@ and can be used as implicit conversions called [views](#views).
The `implicit` modifier is illegal for all
type members, as well as for [top-level objects](#packagings).
-(@impl-monoid) The following code defines an abstract class of monoids and
- two concrete implementations, `StringMonoid` and
- `IntMonoid`. The two implementations are marked implicit.
-
- ```
- abstract class Monoid[A] extends SemiGroup[A] {
- def unit: A
- def add(x: A, y: A): A
- }
- object Monoids {
- implicit object stringMonoid extends Monoid[String] {
- def add(x: String, y: String): String = x.concat(y)
- def unit: String = ""
- }
- implicit object intMonoid extends Monoid[Int] {
- def add(x: Int, y: Int): Int = x + y
- def unit: Int = 0
- }
- }
- ```
+###### Example: `Monoid`
+The following code defines an abstract class of monoids and
+two concrete implementations, `StringMonoid` and
+`IntMonoid`. The two implementations are marked implicit.
+
+```
+abstract class Monoid[A] extends SemiGroup[A] {
+ def unit: A
+ def add(x: A, y: A): A
+}
+object Monoids {
+ implicit object stringMonoid extends Monoid[String] {
+ def add(x: String, y: String): String = x.concat(y)
+ def unit: String = ""
+ }
+ implicit object intMonoid extends Monoid[Int] {
+ def add(x: Int, y: Int): Int = x + y
+ def unit: Int = 0
+ }
+}
+```
## Implicit Parameters
@@ -85,25 +86,26 @@ of static [overloading resolution](#overloading-resolution).
If the parameter has a default argument and no implicit argument can
be found the default argument is used.
-(@) Assuming the classes from \ref{ex:impl-monoid}, here is a
- method which computes the sum of a list of elements using the
- monoid's `add` and `unit` operations.
+###### Example
+Assuming the classes from the [`Monoid` example](#example-monoid), here is a
+method which computes the sum of a list of elements using the
+monoid's `add` and `unit` operations.
- ```
- def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
- if (xs.isEmpty) m.unit
- else m.add(xs.head, sum(xs.tail))
- ```
+```
+def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
+ if (xs.isEmpty) m.unit
+ else m.add(xs.head, sum(xs.tail))
+```
- The monoid in question is marked as an implicit parameter, and can therefore
- be inferred based on the type of the list.
- Consider for instance the call `sum(List(1, 2, 3))`
- in a context where `stringMonoid` and `intMonoid`
- are visible. We know that the formal type parameter `a` of
- `sum` needs to be instantiated to `Int`. The only
- eligible object which matches the implicit formal parameter type
- `Monoid[Int]` is `intMonoid` so this object will
- be passed as implicit parameter.
+The monoid in question is marked as an implicit parameter, and can therefore
+be inferred based on the type of the list.
+Consider for instance the call `sum(List(1, 2, 3))`
+in a context where `stringMonoid` and `intMonoid`
+are visible. We know that the formal type parameter `a` of
+`sum` needs to be instantiated to `Int`. The only
+eligible object which matches the implicit formal parameter type
+`Monoid[Int]` is `intMonoid` so this object will
+be passed as implicit parameter.
This discussion also shows that implicit parameters are inferred after
@@ -210,39 +212,41 @@ the type:
> `$\mathit{complexity}(T_1$ with $\ldots$ with $T_n)$` $= \Sigma\mathit{complexity}(T_i)$
-(@) When typing `sort(xs)` for some list `xs` of type `List[List[List[Int]]]`,
- the sequence of types for
- which implicit arguments are searched is
+###### Example
+When typing `sort(xs)` for some list `xs` of type `List[List[List[Int]]]`,
+the sequence of types for
+which implicit arguments are searched is
- ```
- List[List[Int]] => Ordered[List[List[Int]]],
- List[Int] => Ordered[List[Int]]
- Int => Ordered[Int]
- ```
+```
+List[List[Int]] => Ordered[List[List[Int]]],
+List[Int] => Ordered[List[Int]]
+Int => Ordered[Int]
+```
- All types share the common type constructor `scala.Function1`,
- but the complexity of the each new type is lower than the complexity of the previous types.
- Hence, the code typechecks.
+All types share the common type constructor `scala.Function1`,
+but the complexity of the each new type is lower than the complexity of the previous types.
+Hence, the code typechecks.
-(@) Let `ys` be a list of some type which cannot be converted
- to `Ordered`. For instance:
+###### Example
+Let `ys` be a list of some type which cannot be converted
+to `Ordered`. For instance:
- ```
- val ys = List(new IllegalArgumentException, new ClassCastException, new Error)
- ```
+```
+val ys = List(new IllegalArgumentException, new ClassCastException, new Error)
+```
- Assume that the definition of `magic` above is in scope. Then the sequence
- of types for which implicit arguments are searched is
+Assume that the definition of `magic` above is in scope. Then the sequence
+of types for which implicit arguments are searched is
- ```
- Throwable => Ordered[Throwable],
- Throwable => Ordered[Throwable],
- ...
- ```
+```
+Throwable => Ordered[Throwable],
+Throwable => Ordered[Throwable],
+...
+```
- Since the second type in the sequence is equal to the first, the compiler
- will issue an error signalling a divergent implicit expansion.
+Since the second type in the sequence is equal to the first, the compiler
+will issue an error signalling a divergent implicit expansion.
## Views
@@ -286,33 +290,34 @@ As for implicit parameters, overloading resolution is applied
if there are several possible candidates (of either the call-by-value
or the call-by-name category).
-(@impl-ordered) Class `scala.Ordered[A]` contains a method
+###### Example: `Ordered`
+Class `scala.Ordered[A]` contains a method
- ```
- def <= [B >: A](that: B)(implicit b2ordered: B => Ordered[B]): Boolean .
- ```
+```
+ def <= [B >: A](that: B)(implicit b2ordered: B => Ordered[B]): Boolean .
+```
- Assume two lists `xs` and `ys` of type `List[Int]`
- and assume that the `list2ordered` and `int2ordered`
- methods defined [here](#implicit-parameters) are in scope.
- Then the operation
+Assume two lists `xs` and `ys` of type `List[Int]`
+and assume that the `list2ordered` and `int2ordered`
+methods defined [here](#implicit-parameters) are in scope.
+Then the operation
- ```
- xs <= ys
- ```
+```
+ xs <= ys
+```
- is legal, and is expanded to:
+is legal, and is expanded to:
- ```
- list2ordered(xs)(int2ordered).<=
- (ys)
- (xs => list2ordered(xs)(int2ordered))
- ```
+```
+ list2ordered(xs)(int2ordered).<=
+ (ys)
+ (xs => list2ordered(xs)(int2ordered))
+```
- The first application of `list2ordered` converts the list
- `xs` to an instance of class `Ordered`, whereas the second
- occurrence is part of an implicit parameter passed to the `<=`
- method.
+The first application of `list2ordered` converts the list
+`xs` to an instance of class `Ordered`, whereas the second
+occurrence is part of an implicit parameter passed to the `<=`
+method.
## Context Bounds and View Bounds
@@ -360,12 +365,13 @@ Consequently, type-parameters in traits may not be view- or context-bounded.
Also, a method or class with view- or context bounds may not define any
additional implicit parameters.
-(@) The `<=` method mentioned in \ref{ex:impl-ordered} can be declared
- more concisely as follows:
+###### Example
+The `<=` method from the [`Ordered` example](#example-ordered) can be declared
+more concisely as follows:
- ```
- def <= [B >: A <% Ordered[B]](that: B): Boolean
- ```
+```
+def <= [B >: A <% Ordered[B]](that: B): Boolean
+```
## Manifests
diff --git a/10-pattern-matching.md b/10-pattern-matching.md
index 2d1c79e538..fd63d3fbc9 100644
--- a/10-pattern-matching.md
+++ b/10-pattern-matching.md
@@ -29,8 +29,8 @@ variables in the pattern to the corresponding components of the value
(or sequence of values). The same variable name may not be bound more
than once in a pattern.
-(@) Some examples of patterns are:
-
+###### Example
+Some examples of patterns are:
1. The pattern `ex: IOException` matches all instances of class
`IOException`, binding variable \verb@ex@ to the instance.
1. The pattern `Some(x)` matches values of the form `Some($v$)`,
@@ -43,9 +43,9 @@ than once in a pattern.
second element, and `xs` to the remainder.
1. The pattern `1 | 2 | 3` matches the integers between 1 and 3.
- Pattern matching is always done in a context which supplies an
- expected type of the pattern. We distinguish the following kinds of
- patterns.
+Pattern matching is always done in a context which supplies an
+expected type of the pattern. We distinguish the following kinds of
+patterns.
### Variable Patterns
@@ -113,32 +113,33 @@ stable identifier pattern may not be a simple name starting with a lower-case
letter. However, it is possible to enclose a such a variable name in
backquotes; then it is treated as a stable identifier pattern.
-(@) Consider the following function definition:
+###### Example
+Consider the following function definition:
- ```
- def f(x: Int, y: Int) = x match {
- case y => ...
- }
- ```
+```
+def f(x: Int, y: Int) = x match {
+ case y => ...
+}
+```
- Here, `y` is a variable pattern, which matches any value.
- If we wanted to turn the pattern into a stable identifier pattern, this
- can be achieved as follows:
+Here, `y` is a variable pattern, which matches any value.
+If we wanted to turn the pattern into a stable identifier pattern, this
+can be achieved as follows:
- ```
- def f(x: Int, y: Int) = x match {
- case `y` => ...
- }
- ```
+```
+def f(x: Int, y: Int) = x match {
+ case `y` => ...
+}
+```
- Now, the pattern matches the `y` parameter of the enclosing function `f`.
- That is, the match succeeds only if the `x` argument and the `y`
- argument of `f` are equal.
+Now, the pattern matches the `y` parameter of the enclosing function `f`.
+That is, the match succeeds only if the `x` argument and the `y`
+argument of `f` are equal.
### Constructor Patterns
```
- SimplePattern ::= StableId `(' [Patterns] `)
+SimplePattern ::= StableId `(' [Patterns] `)
```
A constructor pattern is of the form $c(p_1 , \ldots , p_n)$ where $n
@@ -211,31 +212,32 @@ result type is of the form `Option[$S$]`, where $S$ is a subtype of
`Seq[$T$]` for some element type $T$.
This case is further discussed [here](#pattern-seqs).
-(@) The `Predef` object contains a definition of an
- extractor object `Pair`:
+###### Example
+The `Predef` object contains a definition of an
+extractor object `Pair`:
- ```
- object Pair {
- def apply[A, B](x: A, y: B) = Tuple2(x, y)
- def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
- }
- ```
+```
+object Pair {
+ def apply[A, B](x: A, y: B) = Tuple2(x, y)
+ def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
+}
+```
- This means that the name `Pair` can be used in place of `Tuple2` for tuple
- formation as well as for deconstruction of tuples in patterns.
- Hence, the following is possible:
+This means that the name `Pair` can be used in place of `Tuple2` for tuple
+formation as well as for deconstruction of tuples in patterns.
+Hence, the following is possible:
- ```
- val x = (1, 2)
- val y = x match {
- case Pair(i, s) => Pair(s + i, i * i)
- }
- ```
+```
+val x = (1, 2)
+val y = x match {
+ case Pair(i, s) => Pair(s + i, i * i)
+}
+```
### Pattern Sequences
```
- SimplePattern ::= StableId `(' [Patterns `,'] [varid `@'] `_' `*' `)'
+SimplePattern ::= StableId `(' [Patterns `,'] [varid `@'] `_' `*' `)'
```
A pattern sequence $p_1 , \ldots , p_n$ appears in two
@@ -451,76 +453,79 @@ has type type parameters $a_1 , \ldots , a_n$. These type parameters
are inferred in the same way as for the typed pattern
`(_: $C[a_1 , \ldots , a_n]$)`.
-(@) Consider the program fragment:
-
- ```
- val x: Any
- x match {
- case y: List[a] => ...
- }
- ```
-
- Here, the type pattern `List[a]` is matched against the
- expected type `Any`. The pattern binds the type variable
- `a`. Since `List[a]` conforms to `Any`
- for every type argument, there are no constraints on `a`.
- Hence, `a` is introduced as an abstract type with no
- bounds. The scope of `a` is right-hand side of its case clause.
-
- On the other hand, if `x` is declared as
-
- ```
- val x: List[List[String]],
- ```
-
- this generates the constraint
- `List[a] <: List[List[String]]`, which simplifies to
- `a <: List[String]`, because `List` is covariant. Hence,
- `a` is introduced with upper bound
- `List[String]`.
-
-(@) Consider the program fragment:
-
- ```
- val x: Any
- x match {
- case y: List[String] => ...
- }
- ```
-
- Scala does not maintain information about type arguments at run-time,
- so there is no way to check that `x` is a list of strings.
- Instead, the Scala compiler will [erase](#type-erasure) the
- pattern to `List[_]`; that is, it will only test whether the
- top-level runtime-class of the value `x` conforms to
- `List`, and the pattern match will succeed if it does. This
- might lead to a class cast exception later on, in the case where the
- list `x` contains elements other than strings. The Scala
- compiler will flag this potential loss of type-safety with an
- ``unchecked'' warning message.
-
-
-(@) Consider the program fragment
-
- ```
- class Term[A]
- class Number(val n: Int) extends Term[Int]
- def f[B](t: Term[B]): B = t match {
- case y: Number => y.n
- }
- ```
-
- The expected type of the pattern `y: Number` is
- `Term[B]`. The type `Number` does not conform to
- `Term[B]`; hence Case 2 of the rules above
- applies. This means that `b` is treated as another type
- variable for which subtype constraints are inferred. In our case the
- applicable constraint is `Number <: Term[B]`, which
- entails `B = Int`. Hence, `B` is treated in
- the case clause as an abstract type with lower and upper bound
- `Int`. Therefore, the right hand side of the case clause,
- `y.n`, of type `Int`, is found to conform to the
- function's declared result type, `Number`.
+###### Example
+Consider the program fragment:
+
+```
+val x: Any
+x match {
+ case y: List[a] => ...
+}
+```
+
+Here, the type pattern `List[a]` is matched against the
+expected type `Any`. The pattern binds the type variable
+`a`. Since `List[a]` conforms to `Any`
+for every type argument, there are no constraints on `a`.
+Hence, `a` is introduced as an abstract type with no
+bounds. The scope of `a` is right-hand side of its case clause.
+
+On the other hand, if `x` is declared as
+
+```
+val x: List[List[String]],
+```
+
+this generates the constraint
+`List[a] <: List[List[String]]`, which simplifies to
+`a <: List[String]`, because `List` is covariant. Hence,
+`a` is introduced with upper bound
+`List[String]`.
+
+###### Example
+Consider the program fragment:
+
+```
+val x: Any
+x match {
+ case y: List[String] => ...
+}
+```
+
+Scala does not maintain information about type arguments at run-time,
+so there is no way to check that `x` is a list of strings.
+Instead, the Scala compiler will [erase](#type-erasure) the
+pattern to `List[_]`; that is, it will only test whether the
+top-level runtime-class of the value `x` conforms to
+`List`, and the pattern match will succeed if it does. This
+might lead to a class cast exception later on, in the case where the
+list `x` contains elements other than strings. The Scala
+compiler will flag this potential loss of type-safety with an
+``unchecked'' warning message.
+
+
+###### Example
+Consider the program fragment
+
+```
+class Term[A]
+class Number(val n: Int) extends Term[Int]
+def f[B](t: Term[B]): B = t match {
+ case y: Number => y.n
+}
+```
+
+The expected type of the pattern `y: Number` is
+`Term[B]`. The type `Number` does not conform to
+`Term[B]`; hence Case 2 of the rules above
+applies. This means that `b` is treated as another type
+variable for which subtype constraints are inferred. In our case the
+applicable constraint is `Number <: Term[B]`, which
+entails `B = Int`. Hence, `B` is treated in
+the case clause as an abstract type with lower and upper bound
+`Int`. Therefore, the right hand side of the case clause,
+`y.n`, of type `Int`, is found to conform to the
+function's declared result type, `Number`.
## Pattern Matching Expressions
@@ -601,43 +606,45 @@ the compilation of pattern matching can emit warnings which diagnose
that a given set of patterns is not exhaustive, i.e.\ that there is a
possibility of a `MatchError` being raised at run-time.
-(@eval) Consider the following definitions of arithmetic terms:
-
- ```
- abstract class Term[T]
- case class Lit(x: Int) extends Term[Int]
- case class Succ(t: Term[Int]) extends Term[Int]
- case class IsZero(t: Term[Int]) extends Term[Boolean]
- case class If[T](c: Term[Boolean],
- t1: Term[T],
- t2: Term[T]) extends Term[T]
- ```
-
- There are terms to represent numeric literals, incrementation, a zero
- test, and a conditional. Every term carries as a type parameter the
- type of the expression it representes (either `Int` or `Boolean`).
-
- A type-safe evaluator for such terms can be written as follows.
-
- ```
- def eval[T](t: Term[T]): T = t match {
- case Lit(n) => n
- case Succ(u) => eval(u) + 1
- case IsZero(u) => eval(u) == 0
- case If(c, u1, u2) => eval(if (eval(c)) u1 else u2)
- }
- ```
-
- Note that the evaluator makes crucial use of the fact that type
- parameters of enclosing methods can acquire new bounds through pattern
- matching.
-
- For instance, the type of the pattern in the second case,
- `Succ(u)`, is `Int`. It conforms to the selector type
- `T` only if we assume an upper and lower bound of `Int` for `T`.
- Under the assumption `Int <: T <: Int` we can also
- verify that the type right hand side of the second case, `Int`
- conforms to its expected type, `T`.
+###### Example: `eval`
+
+Consider the following definitions of arithmetic terms:
+
+```
+abstract class Term[T]
+case class Lit(x: Int) extends Term[Int]
+case class Succ(t: Term[Int]) extends Term[Int]
+case class IsZero(t: Term[Int]) extends Term[Boolean]
+case class If[T](c: Term[Boolean],
+ t1: Term[T],
+ t2: Term[T]) extends Term[T]
+```
+
+There are terms to represent numeric literals, incrementation, a zero
+test, and a conditional. Every term carries as a type parameter the
+type of the expression it representes (either `Int` or `Boolean`).
+
+A type-safe evaluator for such terms can be written as follows.
+
+```
+def eval[T](t: Term[T]): T = t match {
+ case Lit(n) => n
+ case Succ(u) => eval(u) + 1
+ case IsZero(u) => eval(u) == 0
+ case If(c, u1, u2) => eval(if (eval(c)) u1 else u2)
+}
+```
+
+Note that the evaluator makes crucial use of the fact that type
+parameters of enclosing methods can acquire new bounds through pattern
+matching.
+
+For instance, the type of the pattern in the second case,
+`Succ(u)`, is `Int`. It conforms to the selector type
+`T` only if we assume an upper and lower bound of `Int` for `T`.
+Under the assumption `Int <: T <: Int` we can also
+verify that the type right hand side of the second case, `Int`
+conforms to its expected type, `T`.
## Pattern Matching Anonymous Functions
@@ -701,23 +708,24 @@ types of all $b_i$. The final default case in the `isDefinedAt`
method is omitted if one of the patterns $p_1 , \ldots , p_n$ is
already a variable or wildcard pattern.
-(@) Here is a method which uses a fold-left operation
- `/:` to compute the scalar product of
- two vectors:
-
- ```
- def scalarProduct(xs: Array[Double], ys: Array[Double]) =
- (0.0 /: (xs zip ys)) {
- case (a, (b, c)) => a + b * c
- }
- ```
-
- The case clauses in this code are equivalent to the following
- anonymous function:
-
- ```
- (x, y) => (x, y) match {
- case (a, (b, c)) => a + b * c
- }
- ```
+###### Example
+Here is a method which uses a fold-left operation
+`/:` to compute the scalar product of
+two vectors:
+
+```
+def scalarProduct(xs: Array[Double], ys: Array[Double]) =
+ (0.0 /: (xs zip ys)) {
+ case (a, (b, c)) => a + b * c
+ }
+```
+
+The case clauses in this code are equivalent to the following
+anonymous function:
+
+```
+(x, y) => (x, y) match {
+ case (a, (b, c)) => a + b * c
+}
+```
diff --git a/11-top-level-definitions.md b/11-top-level-definitions.md
index e7d6a9c192..dc25e7e476 100644
--- a/11-top-level-definitions.md
+++ b/11-top-level-definitions.md
@@ -119,25 +119,26 @@ closest enclosing scope that defines a member named $p$.
The special predefined name `_root_` refers to the
outermost root package which contains all top-level packages.
-(@package-ids) Consider the following program:
+###### Example
+Consider the following program:
- ```
- package b {
- class B
- }
+```
+package b {
+ class B
+}
- package a.b {
- class A {
- val x = new _root_.b.B
- }
- }
- ```
+package a.b {
+ class A {
+ val x = new _root_.b.B
+ }
+}
+```
- Here, the reference `_root_.b.B` refers to class `B` in the
- toplevel package `b`. If the `_root_` prefix had been
- omitted, the name `b` would instead resolve to the package
- `a.b`, and, provided that package does not also
- contain a class `B`, a compiler-time error would result.
+Here, the reference `_root_.b.B` refers to class `B` in the
+toplevel package `b`. If the `_root_` prefix had been
+omitted, the name `b` would instead resolve to the package
+`a.b`, and, provided that package does not also
+contain a class `B`, a compiler-time error would result.
## Programs
@@ -154,37 +155,38 @@ object, or it can be inherited. The scala library defines a special class
An objects $m$ inheriting from this class is thus a program,
which executes the initializaton code of the object $m$.
-(@) The following example will create a hello world program by defining
- a method `main` in module `test.HelloWorld`.
+###### Example
+The following example will create a hello world program by defining
+a method `main` in module `test.HelloWorld`.
- ```
- package test
- object HelloWorld {
- def main(args: Array[String]) { println("Hello World") }
- }
- ```
+```
+package test
+object HelloWorld {
+ def main(args: Array[String]) { println("Hello World") }
+}
+```
- This program can be started by the command
+This program can be started by the command
- ```
- scala test.HelloWorld
- ```
+```
+scala test.HelloWorld
+```
- In a Java environment, the command
+In a Java environment, the command
- ```
- java test.HelloWorld
- ```
+```
+java test.HelloWorld
+```
- would work as well.
+would work as well.
- `HelloWorld` can also be defined without a `main` method
- by inheriting from `App` instead:
+`HelloWorld` can also be defined without a `main` method
+by inheriting from `App` instead:
- ```
- package test
- object HelloWorld extends App {
- println("Hello World")
- }
- ```
+```
+package test
+object HelloWorld extends App {
+ println("Hello World")
+}
+```
diff --git a/12-xml-expressions-and-patterns.md b/12-xml-expressions-and-patterns.md
index 974fbc6b78..b6998da116 100644
--- a/12-xml-expressions-and-patterns.md
+++ b/12-xml-expressions-and-patterns.md
@@ -1,6 +1,6 @@
# XML Expressions and Patterns
-__By Burak Emir__ \
+__By Burak Emir__
This chapter describes the syntactic structure of XML expressions and patterns.
It follows as closely as possible the XML 1.0 specification \cite{w3c:xml},
@@ -44,7 +44,7 @@ XmlContent ::= Element
| CDSect
| PI
| Comment
-```
+```
If an XML expression is a single element, its value is a runtime
representation of an XML node (an instance of a subclass of
@@ -95,7 +95,6 @@ Name ::= XNameStart {NameChar}
XNameStart ::= ‘_’ | BaseChar | Ideographic
$\mbox{\rm\em (as in W3C XML, but without }$ ‘:’
-
```
## XML patterns
diff --git a/14-the-scala-standard-library.md b/14-the-scala-standard-library.md
index 59927f4e98..3bfeb9013c 100644
--- a/14-the-scala-standard-library.md
+++ b/14-the-scala-standard-library.md
@@ -234,53 +234,55 @@ for type `Int` and for all subrange types.
The `toString` method displays its receiver as an integer or
floating point number.
-(@) As an example, here is the signature of the numeric value type `Int`:
+###### Example:
- ```
- package scala
- abstract sealed class Int extends AnyVal {
- def == (that: Double): Boolean // double equality
- def == (that: Float): Boolean // float equality
- def == (that: Long): Boolean // long equality
- def == (that: Int): Boolean // int equality
- def == (that: Short): Boolean // int equality
- def == (that: Byte): Boolean // int equality
- def == (that: Char): Boolean // int equality
- /* analogous for !=, <, >, <=, >= */
-
- def + (that: Double): Double // double addition
- def + (that: Float): Double // float addition
- def + (that: Long): Long // long addition
- def + (that: Int): Int // int addition
- def + (that: Short): Int // int addition
- def + (that: Byte): Int // int addition
- def + (that: Char): Int // int addition
- /* analogous for -, *, /, % */
-
- def & (that: Long): Long // long bitwise and
- def & (that: Int): Int // int bitwise and
- def & (that: Short): Int // int bitwise and
- def & (that: Byte): Int // int bitwise and
- def & (that: Char): Int // int bitwise and
- /* analogous for |, ^ */
-
- def << (cnt: Int): Int // int left shift
- def << (cnt: Long): Int // long left shift
- /* analogous for >>, >>> */
-
- def unary_+ : Int // int identity
- def unary_- : Int // int negation
- def unary_~ : Int // int bitwise negation
-
- def toByte: Byte // convert to Byte
- def toShort: Short // convert to Short
- def toChar: Char // convert to Char
- def toInt: Int // convert to Int
- def toLong: Long // convert to Long
- def toFloat: Float // convert to Float
- def toDouble: Double // convert to Double
- }
- ```
+This is the signature of the numeric value type `Int`:
+
+```
+package scala
+abstract sealed class Int extends AnyVal {
+ def == (that: Double): Boolean // double equality
+ def == (that: Float): Boolean // float equality
+ def == (that: Long): Boolean // long equality
+ def == (that: Int): Boolean // int equality
+ def == (that: Short): Boolean // int equality
+ def == (that: Byte): Boolean // int equality
+ def == (that: Char): Boolean // int equality
+ /* analogous for !=, <, >, <=, >= */
+
+ def + (that: Double): Double // double addition
+ def + (that: Float): Double // float addition
+ def + (that: Long): Long // long addition
+ def + (that: Int): Int // int addition
+ def + (that: Short): Int // int addition
+ def + (that: Byte): Int // int addition
+ def + (that: Char): Int // int addition
+ /* analogous for -, *, /, % */
+
+ def & (that: Long): Long // long bitwise and
+ def & (that: Int): Int // int bitwise and
+ def & (that: Short): Int // int bitwise and
+ def & (that: Byte): Int // int bitwise and
+ def & (that: Char): Int // int bitwise and
+ /* analogous for |, ^ */
+
+ def << (cnt: Int): Int // int left shift
+ def << (cnt: Long): Int // long left shift
+ /* analogous for >>, >>> */
+
+ def unary_+ : Int // int identity
+ def unary_- : Int // int negation
+ def unary_~ : Int // int bitwise negation
+
+ def toByte: Byte // convert to Byte
+ def toShort: Short // convert to Short
+ def toChar: Char // convert to Char
+ def toInt: Int // convert to Int
+ def toLong: Long // convert to Long
+ def toFloat: Float // convert to Float
+ def toDouble: Double // convert to Double
+}
+```
### Class `Boolean`
@@ -427,12 +429,12 @@ Because of the syntactic sugar for `apply` and `update` operations,
we have the following correspondences between Scala and Java/C# code for
operations on an array `xs`:
------------------- ----------------------
-_Scala_ _Java/C#_
-`xs.length` `xs.length`
-`xs(i)` `xs[i]`
-`xs(i) = e` `xs[i] = e`
------------------- ----------------------
+|------------------|------------|
+|_Scala_ |_Java/C#_ |
+|`xs.length` |`xs.length` |
+|`xs(i)` |`xs[i]` |
+|`xs(i) = e` |`xs[i] = e` |
+|------------------|------------|
Two implicit conversions exist in `Predef` that are frequently applied to arrays:
a conversion to `scala.collection.mutable.ArrayOps` and a conversion to
@@ -495,11 +497,9 @@ def mkArray[T : ClassTag](elems: Seq[T]): Array[T] = {
If type $T$ is a type for which the host platform offers a specialized array
representation, this representation is used.
-(@) On the Java Virtual Machine, an invocation of
- ```
- mkArray(List(1,2,3))
- ```
- will return a primitive array of `int`s, written as `int[]` in Java.
+###### Example
+On the Java Virtual Machine, an invocation of `mkArray(List(1,2,3))`
+will return a primitive array of `int`s, written as `int[]` in Java.
#### Companion object