diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-10 16:57:23 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-10 16:57:23 -0700 |
commit | 9dec37b50be3288822b9c7c0cb5c4d263f3d05e7 (patch) | |
tree | 466424f759cc267f6c05da7610b7bd7bdd166afc | |
parent | df2f3f7cd69bb042a29b4fcea3ab81d641f17906 (diff) | |
download | scala-9dec37b50be3288822b9c7c0cb5c4d263f3d05e7.tar.gz scala-9dec37b50be3288822b9c7c0cb5c4d263f3d05e7.tar.bz2 scala-9dec37b50be3288822b9c7c0cb5c4d263f3d05e7.zip |
github markdown: drop css classes
-rw-r--r-- | 03-lexical-syntax.md | 116 | ||||
-rw-r--r-- | 04-identifiers-names-and-scopes.md | 6 | ||||
-rw-r--r-- | 05-types.md | 98 | ||||
-rw-r--r-- | 06-basic-declarations-and-definitions.md | 92 | ||||
-rw-r--r-- | 07-classes-and-objects.md | 88 | ||||
-rw-r--r-- | 08-expressions.md | 178 | ||||
-rw-r--r-- | 09-implicit-parameters-and-views.md | 56 | ||||
-rw-r--r-- | 10-pattern-matching.md | 68 | ||||
-rw-r--r-- | 11-top-level-definitions.md | 24 | ||||
-rw-r--r-- | 12-xml-expressions-and-patterns.md | 14 | ||||
-rw-r--r-- | 13-user-defined-annotations.md | 12 | ||||
-rw-r--r-- | 14-the-scala-standard-library.md | 44 | ||||
-rw-r--r-- | 15-scala-syntax-summary.md | 4 |
13 files changed, 400 insertions, 400 deletions
diff --git a/03-lexical-syntax.md b/03-lexical-syntax.md index 5c6a0135c4..0bbf47fc80 100644 --- a/03-lexical-syntax.md +++ b/03-lexical-syntax.md @@ -11,7 +11,7 @@ to Scala mode, and literal characters ‘c’ refer to the ASCII fragment In Scala mode, _Unicode escapes_ are replaced by the corresponding Unicode character with the given hexadecimal code. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UnicodeEscape ::= \{\\}u{u} hexDigit hexDigit hexDigit hexDigit hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -35,7 +35,7 @@ classes (Unicode general category given in parentheses): ## Identifiers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ op ::= opchar {opchar} varid ::= lower idrest plainid ::= upper idrest @@ -60,7 +60,7 @@ of all characters excluding the backquotes themselves. As usual, a longest match rule applies. For instance, the string -~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~ big_bob++=`def` ~~~~~~~~~~~~~~~~ @@ -103,12 +103,12 @@ equivalents ‘=>’ and ‘<-’, are also reserved. 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`() ``{.scala} + work-around: `` Thread.`yield`() `` ## Newline Characters -~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~ semi ::= ‘;’ | nl {nl} ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -137,8 +137,8 @@ with yield , . ; : = => <- <: <% >: # [ ) ] } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A `case`{.scala} token can begin a statement only if followed by a -`class`{.scala} or `object`{.scala} token. +A `case` token can begin a statement only if followed by a +`class` or `object` token. Newlines are enabled in: @@ -153,8 +153,8 @@ Newlines are disabled in: nested regions where newlines are enabled, and 1. the interval between matching `[` and `]` bracket tokens, except for nested regions where newlines are enabled. -1. The interval between a `case`{.scala} token and its matching - `=>`{.scala} token, except for nested regions where newlines are +1. The interval between a `case` token and its matching + `=>` token, except for nested regions where newlines are enabled. 1. Any regions analyzed in [XML mode](#xml-mode). @@ -186,7 +186,7 @@ of these cases): - between the enumerators of a [for-comprehension](#for-comprehensions-and-for-loops) and the next following expression, and -- after the initial `type`{.scala} keyword in a +- after the initial `type` keyword in a [type definition or declaration](#type-declarations-and-type-aliases). A single new line token is accepted @@ -202,7 +202,7 @@ A single new line token is accepted on two lines. The newline tokens between the two lines are not treated as statement separators. - ~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~ if (x > 0) x = x - 1 @@ -218,7 +218,7 @@ A single new line token is accepted (@) The following code designates an anonymous class: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ new Iterator[Int] { private var x = 0 @@ -230,7 +230,7 @@ A single new line token is accepted With an additional newline character, the same code is interpreted as an object creation followed by a local block: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ new Iterator[Int] { @@ -242,7 +242,7 @@ A single new line token is accepted (@) The following code designates a single expression: - ~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~ x < 0 || x > 10 ~~~~~~~~~~~~ @@ -250,7 +250,7 @@ A single new line token is accepted With an additional newline character, the same code is interpreted as two expressions: - ~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~ x < 0 || x > 10 @@ -258,7 +258,7 @@ A single new line token is accepted (@) The following code designates a single, curried function definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~ def func(x: Int) (y: Int) = x + y ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -266,7 +266,7 @@ A single new line token is accepted With an additional newline character, the same code is interpreted as an abstract function definition and a syntactically illegal statement: - ~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~ def func(x: Int) (y: Int) = x + y @@ -274,7 +274,7 @@ A single new line token is accepted (@) The following code designates an attributed definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @serializable protected class Data { ... } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -283,7 +283,7 @@ A single new line token is accepted an attribute and a separate statement (which is syntactically illegal). - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @serializable protected class Data { ... } @@ -301,7 +301,7 @@ each case as in Java. particular float and double. --> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Literal ::= [‘-’] integerLiteral | [‘-’] floatingPointLiteral | booleanLiteral @@ -314,7 +314,7 @@ Literal ::= [‘-’] integerLiteral ### Integer Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ integerLiteral ::= (decimalNumeral | hexNumeral | octalNumeral) [‘L’ | ‘l’] decimalNumeral ::= ‘0’ | nonZeroDigit {digit} @@ -325,24 +325,24 @@ nonZeroDigit ::= ‘1’ | … | ‘9’ octalDigit ::= ‘0’ | … | ‘7’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Integer literals are usually of type `Int`{.scala}, or of type -`Long`{.scala} when followed by a `L` or -`l` suffix. Values of type `Int`{.scala} are all integer +Integer literals are usually of type `Int`, or of type +`Long` when followed by a `L` or +`l` suffix. Values of type `Int` are all integer numbers between $-2^{31}$ and $2^{31}-1$, inclusive. Values of -type `Long`{.scala} are all integer numbers between $-2^{63}$ and +type `Long` are all integer numbers between $-2^{63}$ and $2^{63}-1$, inclusive. A compile-time error occurs if an integer literal denotes a number outside these ranges. However, if the expected type [_pt_](#expression-typing) of a literal -in an expression is either `Byte`{.scala}, `Short`{.scala}, or `Char`{.scala} +in an expression is either `Byte`, `Short`, or `Char` and the integer number fits in the numeric range defined by the type, then the number is converted to type _pt_ and the literal's type is _pt_. The numeric ranges given by these types are: --------------- ----------------------- -`Byte`{.scala} $-2^7$ to $2^7-1$ -`Short`{.scala} $-2^{15}$ to $2^{15}-1$ -`Char`{.scala} $0$ to $2^{16}-1$ +`Byte` $-2^7$ to $2^7-1$ +`Short` $-2^{15}$ to $2^{15}-1$ +`Char` $0$ to $2^{16}-1$ --------------- ----------------------- (@) Here are some integer literals: @@ -354,7 +354,7 @@ is _pt_. The numeric ranges given by these types are: ### Floating Point Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ floatingPointLiteral ::= digit {digit} ‘.’ {digit} [exponentPart] [floatType] | ‘.’ digit {digit} [exponentPart] [floatType] | digit {digit} exponentPart [floatType] @@ -363,11 +363,11 @@ exponentPart ::= (‘E’ | ‘e’) [‘+’ | ‘-’] digit {digit} floatType ::= ‘F’ | ‘f’ | ‘D’ | ‘d’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Floating point literals are of type `Float`{.scala} when followed by +Floating point literals are of type `Float` when followed by a floating point type suffix `F` or `f`, and are -of type `Double`{.scala} otherwise. The type `Float`{.scala} +of type `Double` otherwise. The type `Float` consists of all IEEE 754 32-bit single-precision binary floating point -values, whereas the type `Double`{.scala} consists of all IEEE 754 +values, whereas the type `Double` consists of all IEEE 754 64-bit double-precision binary floating point values. If a floating point literal in a program is followed by a token @@ -380,26 +380,26 @@ whitespace character between the two tokens. 0.0 1e30f 3.14159f 1.0e-100 .1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(@) The phrase `1.toString`{.scala} parses as three different tokens: - `1`{.scala}, `.`{.scala}, and `toString`{.scala}. On the +(@) The phrase `1.toString` parses as three different tokens: + `1`, `.`, and `toString`. On the other hand, if a space is inserted after the period, the phrase - `1. toString`{.scala} parses as the floating point literal - `1.`{.scala} followed by the identifier `toString`{.scala}. + `1. toString` parses as the floating point literal + `1.` followed by the identifier `toString`. ### Boolean Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ booleanLiteral ::= ‘true’ | ‘false’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The boolean literals `true`{.scala} and `false`{.scala} are -members of type `Boolean`{.scala}. +The boolean literals `true` and `false` are +members of type `Boolean`. ### Character Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ characterLiteral ::= ‘'’ printableChar ‘'’ | ‘'’ charEscapeSeq ‘'’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -423,7 +423,7 @@ the octal escape `'\12'` ([see here](#escape-sequences)). ### String Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ stringLiteral ::= ‘\"’ {stringElement} ‘\"’ stringElement ::= printableCharNoDoubleQuote | charEscapeSeq ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -433,11 +433,11 @@ characters are either printable unicode character or are described by [escape sequences](#escape-sequences). If the string literal contains a double quote character, it must be escaped, i.e. `"\""`. The value of a string literal is an instance of -class `String`{.scala}. +class `String`. (@) Here are some string literals: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "Hello,\nWorld!" "This string contains a \" character." ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -450,7 +450,7 @@ multiLineChars ::= {[‘"’] [‘"’] charNoDoubleQuote} {‘"’} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A multi-line string literal is a sequence of characters enclosed in -triple quotes `""" ... """`{.scala}. The sequence of characters is +triple quotes `""" ... """`. The sequence of characters is arbitrary, except that it may contain three or more consuctive quote characters only at the very end. Characters must not necessarily be printable; newlines or other @@ -459,7 +459,7 @@ of the escape sequences [here](#escape-sequences) are interpreted. (@) Here is a multi-line string literal: - ~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~ """the present string spans three lines.""" @@ -477,7 +477,7 @@ The Scala library contains a utility method `stripMargin` which can be used to strip leading whitespace from multi-line strings. The expression -~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~ """the present string spans three lines.""".stripMargin @@ -485,7 +485,7 @@ The expression evaluates to -~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~ the present string spans three lines. @@ -494,8 +494,8 @@ lines. Method `stripMargin` is defined in class [scala.collection.immutable.StringLike](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringLike). Because there is a predefined -[implicit conversion](#implicit-conversions) from `String`{.scala} to -`StringLike`{.scala}, the method is applicable to all strings. +[implicit conversion](#implicit-conversions) from `String` to +`StringLike`, the method is applicable to all strings. ### Escape Sequences @@ -524,23 +524,23 @@ string literal does not start a valid escape sequence. ### Symbol literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ symbolLiteral ::= ‘'’ plainid ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A symbol literal `'x`{.scala} is a shorthand for the expression -`scala.Symbol("x")`{.scala}. `Symbol` is a [case class](#case-classes), +A symbol literal `'x` is a shorthand for the expression +`scala.Symbol("x")`. `Symbol` is a [case class](#case-classes), which is defined as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala final case class Symbol private (name: String) { override def toString: String = "'" + name } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The `apply`{.scala} method of `Symbol`{.scala}'s companion object -caches weak references to `Symbol`{.scala}s, thus ensuring that +The `apply` method of `Symbol`'s companion object +caches weak references to `Symbol`s, thus ensuring that identical symbol literals are equivalent with respect to reference equality. @@ -568,7 +568,7 @@ angle bracket '<' in the following circumstance: The '<' must be preceded either by whitespace, an opening parenthesis or an opening brace and immediately followed by a character starting an XML name. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ( whitespace | ‘(’ | ‘{’ ) ‘<’ (XNameStart | ‘!’ | ‘?’) XNameStart ::= ‘_’ | BaseChar | Ideographic // as in W3C XML, but without ‘:’ @@ -591,7 +591,7 @@ as text. (@) The following value definition uses an XML literal with two embedded Scala expressions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val b = <book> <title>The Scala Language Specification</title> <version>{scalaBook.version}</version> diff --git a/04-identifiers-names-and-scopes.md b/04-identifiers-names-and-scopes.md index e5d8a70c59..e4b92d2a8b 100644 --- a/04-identifiers-names-and-scopes.md +++ b/04-identifiers-names-and-scopes.md @@ -31,7 +31,7 @@ scopes. Note that shadowing is only a partial order. In a situation like -~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~ val x = 1; { import p.x; x } @@ -57,7 +57,7 @@ of the referenced entity. (@) Assume the following two definitions of a objects named `X` in packages `P` and `Q`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package P { object X { val x = 1; val y = 2 } } @@ -70,7 +70,7 @@ of the referenced entity. The following program illustrates different kinds of bindings and precedences between them. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package P { // `X' bound by package clause import Console._ // `println' bound by wildcard import object A { diff --git a/05-types.md b/05-types.md index 624804df10..03be174d75 100644 --- a/05-types.md +++ b/05-types.md @@ -1,6 +1,6 @@ # Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type ::= FunctionArgTypes ‘=>’ Type | InfixType [ExistentialClause] FunctionArgTypes ::= InfixType @@ -54,13 +54,13 @@ Non-value types are expressed indirectly in Scala. E.g., a method type is described by writing down a method signature, which in itself is not a real type, although it gives rise to a corresponding [method type](#method-types). Type constructors are another example, as one can write -`type Swap[m[_, _], a,b] = m[b, a]`{.scala}, but there is no syntax to write +`type Swap[m[_, _], a,b] = m[b, a]`, but there is no syntax to write the corresponding anonymous type function directly. ## Paths -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Path ::= StableId | [id ‘.’] this StableId ::= id @@ -84,7 +84,7 @@ A path is one of the following. - `$C$.super.$x$` or `$C$.super[$M$].$x$` where $C$ references a class and $x$ references a stable member of the super class or designated parent class $M$ of $C$. - The prefix `super`{.scala} is taken as a shorthand for `$C$.super` where + The prefix `super` is taken as a shorthand for `$C$.super` where $C$ is the name of the class directly enclosing the reference. A _stable identifier_ is a path which ends in an identifier. @@ -97,25 +97,25 @@ forms. ### Singleton Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleType ::= Path ‘.’ type ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A singleton type is of the form `$p$.type`{.scala}, where $p$ is a +A singleton type is of the form `$p$.type`, where $p$ is a path pointing to a value expected to [conform](#expression-typing) -to `scala.AnyRef`{.scala}. The type denotes the set of values -consisting of `null`{.scala} and the value denoted by $p$. +to `scala.AnyRef`. The type denotes the set of values +consisting of `null` and the value denoted by $p$. A _stable type_ is either a singleton type or a type which is -declared to be a subtype of trait `scala.Singleton`{.scala}. +declared to be a subtype of trait `scala.Singleton`. ### Type Projection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleType ::= SimpleType ‘#’ id ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A type projection `$T$#$x$`{.scala} references the type member named +A type projection `$T$#$x$` references the type member named $x$ of type $T$. <!-- @@ -126,7 +126,7 @@ If $x$ references an abstract type member, then $T$ must be a ### Type Designators -~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleType ::= StableId ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -135,17 +135,17 @@ qualified. All such type designators are shorthands for type projections. Specifically, the unqualified type name $t$ where $t$ is bound in some class, object, or package $C$ is taken as a shorthand for -`$C$.this.type#$t$`{.scala}. If $t$ is +`$C$.this.type#$t$`. If $t$ is not bound in a class, object, or package, then $t$ is taken as a shorthand for `ε.type#$t$`. 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`{.scala}. +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`{.scala}, + with a type member `Node` and the standard class `scala.Int`, -------------------- -------------------------- t ε.type#t @@ -157,7 +157,7 @@ equivalent to the type projection `p.type#t`{.scala}. ### Parameterized Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleType ::= SimpleType TypeArgs TypeArgs ::= ‘[’ Types ‘]’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -175,7 +175,7 @@ substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. (@param-types) Given the partial type definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class TreeMap[A <: Comparable[A], B] { … } class List[A] { … } class I extends Comparable[I] { … } @@ -187,7 +187,7 @@ substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. the following parameterized types are well formed: - ~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~ TreeMap[I, String] List[I] List[List[Boolean]] @@ -199,7 +199,7 @@ substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. (@) Given the type definitions of (@param-types), the following types are ill-formed: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TreeMap[I] // illegal: wrong number of parameters TreeMap[List[I], Int] // illegal: type parameter not within bound @@ -214,7 +214,7 @@ substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. ### Tuple Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleType ::= ‘(’ Types ‘)’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -228,7 +228,7 @@ class and product trait are defined at least as follows in the standard Scala library (they might also add other methods and implement other traits). -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ case class Tuple$n$[+T1, … , +$T_n$](_1: T1, … , _n: $T_n$) extends Product_n[T1, … , $T_n$] @@ -242,7 +242,7 @@ trait Product_n[+T1, … , +$T_n$] { ### Annotated Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AnnotType ::= SimpleType {Annotation} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -250,17 +250,17 @@ 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`{.scala} annotation to the type - `String`{.scala}: +(@) The following type adds the `@suspendable` annotation to the type + `String`: - ~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~ String @suspendable ~~~~~~~~~~~~~~~~~~~~ ### Compound Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement] | Refinement Refinement ::= [nl] ‘{’ RefineStat {semi RefineStat} ‘}’ @@ -290,17 +290,17 @@ definition within the refinement. This restriction does not apply to the function's result type. If no refinement is given, the empty refinement is implicitly added, -i.e.\ `$T_1$ with … with $T_n$`{.scala} is a shorthand for -`$T_1$ with … with $T_n$ {}`{.scala}. +i.e.\ `$T_1$ with … with $T_n$` is a shorthand for +`$T_1$ with … with $T_n$ {}`. A compound type may also consist of just a refinement `{ $R$ }` with no preceding component types. Such a type is -equivalent to `AnyRef{ R }`{.scala}. +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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ case class Bird (val name: String) extends Object { def fly(height: Int) = … … @@ -330,7 +330,7 @@ equivalent to `AnyRef{ R }`{.scala}. ### Infix Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ InfixType ::= CompoundType {id [nl] CompoundType} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -359,7 +359,7 @@ $t_0 \mathit{op_1} (t_1 \mathit{op_2} ( \ldots \mathit{op_n} t_n) \ldots)$. ### Function Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type ::= FunctionArgs ‘=>’ Type FunctionArgs ::= InfixType | ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’ @@ -382,7 +382,7 @@ $(T_1 , \ldots , T_n) \Rightarrow U$ is a shorthand for the class type `Function$_n$[T1 , … , $T_n$, U]`. Such class types are defined in the Scala library for $n$ between 0 and 9 as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala trait Function_n[-T1 , … , -T$_n$, +R] { def apply(x1: T1 , … , x$_n$: T$_n$): R @@ -395,7 +395,7 @@ result type and contravariant in their argument types. ### Existential Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type ::= InfixType ExistentialClauses ExistentialClauses ::= ‘forSome’ ‘{’ ExistentialDcl {semi ExistentialDcl} ‘}’ @@ -464,7 +464,7 @@ fresh type name and $T'$ results from $T$ by replacing every occurrence of #### Placeholder Syntax for Existential Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ WildcardType ::= ‘_’ TypeBounds ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -497,14 +497,14 @@ type. (@) Assume the class definitions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Ref[T] abstract class Outer { type T } . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here are some examples of existential types: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 } @@ -513,31 +513,31 @@ type. The last two types in this list are equivalent. An alternative formulation of the first type above using wildcard syntax is: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ref[_ <: java.lang.Number] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ (@) The type `List[List[_]]` is equivalent to the existential type - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ List[List[t] forSome { type t }] . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (@) Assume a covariant type - ~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~ class List[+T] ~~~~~~~~~~~~~~~ The type - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ List[T] forSome { type T <: java.lang.Number } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is equivalent (by simplification rule 4 above) to - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ List[java.lang.Number] forSome { type T <: java.lang.Number } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -575,7 +575,7 @@ corresponding function type. (@) The declarations - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def a: Int def b (x: Int): Boolean def c (x: Int) (y: String, z: String): String @@ -583,7 +583,7 @@ corresponding function type. produce the typings - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a: => Int b: (Int) Boolean c: (Int) (String, String) String @@ -603,14 +603,14 @@ take type arguments `$S_1 , \ldots , S_n$` which (@) The declarations - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def empty[A]: List[A] def union[A <: Comparable[A]] (x: Set[A], xs: Set[A]): Set[A] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ produce the typings - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ empty : [A >: Nothing <: Any] List[A] union : [A >: Nothing <: Comparable[A]] (x: Set[A], xs: Set[A]) Set[A] . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -624,9 +624,9 @@ 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]`{.scala} class: +(@) Consider this fragment of the `Iterable[+X]` class: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait Iterable[+X] { def flatMap[newType[+X] <: Iterable[X], S](f: X => newType[S]): newType[S] } @@ -884,7 +884,7 @@ are understood to be relative to that order. > of a set of types does not always exist. For instance, consider > the class definitions -~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~ class A[+T] {} class B extends A[B] class C extends A[C] diff --git a/06-basic-declarations-and-definitions.md b/06-basic-declarations-and-definitions.md index dcf41abce3..accf4400a1 100644 --- a/06-basic-declarations-and-definitions.md +++ b/06-basic-declarations-and-definitions.md @@ -1,7 +1,7 @@ # Basic Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Dcl ::= ‘val’ ValDcl | ‘var’ VarDcl | ‘def’ FunDcl @@ -37,7 +37,7 @@ between and including $s_i$ and $s_j$, ## Value Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Dcl ::= ‘val’ ValDcl ValDcl ::= ids ‘:’ Type PatVarDef ::= ‘val’ PatDef @@ -63,7 +63,7 @@ its right hand side $e$ the first time the value is accessed. A _constant value definition_ is of the form -~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~ final val x = e ~~~~~~~~~~~~~~~~ @@ -80,7 +80,7 @@ value definition `val $p$ = $e$` is expanded as follows: 1. If the pattern $p$ has bound variables $x_1 , \ldots , x_n$, where $n > 1$: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val $\$ x$ = $e$ match {case $p$ => ($x_1 , \ldots , x_n$)} val $x_1$ = $\$ x$._1 $\ldots$ @@ -91,19 +91,19 @@ Here, $\$ x$ is a fresh name. 2. If $p$ has a unique bound variable $x$: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val $x$ = $e$ match { case $p$ => $x$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3. If $p$ has no bound variables: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $e$ match { case $p$ => ()} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (@) The following are examples of value definitions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val pi = 3.1415 val pi: Double = 3.1415 // equivalent to first definition val Some(x) = f() // a pattern definition @@ -112,7 +112,7 @@ $e$ match { case $p$ => ()} The last two definitions have the following expansions. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val x = f() match { case Some(x) => x } val x$\$$ = mylist match { case x :: xs => (x, xs) } @@ -133,7 +133,7 @@ sequence of value definitions `val $p_1: T$ = $e$; ...; val $p_n: T$ = $e$`. ## Variable Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Dcl ::= ‘var’ VarDcl PatVarDef ::= ‘var’ VarDef VarDcl ::= ids ‘:’ Type @@ -145,7 +145,7 @@ A variable declaration `var $x$: $T$` is equivalent to declarations of a _getter function_ $x$ and a _setter function_ `$x$_=`, defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~ def $x$: $T$ def $x$_= ($y$: $T$): Unit ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -201,7 +201,7 @@ a template member. values to be assigned to these fields. The user code, on the other hand, accesses these fields just like normal variables. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class TimeOfDayVar { private var h: Int = 0 private var m: Int = 0 @@ -237,7 +237,7 @@ the sequence of variable definitions <!-- TODO: Higher-kinded tdecls should have a separate section --> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Dcl ::= ‘type’ {nl} TypeDcl TypeDcl ::= id [TypeParamClause] [‘>:’ Type] [‘<:’ Type] Def ::= type {nl} TypeDef @@ -285,7 +285,7 @@ an abstract type is directly or indirectly its own upper or lower bound. (@) The following are legal type declarations and definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ type IntList = List[Integer] type T <: Comparable[T] type Two[A] = Tuple2[A, A] @@ -294,7 +294,7 @@ an abstract type is directly or indirectly its own upper or lower bound. The following are illegal: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ type Abs = Comparable[Abs] // recursive type alias type S <: T // S, T are bounded by themselves. @@ -313,7 +313,7 @@ objects of type $S$. (@) The `Predef` object contains a definition which establishes `Pair` as an alias of the parameterized class `Tuple2`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ type Pair[+A, +B] = Tuple2[A, B] object Pair { def apply[A, B](x: A, y: B) = Tuple2(x, y) @@ -325,14 +325,14 @@ objects of type $S$. `Pair[$S$, $T\,$]` is equivalent to the type `Tuple2[$S$, $T\,$]`. `Pair` can also be used as a constructor instead of `Tuple2`, as in: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val x: Pair[Int, String] = new Pair(1, "abc") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Type Parameters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’ VariantTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeParam TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] [‘:’ Type] @@ -371,7 +371,7 @@ The above scoping restrictions are generalized to the case of nested type parame (@) Here are some well-formed type parameter clauses: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [S, T] [@specialized T, U] [Ex <: Throwable] @@ -385,7 +385,7 @@ The above scoping restrictions are generalized to the case of nested type parame The following type parameter clauses are illegal: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [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 @@ -444,7 +444,7 @@ appear anywhere without restricting its legal variance annotations. (@) The following variance annotation is legal. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class P[+A, +B] { def fst: A; def snd: B } @@ -454,14 +454,14 @@ appear anywhere without restricting its legal variance annotations. of $P$ subtype covariantly with respect to their arguments. For instance, - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ P[IOException, String] <: P[Throwable, AnyRef] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the members of $P$ are mutable variables, the same variance annotation becomes illegal. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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. @@ -471,7 +471,7 @@ appear anywhere without restricting its legal variance annotations. If the mutable variables are object-private, the class definition becomes legal again: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class R[+A, +B](x: A, y: B) { private[this] var fst: A = x // OK private[this] var snd: B = y // OK @@ -481,7 +481,7 @@ appear anywhere without restricting its legal variance annotations. (@) The following variance annotation is illegal, since $a$ appears in contravariant position in the parameter of `append`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class Sequence[+A] { def append(x: Sequence[A]): Sequence[A] // **** error: illegal variance: @@ -492,7 +492,7 @@ appear anywhere without restricting its legal variance annotations. The problem can be avoided by generalizing the type of `append` by means of a lower bound: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class Sequence[+A] { def append[B >: A](x: Sequence[B]): Sequence[B] } @@ -500,7 +500,7 @@ appear anywhere without restricting its legal variance annotations. (@) Here is a case where a contravariant type parameter is useful. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class OutputChannel[-A] { def write(x: A): Unit } @@ -515,7 +515,7 @@ appear anywhere without restricting its legal variance annotations. ## Function Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Dcl ::= ‘def’ FunDcl FunDcl ::= FunSig ‘:’ Type Def ::= ‘def’ FunDef @@ -581,7 +581,7 @@ be pairwise distinct. (@) In the method - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def compare[T](a: T = 0)(b: T = a) = (a == b) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -590,7 +590,7 @@ be pairwise distinct. and `T` is instantiated to `Int`. The methods computing the default arguments have the form: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def compare$\$$default$\$$1[T]: Int = 0 def compare$\$$default$\$$2[T](a: T): T = a ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -599,7 +599,7 @@ be pairwise distinct. ### By-Name Parameters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ParamType ::= ‘=>’ Type ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -618,7 +618,7 @@ by-name modifier is also disallowed for (@) The declaration - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def whileLoop (cond: => Boolean) (stat: => Unit): Unit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -628,7 +628,7 @@ by-name modifier is also disallowed for ### Repeated Parameters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ParamType ::= Type ‘*’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -656,7 +656,7 @@ with a repeated parameter. (@) The following method definition computes the sum of the squares of a variable number of integer arguments. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def sum(args: Int*) = { var result = 0 for (arg <- args) result += arg * arg @@ -667,7 +667,7 @@ with a repeated parameter. The following applications of this method yield `0`, `1`, `6`, in that order. - ~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~ sum() sum(1) sum(1, 2, 3) @@ -675,27 +675,27 @@ with a repeated parameter. Furthermore, assume the definition: - ~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~ val xs = List(1, 2, 3) ~~~~~~~~~~~~~~~~~~~~~~~ The following application of method `sum` is ill-formed: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sum(xs) // ***** error: expected: Int, found: List[Int] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ By contrast, the following application is well formed and yields again the result `6`: - ~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~ sum(xs: _*) ~~~~~~~~~~~~ ### Procedures -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FunDcl ::= FunSig FunDef ::= FunSig [nl] ‘{’ Block ‘}’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -714,7 +714,7 @@ E.g., `def $f$($\mathit{ps}$) {$\mathit{stats}$}` is equivalent to (@) Here is a declaration and a definition of a procedure named `write`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait Writer { def write(str: String) } @@ -725,7 +725,7 @@ E.g., `def $f$($\mathit{ps}$) {$\mathit{stats}$}` is equivalent to The code above is implicitly completed to the following code: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait Writer { def write(str: String): Unit } @@ -748,7 +748,7 @@ as $R$ conforms to $R'$. (@) Assume the following definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait I { def factorial(x: Int): Int } @@ -763,7 +763,7 @@ as $R$ conforms to $R'$. ## Import Clauses -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors) ImportSelectors ::= ‘{’ {ImportSelector ‘,’} @@ -779,7 +779,7 @@ _importable_ if it is not [object-private](#modifiers). The most general form of an import expression is a list of {\em import selectors} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { $x_1$ => $y_1 , \ldots , x_n$ => $y_n$, _ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -829,7 +829,7 @@ sequence of import clauses (@) Consider the object definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ object M { def z = 0, one = 1 def add(x: Int, y: Int): Int = x + y @@ -837,13 +837,13 @@ sequence of import clauses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Then the block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { import M.{one, z => zero, _}; add(zero, one) } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ is equivalent to the block - ~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~ { M.add(M.z, M.one) } ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/07-classes-and-objects.md b/07-classes-and-objects.md index 5e6cc3dfb5..4694c2eb13 100644 --- a/07-classes-and-objects.md +++ b/07-classes-and-objects.md @@ -1,6 +1,6 @@ # Classes and Objects -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TmplDef ::= [`case'] `class' ClassDef | [`case'] `object' ObjectDef | `trait' TraitDef @@ -12,7 +12,7 @@ are both defined in terms of _templates_. ## Templates -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ClassTemplate ::= [EarlyDefs] ClassParents [TemplateBody] TraitTemplate ::= [EarlyDefs] TraitParents [TemplateBody] ClassParents ::= Constr {`with' AnnotType} @@ -50,13 +50,13 @@ The list of parents of every class is also always implicitly extended by a reference to the `scala.ScalaObject` trait as last mixin. E.g. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $sc$ with $mt_1$ with $\ldots$ with $mt_n$ { $\mathit{stats}$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ becomes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $mt_1$ with $\ldots$ with $mt_n$ with ScalaObject { $\mathit{stats}$ }. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -103,7 +103,7 @@ without introducing an alias name for it. (@) Consider the following class definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Base extends Object {} trait Mixin extends Base {} object O extends Mixin {} @@ -111,7 +111,7 @@ without introducing an alias name for it. In this case, the definition of `O` is expanded to: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ object O extends Base with Mixin {} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -150,14 +150,14 @@ it. But templates inheriting the `scala.DelayedInit` trait can override the hook by re-implementing the `delayedInit` method, which is defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def delayedInit(body: => Unit) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ### Constructor Invocations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Constr ::= AnnotType {`(' [Exprs] `)'} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -207,7 +207,7 @@ linearization of this graph is defined as follows. > Here $\vec{+}$ denotes concatenation where elements of the right operand > replace identical elements of the left operand: > -> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.math} +> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > \[ > \begin{array}{lcll} > \{a, A\} \;\vec{+}\; B &=& a, (A \;\vec{+}\; B) &{\bf if} \; a \not\in B \\ @@ -219,7 +219,7 @@ linearization of this graph is defined as follows. (@) Consider the following class definitions. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class AbsIterator extends AnyRef { ... } trait RichIterator extends AbsIterator { ... } class StringIterator extends AbsIterator { ... } @@ -322,7 +322,7 @@ defined or inherited) with the same name which both define default arguments. (@) Consider the trait definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 } @@ -382,7 +382,7 @@ superclass (otherwise). (@compounda) Consider the definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait Root { type T <: Root } trait A extends Root { type T <: A } trait B extends Root { type T <: B } @@ -396,7 +396,7 @@ superclass (otherwise). in type `A`. The problem can be solved by adding an overriding definition of type `T` in class `C`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class C extends A with B { type T <: C } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -418,7 +418,7 @@ necessary to make subtyping decidable [@kennedy-pierce:decidable]). ### Early Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EarlyDefs ::= `{' [EarlyDef {semi EarlyDef}] `}' `with' EarlyDef ::= {Annotation} {Modifier} PatVarDef ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -427,7 +427,7 @@ A template may start with an _early field definition_ clause, which serves to define certain field values before the supertype constructor is called. In a template -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { val $p_1$: $T_1$ = $e_1$ ... val $p_n$: $T_n$ = $e_n$ @@ -461,7 +461,7 @@ before the superclass constructor of the template is called. (@) Early definitions are particularly useful for traits, which do not have normal constructor parameters. Example: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait Greeting { val name: String val msg = "How are you, "+name @@ -485,7 +485,7 @@ before the superclass constructor of the template is called. ## Modifiers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modifier ::= LocalModifier | AccessModifier | `override' @@ -626,7 +626,7 @@ the validity and meaning of a modifier are as follows. (@) The following code illustrates the use of qualified private: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package outerpkg.innerpkg class Outer { class Inner { @@ -650,7 +650,7 @@ the validity and meaning of a modifier are as follows. constructing new instances of that class is to declare the class `abstract` and `sealed`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ object m { abstract sealed class C (x: Int) { def nextC = new C(x + 1) {} @@ -664,7 +664,7 @@ the validity and meaning of a modifier are as follows. object; it is not possible for clients to create objects of class `m.C` directly. Indeed the following two lines are both in error: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ new m.C(0) // **** error: C is abstract, so it cannot be instantiated. new m.C(0) {} // **** error: illegal inheritance from sealed class. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -675,7 +675,7 @@ the validity and meaning of a modifier are as follows. ## Class Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TmplDef ::= `class' ClassDef ClassDef ::= id [TypeParamClause] {Annotation} [AccessModifier] ClassParamClauses ClassTemplateOpt @@ -690,7 +690,7 @@ ClassTemplateOpt ::= `extends' ClassTemplate | [[`extends'] TemplateBody] The most general form of class definition is -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class $c$[$\mathit{tps}\,$] $as$ $m$($\mathit{ps}_1$)$\ldots$($\mathit{ps}_n$) extends $t$ $\gap(n \geq 0)$. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -738,7 +738,7 @@ Here, [call-by-name parameter](#by-name-parameters). - $t$ is a [template](#templates) of the form - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $sc$ with $mt_1$ with $\ldots$ with $mt_m$ { $\mathit{stats}$ } // $m \geq 0$ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -759,7 +759,7 @@ $t$. (@) The following example illustrates `val` and `var` parameters of a class `C`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class C(x: Int, val y: String, var z: List[String]) val c = new C(1, "abc", List()) c.z = c.y :: c.z @@ -768,7 +768,7 @@ $t$. (@privateconstr) The following class can be created only from its companion module. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ object Sensitive { def makeSensitive(credentials: Certificate): Sensitive = if (credentials == Admin) new Sensitive() @@ -782,7 +782,7 @@ $t$. ### Constructor Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FunDef ::= `this' ParamClause ParamClauses (`=' ConstrExpr | [nl] ConstrBlock) ConstrExpr ::= SelfInvocation @@ -834,7 +834,7 @@ primary constructor of the class). (@) Consider the class definition - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LinkedList[A]() { var head = _ var tail = null @@ -851,7 +851,7 @@ primary constructor of the class). ## Case Classes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TmplDef ::= `case' `class' ClassDef ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -871,7 +871,7 @@ parameters $\mathit{tps}$ and value parameters $\mathit{ps}$ implicitly generates an [extractor object](#extractor-patterns) which is defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ object $c$ { def apply[$\mathit{tps}\,$]($\mathit{ps}_1\,$)$\ldots$($\mathit{ps}_n$): $c$[$\mathit{tps}\,$] = new $c$[$\mathit{Ts}\,$]($\mathit{xs}_1\,$)$\ldots$($\mathit{xs}_n$) def unapply[$\mathit{tps}\,$]($x$: $c$[$\mathit{tps}\,$]) = @@ -896,7 +896,7 @@ If the case class definition contains an empty value parameter list, the `unapply` method returns a `Boolean` instead of an `Option` type and is defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def unapply[$\mathit{tps}\,$]($x$: $c$[$\mathit{tps}\,$]) = x ne null ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -911,7 +911,7 @@ A method named `copy` is implicitly added to every case class unless the class already has a member (directly defined or inherited) with that name. The method is defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def copy[$\mathit{tps}\,$]($\mathit{ps}'_1\,$)$\ldots$($\mathit{ps}'_n$): $c$[$\mathit{tps}\,$] = new $c$[$\mathit{Ts}\,$]($\mathit{xs}_1\,$)$\ldots$($\mathit{xs}_n$) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -940,7 +940,7 @@ class different from `AnyRef`. In particular: (@) Here is the definition of abstract syntax for lambda calculus: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Expr case class Var (x: String) extends Expr case class Apply (f: Expr, e: Expr) extends Expr @@ -951,7 +951,7 @@ class different from `AnyRef`. In particular: `Var`, `Apply` and `Lambda`. A call-by-value evaluator for lambda expressions could then be written as follows. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ type Env = String => Value case class Value(e: Expr, env: Env) @@ -970,7 +970,7 @@ class different from `AnyRef`. In particular: It is possible to define further case classes that extend type `Expr` in other parts of the program, for instance - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ case class Number(x: Int) extends Expr ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -982,7 +982,7 @@ class different from `AnyRef`. In particular: ### Traits -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TmplDef ::= `trait' TraitDef TraitDef ::= id [TypeParamClause] TraitTemplateOpt TraitTemplateOpt ::= `extends' TraitTemplate | [[`extends'] TemplateBody] @@ -1012,7 +1012,7 @@ least proper supertype (which is statically known). comparison operators `<=`, `>`, and `>=`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait Comparable[T <: Comparable[T]] { self: T => def < (that: T): Boolean def <=(that: T): Boolean = this < that || this == that @@ -1029,7 +1029,7 @@ least proper supertype (which is statically known). `get`, except that it returns a given default value if the table is undefined for the given key. This class is implemented as follows. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class Table[A, B](defaultValue: B) { def get(key: A): Option[B] def set(key: A, value: B) @@ -1042,7 +1042,7 @@ least proper supertype (which is statically known). Here is a concrete implementation of the `Table` class. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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) @@ -1053,7 +1053,7 @@ least proper supertype (which is statically known). Here is a trait that prevents concurrent access to the `get` and `set` operations of its parent class: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait SynchronizedTable[A, B] extends Table[A, B] { abstract override def get(key: A): B = synchronized { super.get(key) } @@ -1074,7 +1074,7 @@ least proper supertype (which is statically known). table with strings as keys and integers as values and with a default value `0`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ object MyTable extends ListTable[String, Int](0) with SynchronizedTable ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1087,7 +1087,7 @@ least proper supertype (which is statically known). ## Object Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ObjectDef ::= id ClassTemplate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1097,7 +1097,7 @@ most general form is $m$ is the name of the object to be defined, and $t$ is a [template](#templates) of the form -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $sc$ with $mt_1$ with $\ldots$ with $mt_n$ { $\mathit{stats}$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1112,7 +1112,7 @@ The object definition defines a single object (or: _module_) conforming to the template $t$. It is roughly equivalent to the following definition of a lazy value: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lazy val $m$ = new $sc$ with $mt_1$ with $\ldots$ with $mt_n$ { this: $m.type$ => $\mathit{stats}$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1135,7 +1135,7 @@ top-level objects are translated to static fields. effect can be achieved by an accompanying object definition E.g. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class Point { val x: Double val y: Double diff --git a/08-expressions.md b/08-expressions.md index 01b21ba91c..18f5831f20 100644 --- a/08-expressions.md +++ b/08-expressions.md @@ -1,6 +1,6 @@ # Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr ::= (Bindings | id | `_') `=>' Expr | Expr1 Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr] @@ -65,14 +65,14 @@ type $T$ and let $t_1[\mathit{tps}_1] >: L_1 <: U_1 , \ldots , t_n[\mathit{tps}_ all the type variables created by skolemization of some part of $e$ which are free in $T$. Then the _packed type_ of $e$ is -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $T$ forSome { type $t_1[\mathit{tps}_1] >: L_1 <: U_1$; $\ldots$; type $t_n[\mathit{tps}_n] >: L_n <: U_n$ }. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= Literal ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -102,7 +102,7 @@ A reference to any other member of the ``null'' object causes a ## Designators -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= Path | SimpleExpr `.' id ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -156,7 +156,7 @@ is thrown. ## This and Super -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= [id `.'] `this' | [id '.'] `super' [ClassQualifier] `.' id ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -208,7 +208,7 @@ it must be concrete. (@super) Consider the following class definitions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Root { def x = "Root" } class A extends Root { override def x = "A" ; def superA = super.x } trait B extends Root { override def x = "B" ; def superB = super.x } @@ -224,7 +224,7 @@ it must be concrete. the linearization of class `D` is `{D, B, A, Root}`. Then we have: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (new A).superA == "Root", (new C).superB = "Root", (new C).superC = "B", (new D).superA == "Root", (new D).superB = "A", (new D).superD = "B", @@ -236,7 +236,7 @@ it must be concrete. ## Function Applications -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= SimpleExpr1 ArgumentExprs ArgumentExprs ::= `(' [Exprs] `)' | `(' [Exprs `,'] PostfixExpr `:' `_' `*' ')' @@ -320,20 +320,20 @@ of the caller. (@) Assume the following function which computes the sum of a variable number of arguments: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def sum(xs: Int*) = (0 /: xs) ((x, y) => x + y) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Then - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ sum(1, 2, 3, 4) sum(List(1, 2, 3, 4): _*) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ both yield `10` as result. On the other hand, - ~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~ sum(List(1, 2, 3, 4)) ~~~~~~~~~~~~~~~~~~~~~~ @@ -362,7 +362,7 @@ If the function $f$ has the form `$p.m$[$\mathit{targs}$]` it is transformed into the block -~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~ { val q = $p$ q.$m$[$\mathit{targs}$] } @@ -372,7 +372,7 @@ If the function $f$ is itself an application expression the transformation is applied recursively on $f$. The result of transforming $f$ is a block of the form -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { val q = $p$ val $x_1$ = expr$_1$ $\ldots$ @@ -397,7 +397,7 @@ that the position of each name matches the position of its corresponding parameter in the method type `($p_1:T_1 , \ldots , p_n:T_n$)$U$`. The final result of the transformation is a block of the form -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { val q = $p$ val $x_1$ = expr$_1$ $\ldots$ @@ -415,7 +415,7 @@ The final result of the transformation is a block of the form ## Method Values -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= SimpleExpr1 `_' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -432,10 +432,10 @@ parameterlist `()`. [anonymous functions](#anonymous-functions) on their right. ------------------------------ ----------------------------------------------------- - `Math.sin _`{.scala} `x => Math.sin(x)`{.scala} - `Array.range _`{.scala} `(x1, x2) => Array.range(x1, x2)`{.scala} - `List.map2 _`{.scala} `(x1, x2) => (x3) => List.map2(x1, x2)(x3)`{.scala} - `List.map2(xs, ys)_`{.scala} `x => List.map2(xs, ys)(x)`{.scala} + `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 @@ -444,7 +444,7 @@ parameterlist `()`. ## Type Applications -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= SimpleExpr TypeArgs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -471,7 +471,7 @@ and the expected result type. ## Tuples -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= `(' [Exprs] `)' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -484,7 +484,7 @@ The empty tuple ## Instance Creation Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr ::= `new' (ClassTemplate | TemplateBody) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -499,7 +499,7 @@ $T$. The concrete self type is normally $T$, except if the expression `new $c$` appears as the right hand side of a value definition -~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~ val $x$: $S$ = new $c$ ~~~~~~~~~~~~~~~~~~~~~~~ @@ -515,7 +515,7 @@ A general instance creation expression is of the form `new $t$` for some [class template](#templates) $t$. Such an expression is equivalent to the block -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { class $a$ extends $t$; new $a$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -529,19 +529,19 @@ types: If `{$D$}` is a class body, then (@) Consider the following structural instance creation expression: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ new { def getName() = "aaron" } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is a shorthand for the general instance creation expression - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ new AnyRef{ def getName() = "aaron" } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The latter is in turn a shorthand for the block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { class anon\$X extends AnyRef{ def getName() = "aaron" }; new anon\$X } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -550,7 +550,7 @@ types: If `{$D$}` is a class body, then ## Blocks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BlockExpr ::= `{' Block `}' Block ::= {BlockStat semi} [ResultExpr] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -595,14 +595,14 @@ $e$, which defines the result of the block. (@) Assuming a class `Ref[T](x: T)`, the block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { class C extends B {$\ldots$} ; new Ref(new C) } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ has the type `Ref[_1] forSome { type _1 <: B }`. The block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { class C extends B {$\ldots$} ; new C } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -613,7 +613,7 @@ $e$, which defines the result of the block. ## Prefix, Infix, and Postfix Operations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PostfixExpr ::= InfixExpr [id [nl]] InfixExpr ::= PrefixExpr | InfixExpr id [nl] InfixExpr @@ -728,7 +728,7 @@ operation `$l$ += $r$`, where $l$, $r$ are expressions. This operation can be re-interpreted as an operation which corresponds to the assignment -~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~ $l$ = $l$ + $r$ ~~~~~~~~~~~~~~~~ @@ -748,7 +748,7 @@ The re-interpretation occurs if the following two conditions are fulfilled. ## Typed Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= PostfixExpr `:' CompoundType ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -758,7 +758,7 @@ the expression is the value of $e$ converted to type $T$. (@) Here are examples of well-typed and illegally typed expressions. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1: Int // legal, of type Int 1: Long // legal, of type Long // 1: string // ***** illegal @@ -767,7 +767,7 @@ the expression is the value of $e$ converted to type $T$. ## Annotated Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= PostfixExpr `:' Annotation {Annotation} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -778,7 +778,7 @@ expression $e$. ## Assignments -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= [SimpleExpr `.'] id `=' Expr | SimpleExpr1 ArgumentExprs `=' Expr ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -803,15 +803,15 @@ the invocation of an `update` function defined by $f$. (@) Here are some assignment expressions and their equivalent expansions. -------------------------- --------------------- - `x.f = e`{.scala} x.f_=(e) - `x.f() = e`{.scala} x.f.update(e) - `x.f(i) = e`{.scala} x.f.update(i, e) - `x.f(i, j) = e`{.scala} 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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { val zss: Array[Array[Double]] = new Array(xss.length, yss(0).length) var i = 0 @@ -836,7 +836,7 @@ the invocation of an `update` function defined by $f$. Desugaring the array accesses and assignments yields the following expanded version: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { val zss: Array[Array[Double]] = new Array(xss.length, yss.apply(0).length) var i = 0 @@ -861,7 +861,7 @@ the invocation of an `update` function defined by $f$. ## Conditional Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -887,7 +887,7 @@ evaluated as if it was `if ($e_1$) $e_2$ else ()`. ## While Loop Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= `while' `(' Expr ')' {nl} Expr ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -895,7 +895,7 @@ The while loop expression `while ($e_1$) $e_2$` is typed and evaluated as if it was an application of `whileLoop ($e_1$) ($e_2$)` where the hypothetical function `whileLoop` is defined as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def whileLoop(cond: => Boolean)(body: => Unit): Unit = if (cond) { body ; whileLoop(cond)(body) } else {} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -903,7 +903,7 @@ def whileLoop(cond: => Boolean)(body: => Unit): Unit = ## Do Loop Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= `do' Expr [semi] `while' `(' Expr ')' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -914,7 +914,7 @@ A semicolon preceding the `while` symbol of a do loop expression is ignored. ## For Comprehensions and For Loops -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= `for' (`(' Enumerators `)' | `{' Enumerators `}') {nl} [`yield'] Expr Enumerators ::= Generator {semi Enumerator} @@ -946,7 +946,7 @@ The translation scheme is as follows. In a first step, every generator `$p$ <- $e$`, where $p$ is not [irrefutable](#patterns) for the type of $e$ is replaced by -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $p$ <- $e$.withFilter { case $p$ => true; case _ => false } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -963,7 +963,7 @@ comprehensions have been eliminated. `$e$.foreach { case $p$ => $e'$ }`. - A for comprehension - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for ($p$ <- $e$; $p'$ <- $e'; \ldots$) yield $e''$ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -971,13 +971,13 @@ comprehensions have been eliminated. sequence of generators, definitions, or guards, is translated to - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $e$.flatMap { case $p$ => for ($p'$ <- $e'; \ldots$) yield $e''$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - A for loop - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for ($p$ <- $e$; $p'$ <- $e'; \ldots$) $e''$ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -985,7 +985,7 @@ comprehensions have been eliminated. sequence of generators, definitions, or guards, is translated to - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $e$.foreach { case $p$ => for ($p'$ <- $e'; \ldots$) $e''$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -998,7 +998,7 @@ comprehensions have been eliminated. `$p'$ = $e'$` is translated to the following generator of pairs of values, where $x$ and $x'$ are fresh names: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ($p$, $p'$) <- for ($x @ p$ <- $e$) yield { val $x' @ p'$ = $e'$; ($x$, $x'$) } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1006,7 +1006,7 @@ comprehensions have been eliminated. (@) The following code produces all pairs of numbers between $1$ and $n-1$ whose sums are prime. - ~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~ for { i <- 1 until n j <- 1 until i if isPrime(i+j) @@ -1015,7 +1015,7 @@ comprehensions have been eliminated. The for comprehension is translated to: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (1 until n) .flatMap { case i => (1 until i) @@ -1029,7 +1029,7 @@ comprehensions have been eliminated. <!-- see test/files/run/t0421.scala --> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def transpose[A](xss: Array[Array[A]]) = { for (i <- Array.range(0, xss(0).length)) yield for (xs <- xss) yield xs(i) @@ -1038,7 +1038,7 @@ comprehensions have been eliminated. Here is a function to compute the scalar product of two vectors: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def scalprod(xs: Array[Double], ys: Array[Double]) = { var acc = 0.0 for ((x, y) <- xs zip ys) acc = acc + x * y @@ -1049,7 +1049,7 @@ comprehensions have been eliminated. Finally, here is a function to compute the product of two matrices. Compare with the imperative version of \ref{ex:imp-mat-mul}. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { val ysst = transpose(yss) for (xs <- xss) yield @@ -1065,7 +1065,7 @@ comprehensions have been eliminated. ## Return Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= `return' [Expr] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1103,7 +1103,7 @@ and will propagate up the call stack. ## Throw Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= `throw' Expr ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1121,7 +1121,7 @@ is `scala.Nothing`. ## Try Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr1 ::= `try' `{' Block `}' [`catch' `{' CaseClauses `}'] [`finally' Expr] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1130,7 +1130,7 @@ A try expression is of the form `try { $b$ } catch $h$` where the handler $h$ is a [pattern matching anonymous function](#pattern-matching-anonymous-functions) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1176,7 +1176,7 @@ for `try { try { $b$ } catch $e_1$ } finally $e_2$`. ## Anonymous Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr ::= (Bindings | [`implicit'] id | `_') `=>' Expr ResultExpr ::= (Bindings | ([`implicit'] id | `_') `:' CompoundType) `=>' Block Bindings ::= `(' Binding {`,' Binding} `)' @@ -1204,7 +1204,7 @@ type which does not refer to any of the formal parameters $x_i$. The anonymous function is evaluated as the instance creation expression -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ new scala.Function$n$[$T_1 , \ldots , T_n$, $T$] { def apply($x_1$: $T_1 , \ldots , x_n$: $T_n$): $T$ = $e$ } @@ -1229,7 +1229,7 @@ anonymous functions always have to be given explicitly. (@) Examples of anonymous functions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ x => x // The identity function f => g => x => f(g(x)) // Curried function composition @@ -1248,7 +1248,7 @@ anonymous functions always have to be given explicitly. ### Placeholder Syntax for Anonymous Functions -~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~ SimpleExpr1 ::= `_' ~~~~~~~~~~~~~~~~~~~~~~ @@ -1276,12 +1276,12 @@ $e'$ results from $e$ by replacing each underscore section $u_i$ by $u_i'$. syntax. Each of these is equivalent to the anonymous function on its right. --------------------------- ------------------------------------ - `_ + 1`{.scala} `x => x + 1`{.scala} - `_ * _`{.scala} `(x1, x2) => x1 * x2`{.scala} - `(_: Int) * 2`{.scala} `(x: Int) => (x: Int) * 2`{.scala} - `if (_) x else y`{.scala} `z => if (z) x else y`{.scala} - `_.map(f)`{.scala} `x => x.map(f)`{.scala} - `_.map(_ + 1)`{.scala} `x => x.map(y => y + 1)`{.scala} + `_ + 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)` --------------------------- ------------------------------------ @@ -1304,7 +1304,7 @@ include at least the expressions of the following forms: ## Statements -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BlockStat ::= Import | {Annotation} [`implicit'] Def | {Annotation} {LocalModifier} TmplDef @@ -1361,7 +1361,7 @@ is applied to pick a unique member. _Type Instantiation_ \ An expression $e$ of polymorphic type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]$T$ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1526,7 +1526,7 @@ alternatives in $\mathscr{B}$. (@) Consider the following definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class A extends B {} def f(x: B, y: B) = $\ldots$ def f(x: A, y: B) = $\ldots$ @@ -1538,7 +1538,7 @@ alternatives in $\mathscr{B}$. definition of $f$ whereas the application `f(a, a)` refers to the second. Assume now we add a third overloaded definition - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def f(x: B, y: A) = $\ldots$ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1640,14 +1640,14 @@ any one of them. (@) Consider the two methods: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def cons[A](x: A, xs: List[A]): List[A] = x :: xs def nil[B]: List[B] = Nil ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and the definition - ~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~ val xs = cons(1, nil) ~~~~~~~~~~~~~~~~~~~~~~ @@ -1663,7 +1663,7 @@ any one of them. itself polymorphic. One tries to type-check `nil` with an expected type `List[a]`. This leads to the constraint system - ~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~ List[b?] <: List[a] ~~~~~~~~~~~~~~~~~~~~ @@ -1672,14 +1672,14 @@ any one of them. Because class `List` is covariant, the optimal solution of this constraint is - ~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~ b = scala.Nothing ~~~~~~~~~~~~~~~~~~ In a second step, one solves the following constraint system for the type parameter `a` of `cons`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Int <: a? List[scala.Nothing] <: List[a?] List[a?] <: $\mbox{\sl undefined}$ @@ -1687,7 +1687,7 @@ any one of them. The optimal solution of this constraint system is - ~~~~~~~~ {.scala} + ~~~~~~~~ a = Int ~~~~~~~~ @@ -1696,7 +1696,7 @@ any one of them. (@) Consider now the definition - ~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~ val ys = cons("abc", xs) ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1714,7 +1714,7 @@ any one of them. In a second step, one solves the following constraint system for the type parameter `a` of `cons`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ String <: a? List[Int] <: List[a?] List[a?] <: $\mbox{\sl undefined}$ @@ -1722,7 +1722,7 @@ any one of them. The optimal solution of this constraint system is - ~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~ a = scala.Any ~~~~~~~~~~~~~~ @@ -1742,7 +1742,7 @@ corresponding fresh name $x_i$. Second, one creates a fresh name $y_i$ for every argument type $T_i$ of the method ($i = 1 , \ldots , n$). The result of eta-conversion is then: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { val $x_1$ = $e_1$; $\ldots$ val $x_m$ = $e_m$; @@ -1755,7 +1755,7 @@ n$). The result of eta-conversion is then: The standard Scala library defines a trait `scala.Dynamic` which defines a member \@invokeDynamic@ as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala trait Dynamic { def applyDynamic (name: String, args: Any*): Any @@ -1766,14 +1766,14 @@ trait Dynamic { Assume a selection of the form $e.x$ where the type of $e$ conforms to `scala.Dynamic`. Further assuming the selection is not followed by any function arguments, such an expression can be rewitten under the conditions given [here](#implicit-conversions) to: -~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~ $e$.applyDynamic("$x$") ~~~~~~~~~~~~~~~~~~~~~~~~ If the selection is followed by some arguments, e.g.\ $e.x(\mathit{args})$, then that expression is rewritten to -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $e$.applyDynamic("$x$", $\mathit{args}$) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/09-implicit-parameters-and-views.md b/09-implicit-parameters-and-views.md index cdbafd9ca4..f943ae211a 100644 --- a/09-implicit-parameters-and-views.md +++ b/09-implicit-parameters-and-views.md @@ -2,7 +2,7 @@ ## The Implicit Modifier -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LocalModifier ::= ‘implicit’ ParamClauses ::= {ParamClause} [nl] ‘(’ ‘implicit’ Params ‘)’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -10,14 +10,14 @@ ParamClauses ::= {ParamClause} [nl] ‘(’ ‘implicit’ Params ‘)’ Template members and parameters labeled with an `implicit` modifier can be passed to [implicit parameters](#implicit-parameters) and can be used as implicit conversions called [views](#views). -The `implicit`{.scala} modifier is illegal for all +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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class Monoid[A] extends SemiGroup[A] { def unit: A def add(x: A, y: A): A @@ -38,7 +38,7 @@ type members, as well as for [top-level objects](#packagings). ## Implicit Parameters An implicit parameter list -`(implicit $p_1$,$\ldots$,$p_n$)`{.scala} of a method marks the parameters $p_1 , \ldots , p_n$ as +`(implicit $p_1$,$\ldots$,$p_n$)` of a method marks the parameters $p_1 , \ldots , p_n$ as implicit. A method or constructor can have only one implicit parameter list, and it must be the last parameter list given. @@ -57,7 +57,7 @@ identifier may thus be a local name, or a member of an enclosing template, or it may be have been made accessible without a prefix through an [import clause](#import-clauses). If there are no eligible identifiers under this rule, then, second, eligible are also all -`implicit`{.scala} members of some object that belongs to the implicit +`implicit` members of some object that belongs to the implicit scope of the implicit parameter's type, $T$. The _implicit scope_ of a type $T$ consists of all @@ -68,13 +68,13 @@ _associated_ with a type $T$, if it is a [base class](#class-linearization) of some part of $T$. The _parts_ of a type $T$ are: -* if $T$ is a compound type `$T_1$ with $\ldots$ with $T_n$`{.scala}, the +* if $T$ is a compound type `$T_1$ with $\ldots$ with $T_n$`, the union of the parts of $T_1 , \ldots , T_n$, as well as $T$ itself, * if $T$ is a parameterized type `$S$[$T_1 , \ldots , T_n$]`, the union of the parts of $S$ and $T_1 , \ldots , T_n$, -* if $T$ is a singleton type `$p$.type`{.scala}, the parts of the type +* if $T$ is a singleton type `$p$.type`, the parts of the type of $p$, -* if $T$ is a type projection `$S$#$U$`{.scala}, the parts of $S$ as +* if $T$ is a type projection `$S$#$U$`, the parts of $S$ as well as $T$ itself, * in all other cases, just $T$ itself. @@ -89,7 +89,7 @@ be found the default argument is used. method which computes the sum of a list of elements using the monoid's `add` and `unit` operations. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def sum[A](xs: List[A])(implicit m: Monoid[A]): A = if (xs.isEmpty) m.unit else m.add(xs.head, sum(xs.tail)) @@ -97,7 +97,7 @@ be found the default argument is used. 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))`{.scala} + 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 @@ -111,10 +111,10 @@ any type arguments are [inferred](#local-type-inference). Implicit methods can themselves have implicit parameters. An example is the following method from module `scala.List`, which injects -lists into the `scala.Ordered`{.scala} class, provided the element +lists into the `scala.Ordered` class, provided the element type of the list is also convertible to this type. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ implicit def list2ordered[A](x: List[A]) (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = ... @@ -122,28 +122,28 @@ implicit def list2ordered[A](x: List[A]) Assume in addition a method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ implicit def int2ordered(x: Int): Ordered[Int] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ that injects integers into the `Ordered` class. We can now define a `sort` method over ordered lists: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def sort[A](xs: List[A])(implicit a2ordered: A => Ordered[A]) = ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We can apply `sort` to a list of lists of integers -`yss: List[List[Int]]`{.scala} +`yss: List[List[Int]]` as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sort(yss) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The call above will be completed by passing two nested implicit arguments: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sort(yss)(xs: List[Int] => list2ordered[Int](xs)(int2ordered)) . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -152,7 +152,7 @@ raises the possibility of an infinite recursion. For instance, one might try to define the following method, which injects _every_ type into the `Ordered` class: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ implicit def magic[A](x: A)(implicit a2ordered: A => Ordered[A]): Ordered[A] = a2ordered(x) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -162,7 +162,7 @@ Now, if one tried to apply another injection into the `Ordered` class, one would obtain an infinite expansion: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sort(arg)(x => magic(x)(x => magic(x)(x => ... ))) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -214,7 +214,7 @@ the type: the sequence of types for which implicit arguments are searched is - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ List[List[Int]] => Ordered[List[List[Int]]], List[Int] => Ordered[List[Int]] Int => Ordered[Int] @@ -228,7 +228,7 @@ the type: (@) Let `ys` be a list of some type which cannot be converted to `Ordered`. For instance: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val ys = List(new IllegalArgumentException, new ClassCastException, new Error) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -288,7 +288,7 @@ or the call-by-name category). (@impl-ordered) Class `scala.Ordered[A]` contains a method - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def <= [B >: A](that: B)(implicit b2ordered: B => Ordered[B]): Boolean . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -303,7 +303,7 @@ or the call-by-name category). is legal, and is expanded to: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ list2ordered(xs)(int2ordered).<= (ys) (xs => list2ordered(xs)(int2ordered)) @@ -317,7 +317,7 @@ or the call-by-name category). ## Context Bounds and View Bounds -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] {‘<%’ Type} {‘:’ Type} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -337,13 +337,13 @@ A method or class containing type parameters with view or context bounds is trea equivalent to a method with implicit parameters. Consider first the case of a single parameter with view and/or context bounds such as: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def $f$[$A$ <% $T_1$ ... <% $T_m$ : $U_1$ : $U_n$]($\mathit{ps}$): $R$ = ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Then the method definition above is expanded to -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def $f$[$A$]($\mathit{ps}$)(implicit $v_1$: $A$ => $T_1$, ..., $v_m$: $A$ => $T_m$, $w_1$: $U_1$[$A$], ..., $w_n$: $U_n$[$A$]): $R$ = ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -363,7 +363,7 @@ additional implicit parameters. (@) The `<=` method mentioned in \ref{ex:impl-ordered} can be declared more concisely as follows: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def <= [B >: A <% Ordered[B]](that: B): Boolean ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -376,7 +376,7 @@ standard library contains a hierarchy of four manifest classes, with `OptManifest` at the top. Their signatures follow the outline below. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait OptManifest[+T] object NoManifest extends OptManifest[Nothing] trait ClassManifest[T] extends OptManifest[T] diff --git a/10-pattern-matching.md b/10-pattern-matching.md index b3c1db3499..e55003187a 100644 --- a/10-pattern-matching.md +++ b/10-pattern-matching.md @@ -2,7 +2,7 @@ ## Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pattern ::= Pattern1 { ‘|’ Pattern1 } Pattern1 ::= varid ‘:’ TypePat | ‘_’ ‘:’ TypePat @@ -38,7 +38,7 @@ than once in a pattern. 1. The pattern `(x, _)` matches pairs of values, binding `x` to the first component of the pair. The second component is matched with a wildcard pattern. - 1. The pattern `x :: y :: xs`{.scala} matches lists of length $\geq 2$, + 1. The pattern `x :: y :: xs` matches lists of length $\geq 2$, binding `x` to the list's first element, `y` to the list's second element, and `xs` to the remainder. 1. The pattern `1 | 2 | 3` matches the integers between 1 and 3. @@ -49,7 +49,7 @@ than once in a pattern. ### Variable Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimplePattern ::= `_' | varid ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -63,7 +63,7 @@ which is treated as if it was a fresh variable on each occurrence. ### Typed Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pattern1 ::= varid `:' TypePat | `_' `:' TypePat ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -77,7 +77,7 @@ that value. ### Pattern Binders -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pattern2 ::= varid `@' Pattern3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -89,7 +89,7 @@ and it binds the variable name to that value. ### Literal Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimplePattern ::= Literal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -99,7 +99,7 @@ expected type of the pattern. ### Stable Identifier Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimplePattern ::= StableId ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -115,7 +115,7 @@ backquotes; then it is treated as a stable identifier pattern. (@) Consider the following function definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def f(x: Int, y: Int) = x match { case y => ... } @@ -125,7 +125,7 @@ backquotes; then it is treated as a stable identifier pattern. If we wanted to turn the pattern into a stable identifier pattern, this can be achieved as follows: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def f(x: Int, y: Int) = x match { case `y` => ... } @@ -137,7 +137,7 @@ backquotes; then it is treated as a stable identifier pattern. ### Constructor Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimplePattern ::= StableId `(' [Patterns] `) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -163,18 +163,18 @@ repeated parameter. This is further discussed [here](#pattern-sequences). ### Tuple Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimplePattern ::= `(' [Patterns] `)' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A tuple pattern `($p_1 , \ldots , p_n$)` is an alias for the constructor pattern `scala.Tuple$n$($p_1 , \ldots , p_n$)`, where $n \geq 2$. The empty tuple -`()`{.scala} is the unique value of type `scala.Unit`{.scala}. +`()` is the unique value of type `scala.Unit`. ### Extractor Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimplePattern ::= StableId `(' [Patterns] `)' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -214,7 +214,7 @@ This case is further discussed [here](#pattern-seqs). (@) The `Predef` object contains a definition of an extractor object `Pair`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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) @@ -225,7 +225,7 @@ This case is further discussed [here](#pattern-seqs). formation as well as for deconstruction of tuples in patterns. Hence, the following is possible: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val x = (1, 2) val y = x match { case Pair(i, s) => Pair(s + i, i * i) @@ -234,7 +234,7 @@ This case is further discussed [here](#pattern-seqs). ### Pattern Sequences -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SimplePattern ::= StableId `(' [Patterns `,'] [varid `@'] `_' `*' `)' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -262,7 +262,7 @@ p_n$. ### Infix Operation Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pattern3 ::= SimplePattern {id [nl] SimplePattern} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -277,7 +277,7 @@ shorthand for the constructor or extractor pattern $\mathit{op}(p, q_1 ### Pattern Alternatives -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pattern ::= Pattern1 { `|' Pattern1 } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -320,7 +320,7 @@ A pattern $p$ is _irrefutable_ for a type $T$, if one of the following applies: ## Type Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TypePat ::= Type ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -457,7 +457,7 @@ are inferred in the same way as for the typed pattern (@) Consider the program fragment: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val x: Any x match { case y: List[a] => ... @@ -473,7 +473,7 @@ are inferred in the same way as for the typed pattern On the other hand, if `x` is declared as - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val x: List[List[String]], ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -485,7 +485,7 @@ are inferred in the same way as for the typed pattern (@) Consider the program fragment: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val x: Any x match { case y: List[String] => ... @@ -506,7 +506,7 @@ are inferred in the same way as for the typed pattern (@) Consider the program fragment - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Term[A] class Number(val n: Int) extends Term[Int] def f[B](t: Term[B]): B = t match { @@ -529,7 +529,7 @@ are inferred in the same way as for the typed pattern ## Pattern Matching Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expr ::= PostfixExpr `match' `{' CaseClauses `}' CaseClauses ::= CaseClause {CaseClause} CaseClause ::= `case' Pattern [Guard] `=>' Block @@ -537,7 +537,7 @@ are inferred in the same way as for the typed pattern A pattern matching expression -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ e match { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -607,7 +607,7 @@ possibility of a `MatchError` being raised at run-time. (@eval) Consider the following definitions of arithmetic terms: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract class Term[T] case class Lit(x: Int) extends Term[Int] case class Succ(t: Term[Int]) extends Term[Int] @@ -623,7 +623,7 @@ possibility of a `MatchError` being raised at run-time. A type-safe evaluator for such terms can be written as follows. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def eval[T](t: Term[T]): T = t match { case Lit(n) => n case Succ(u) => eval(u) + 1 @@ -646,13 +646,13 @@ possibility of a `MatchError` being raised at run-time. ## Pattern Matching Anonymous Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BlockExpr ::= `{' CaseClauses `}' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ An anonymous function can be defined by a sequence of cases -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -666,7 +666,7 @@ $R$ may be undetermined. If the expected type is `scala.Function$k$[$S_1 , \ldots , S_k$, $R$]`, the expression is taken to be equivalent to the anonymous function: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ($x_1: S_1 , \ldots , x_k: S_k$) => ($x_1 , \ldots , x_k$) match { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ } @@ -677,7 +677,7 @@ As was shown [here](#anonymous-functions), this anonymous function is in turn equivalent to the following instance creation expression, where $T$ is the weak least upper bound of the types of all $b_i$. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ new scala.Function$k$[$S_1 , \ldots , S_k$, $T$] { def apply($x_1: S_1 , \ldots , x_k: S_k$): $T$ = ($x_1 , \ldots , x_k$) match { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ @@ -688,7 +688,7 @@ new scala.Function$k$[$S_1 , \ldots , S_k$, $T$] { If the expected type is `scala.PartialFunction[$S$, $R$]`, the expression is taken to be equivalent to the following instance creation expression: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ new scala.PartialFunction[$S$, $T$] { def apply($x$: $S$): $T$ = x match { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ @@ -709,7 +709,7 @@ already a variable or wildcard pattern. `/:` to compute the scalar product of two vectors: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def scalarProduct(xs: Array[Double], ys: Array[Double]) = (0.0 /: (xs zip ys)) { case (a, (b, c)) => a + b * c @@ -719,7 +719,7 @@ already a variable or wildcard pattern. The case clauses in this code are equivalent to the following anonymous function: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (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 3229037fbf..215e16c426 100644 --- a/11-top-level-definitions.md +++ b/11-top-level-definitions.md @@ -2,7 +2,7 @@ ## Compilation Units -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CompilationUnit ::= {‘package’ QualId semi} TopStatSeq TopStatSeq ::= TopStat {semi TopStat} TopStat ::= {Annotation} {Modifier} TmplDef @@ -19,7 +19,7 @@ package clause. A compilation unit -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package $p_1$; $\ldots$ package $p_n$; @@ -30,7 +30,7 @@ starting with one or more package clauses is equivalent to a compilation unit consisting of the packaging -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package $p_1$ { $\ldots$ package $p_n$ { $\mathit{stats}$ @@ -46,7 +46,7 @@ that order hide members of an earlier import. ## Packagings -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -55,17 +55,17 @@ objects and packages. Unlike other objects, packages are not introduced by a definition. Instead, the set of members of a package is determined by packagings. -A packaging `package $p$ { $\mathit{ds}$ }`{.scala} injects all +A packaging `package $p$ { $\mathit{ds}$ }` injects all definitions in $\mathit{ds}$ as members into the package whose qualified name is $p$. Members of a package are called _top-level_ definitions. -If a definition in $\mathit{ds}$ is labeled `private`{.scala}, it is +If a definition in $\mathit{ds}$ is labeled `private`, it is visible only for other members in the package. Inside the packaging, all members of package $p$ are visible under their simple names. However this rule does not extend to members of enclosing packages of $p$ that are designated by a prefix of the path $p$. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package org.net.prj { ... } @@ -88,7 +88,7 @@ are visible to each other without qualification. ## Package Objects -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PackageObject ::= ‘package’ ‘object’ ObjectDef ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -107,7 +107,7 @@ future version of Scala. ## Package References -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ QualId ::= id {‘.’ id} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -121,7 +121,7 @@ outermost root package which contains all top-level packages. (@package-ids) Consider the following program: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package b { class B } @@ -157,7 +157,7 @@ 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`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package test object HelloWorld { def main(args: Array[String]) { println("Hello World") } @@ -181,7 +181,7 @@ which executes the initializaton code of the object $m$. `HelloWorld` can also be defined without a `main` method by inheriting from `App` instead: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 b1f1a8f813..4d4ed87169 100644 --- a/12-xml-expressions-and-patterns.md +++ b/12-xml-expressions-and-patterns.md @@ -12,7 +12,7 @@ XML expressions are expressions generated by the following production, where the opening bracket `<' of the first element must be in a position to start the lexical [XML mode](#xml-mode). -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XmlExpr ::= XmlContent {Element} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -28,7 +28,7 @@ are changed. Scala does not support declarations, CDATA sections or processing instructions. Entity references are not resolved at runtime. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Element ::= EmptyElemTag | STag Content ETag @@ -44,7 +44,7 @@ XmlContent ::= Element | CDSect | PI | Comment -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If an XML expression is a single element, its value is a runtime representation of an XML node (an instance of a subclass of @@ -62,7 +62,7 @@ and consecutive occurrences of whitespace are replaced by a single space character \\u0020. This behavior can be changed to preserve all whitespace with a compiler option. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Attribute ::= Name Eq AttValue AttValue ::= ‘"’ {CharQ | CharRef} ‘"’ @@ -82,7 +82,7 @@ within XML text as generated by CharData, it must be doubled. Thus, ‘{{’ represents the XML text ‘{’ and does not introduce an embedded Scala expression. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BaseChar, Char, Comment, CombiningChar, Ideographic, NameChar, S, Reference ::= $\mbox{\rm\em “as in W3C XML”}$ @@ -104,7 +104,7 @@ XML patterns are patterns generated by the following production, where the opening bracket ‘<’ of the element patterns must be in a position to start the lexical [XML mode](#xml-mode). -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ XmlPattern ::= ElementPattern ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -126,7 +126,7 @@ and consecutive occurrences of whitespace are replaced by a single space character \\u0020. This behavior can be changed to preserve all whitespace with a compiler option. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ElemPattern ::= EmptyElemTagP | STagP ContentP ETagP diff --git a/13-user-defined-annotations.md b/13-user-defined-annotations.md index 4397ebdef2..1aa5e7e613 100644 --- a/13-user-defined-annotations.md +++ b/13-user-defined-annotations.md @@ -1,6 +1,6 @@ # User-Defined Annotations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Annotation ::= ‘@’ SimpleType {ArgumentExprs} ConstrAnnotation ::= ‘@’ SimpleType ArgumentExprs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -20,7 +20,7 @@ does not matter. Examples: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @serializable class C { ... } // A class annotation. @transient @volatile var m: Int // A variable annotation String @local // A type annotation @@ -55,7 +55,7 @@ Java platform, the following annotations have a standard meaning. This is equivalent to a the following field definition in Java: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private final static SerialVersionUID = <longlit> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -95,7 +95,7 @@ Java platform, the following annotations have a standard meaning. matches which would otherwise be emitted. For instance, no warnings would be produced for the method definition below. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def f(x: Option[Int]) = (x: @unchecked) match { case Some(y) => y } @@ -110,7 +110,7 @@ Java platform, the following annotations have a standard meaning. value to appear in a path, even if its type is [volatile](#volatile-types). For instance, the following member definitions are legal: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ type A { type T } type B @uncheckedStable val x: A with B // volatile type @@ -135,7 +135,7 @@ Java platform, the following annotations have a standard meaning. For instance, the following code would generate specialized traits for `Unit`, `Int` and `Double` - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trait Function0[@specialized(Unit, Int, Double) T] { def apply: T } diff --git a/14-the-scala-standard-library.md b/14-the-scala-standard-library.md index 2ba846e3f4..b6fd1ceb77 100644 --- a/14-the-scala-standard-library.md +++ b/14-the-scala-standard-library.md @@ -37,7 +37,7 @@ class for objects). The signatures of these root classes are described by the following definitions. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala /** The universal root class */ abstract class Any { @@ -91,7 +91,7 @@ trait ScalaObject extends AnyRef The type test `$x$.isInstanceOf[$T$]` is equivalent to a typed pattern match -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $x$ match { case _: $T'$ => true case _ => false @@ -216,7 +216,7 @@ type. If this is true, it will perform the `==` operation which is appropriate for that type. That is, the `equals` method of a numeric value type can be thought of being defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def equals(other: Any): Boolean = other match { case that: Byte => this == that case that: Short => this == that @@ -238,7 +238,7 @@ floating point number. (@) As an example, here is the signature of the numeric value type `Int`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala abstract sealed class Int extends AnyVal { def == (that: Double): Boolean // double equality @@ -291,7 +291,7 @@ Class `Boolean` has only two values: `true` and `false`. It implements operations as given in the following class definition. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala abstract sealed class Boolean extends AnyVal { def && (p: => Boolean): Boolean = // boolean and @@ -347,7 +347,7 @@ class of the underlying host system (and may be identified with it). For Scala clients the class is taken to support in each case a method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def + (that: Any): String ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -359,7 +359,7 @@ right operand. Scala defines tuple classes `Tuple$n$` for $n = 2 , \ldots , 9$. These are defined as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala case class Tuple$n$[+A_1, ..., +A_n](_1: A_1, ..., _$n$: A_$n$) { def toString = "(" ++ _1 ++ "," ++ $\ldots$ ++ "," ++ _$n$ ++ ")" @@ -375,7 +375,7 @@ as an alias for `Tuple3`. Scala defines function classes `Function$n$` for $n = 1 , \ldots , 9$. These are defined as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala trait Function$n$[-A_1, ..., -A_$n$, +B] { def apply(x_1: A_1, ..., x_$n$: A_$n$): B @@ -389,7 +389,7 @@ which are undefined on some points in their domain. In addition to the `isDefined` method, which tells whether the function is defined at the given argument: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class PartialFunction[-A, +B] extends Function1[A, B] { def isDefinedAt(x: A): Boolean } @@ -402,7 +402,7 @@ The implicitly imported [`Predef`](#the-predef-object) object defines the name The class of generic arrays is given as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ final class Array[A](len: Int) extends Seq[A] { def length: Int = len def apply(i: Int): A = $\ldots$ @@ -454,7 +454,7 @@ However, it is possible to cast an expression of type `Array[String]` to `Array[Object]`, and this cast will succeed without raising a `ClassCastException`. Example: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val xs = new Array[String](2) // val ys: Array[Object] = xs // **** error: incompatible types val ys: Array[Object] = xs.asInstanceOf[Array[Object]] // OK @@ -467,7 +467,7 @@ from `isInstanceOf` and `asInstanceOf` still work as if the array used the standard representation of monomorphic arrays: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ val ss = new Array[String](2) def f[T](xs: Array[T]): Array[String] = @@ -483,7 +483,7 @@ following implementation of method `mkArray`, which creates an array of an arbitrary type $T$, given a sequence of $T$'s which defines its elements. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def mkArray[T](elems: Seq[T]): Array[T] = { val result = new Array[T](elems.length) var i = 0 @@ -510,7 +510,7 @@ constructor methods for arrays, as well as the [extractor method](#extractor-patterns) `unapplySeq` which enables pattern matching over arrays. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala object Array { /** copies array elements from `src' to `dest'. */ @@ -548,7 +548,7 @@ object Array { (@) The following method duplicates a given argument array and returns a pair consisting of the original and the duplicate: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def duplicate[T](xs: Array[T]) = { val ys = new Array[T](xs.length) Array.copy(xs, 0, ys, 0, xs.length) @@ -559,7 +559,7 @@ object Array { ## Class Node -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala.xml trait Node { @@ -638,7 +638,7 @@ for Scala programs. It is always implicitly imported, so that all its defined members are available without qualification. Its definition for the JVM environment conforms to the following signature: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ package scala object Predef { @@ -715,7 +715,7 @@ object Predef { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // tupling --------------------------------------------------------- @@ -787,7 +787,7 @@ The available high-priority implicits include definitions falling into the follo * An implicit wrapper that adds `ensuring` methods with the following overloaded variants to type `Any`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def ensuring(cond: Boolean): A = { assert(cond); x } def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x } def ensuring(cond: A => Boolean): A = { assert(cond(x)); x } @@ -797,7 +797,7 @@ The available high-priority implicits include definitions falling into the follo * An implicit wrapper that adds a `->` method with the following implementation to type `Any`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def -> [B](y: B): (A, B) = (x, y) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -811,7 +811,7 @@ The available high-priority implicits include definitions falling into the follo * An implicit wrapper that adds `+` and `formatted` method with the following implementations to type `Any`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def +(other: String) = String.valueOf(self) + other def formatted(fmtstr: String): String = fmtstr format self ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -845,7 +845,7 @@ The available high-priority implicits include definitions falling into the follo * An implicit definition that generates instances of type `T <:< T`, for any type `T`. Here, `<:<` is a class defined as follows. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sealed abstract class <:<[-From, +To] extends (From => To) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/15-scala-syntax-summary.md b/15-scala-syntax-summary.md index 2b880069b9..33cd29c09c 100644 --- a/15-scala-syntax-summary.md +++ b/15-scala-syntax-summary.md @@ -5,7 +5,7 @@ The lexical syntax of Scala is given by the following grammar in EBNF form. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ upper ::= ‘A’ | … | ‘Z’ | ‘\$’ | ‘_’ // and Unicode category Lu lower ::= ‘a’ | … | ‘z’ // and Unicode category Ll letter ::= upper | lower // and Unicode categories Lo, Lt, Nl @@ -61,7 +61,7 @@ semi ::= ‘;’ | nl {nl} The context-free syntax of Scala is given by the following EBNF grammar. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Literal ::= [‘-’] integerLiteral | [‘-’] floatingPointLiteral | booleanLiteral |