diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-10 16:58:12 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-10 16:58:12 -0700 |
commit | b44c5980ac2f1e330acd522badabb01f5eb50c06 (patch) | |
tree | d8a128c8ce8a46c46d2b468e6b51b33113a971b4 | |
parent | 9dec37b50be3288822b9c7c0cb5c4d263f3d05e7 (diff) | |
download | scala-b44c5980ac2f1e330acd522badabb01f5eb50c06.tar.gz scala-b44c5980ac2f1e330acd522badabb01f5eb50c06.tar.bz2 scala-b44c5980ac2f1e330acd522badabb01f5eb50c06.zip |
github markdown: code blocks
-rw-r--r-- | 03-lexical-syntax.md | 144 | ||||
-rw-r--r-- | 04-identifiers-names-and-scopes.md | 12 | ||||
-rw-r--r-- | 05-types.md | 140 | ||||
-rw-r--r-- | 06-basic-declarations-and-definitions.md | 184 | ||||
-rw-r--r-- | 07-classes-and-objects.md | 188 | ||||
-rw-r--r-- | 08-expressions.md | 304 | ||||
-rw-r--r-- | 09-implicit-parameters-and-views.md | 84 | ||||
-rw-r--r-- | 10-pattern-matching.md | 128 | ||||
-rw-r--r-- | 11-top-level-definitions.md | 48 | ||||
-rw-r--r-- | 12-xml-expressions-and-patterns.md | 24 | ||||
-rw-r--r-- | 13-user-defined-annotations.md | 24 | ||||
-rw-r--r-- | 14-the-scala-standard-library.md | 100 | ||||
-rw-r--r-- | 15-scala-syntax-summary.md | 8 | ||||
-rw-r--r-- | README.md | 4 |
14 files changed, 696 insertions, 696 deletions
diff --git a/03-lexical-syntax.md b/03-lexical-syntax.md index 0bbf47fc80..7f4614f387 100644 --- a/03-lexical-syntax.md +++ b/03-lexical-syntax.md @@ -11,10 +11,10 @@ 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` UnicodeEscape ::= \{\\}u{u} hexDigit hexDigit hexDigit hexDigit hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` To construct tokens, characters are distinguished according to the following classes (Unicode general category given in parentheses): @@ -35,7 +35,7 @@ classes (Unicode general category given in parentheses): ## Identifiers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` op ::= opchar {opchar} varid ::= lower idrest plainid ::= upper idrest @@ -44,7 +44,7 @@ plainid ::= upper idrest id ::= plainid | ‘`’ stringLit ‘`’ idrest ::= {letter | digit} [‘_’ op] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` There are three ways to form an identifier. First, an identifier can start with a letter which can be followed by an arbitrary sequence of @@ -60,9 +60,9 @@ of all characters excluding the backquotes themselves. As usual, a longest match rule applies. For instance, the string -~~~~~~~~~~~~~~~~ +``` big_bob++=`def` -~~~~~~~~~~~~~~~~ +``` decomposes into the three identifiers `big_bob`, `++=`, and `def`. The rules for pattern matching further distinguish between @@ -76,7 +76,7 @@ identifiers which contain ‘\$’ characters. The following names are reserved words instead of being members of the syntactic class `id` of lexical identifiers. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` abstract case catch class def do else extends false final finally for forSome if implicit @@ -86,18 +86,18 @@ return sealed super this throw trait try true type val var while with yield _ : = => <- <: <% >: # @ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The Unicode operators \\u21D2 ‘$\Rightarrow$’ and \\u2190 ‘$\leftarrow$’, which have the ASCII equivalents ‘=>’ and ‘<-’, are also reserved. (@) Here are examples of identifiers: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` x Object maxIndex p2p empty_? + `yield` αρετη _y dot_product_* __system _MAX_LEN_ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) Backquote-enclosed strings are a solution when one needs to access Java identifiers that are reserved words in Scala. For @@ -108,9 +108,9 @@ equivalents ‘=>’ and ‘<-’, are also reserved. ## Newline Characters -~~~~~~~~~~~~~~~~~~~~~~~~ +``` semi ::= ‘;’ | nl {nl} -~~~~~~~~~~~~~~~~~~~~~~~~ +``` Scala is a line-oriented language where statements may be terminated by semi-colons or newlines. A newline in a Scala source text is treated @@ -123,19 +123,19 @@ as the special token “nl” if the three following criteria are satisfied: The tokens that can terminate a statement are: literals, identifiers and the following delimiters and reserved words: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` this null true false return type <xml-start> _ ) ] } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The tokens that can begin a statement are all Scala tokens _except_ the following delimiters and reserved words: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` catch else extends finally forSome match with yield , . ; : = => <- <: <% >: # [ ) ] } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A `case` token can begin a statement only if followed by a `class` or `object` token. @@ -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. - ~~~~~~~~~~~~~~~~~~~~~~ + ``` if (x > 0) x = x - 1 @@ -214,23 +214,23 @@ A single new line token is accepted type IntList = List[Int] - ~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) The following code designates an anonymous class: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` new Iterator[Int] { private var x = 0 def hasNext = true def next = { x += 1; x } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` With an additional newline character, the same code is interpreted as an object creation followed by a local block: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` new Iterator[Int] { @@ -238,56 +238,56 @@ A single new line token is accepted def hasNext = true def next = { x += 1; x } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) The following code designates a single expression: - ~~~~~~~~~~~~ + ``` x < 0 || x > 10 - ~~~~~~~~~~~~ + ``` With an additional newline character, the same code is interpreted as two expressions: - ~~~~~~~~~~~ + ``` x < 0 || x > 10 - ~~~~~~~~~~~ + ``` (@) The following code designates a single, curried function definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def func(x: Int) (y: Int) = x + y - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` With an additional newline character, the same code is interpreted as an abstract function definition and a syntactically illegal statement: - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def func(x: Int) (y: Int) = x + y - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) The following code designates an attributed definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` @serializable protected class Data { ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` With an additional newline character, the same code is interpreted as an attribute and a separate statement (which is syntactically illegal). - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` @serializable protected class Data { ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Literals @@ -301,7 +301,7 @@ each case as in Java. particular float and double. --> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Literal ::= [‘-’] integerLiteral | [‘-’] floatingPointLiteral | booleanLiteral @@ -309,12 +309,12 @@ Literal ::= [‘-’] integerLiteral | stringLiteral | symbolLiteral | ‘null’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Integer Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` integerLiteral ::= (decimalNumeral | hexNumeral | octalNumeral) [‘L’ | ‘l’] decimalNumeral ::= ‘0’ | nonZeroDigit {digit} @@ -323,7 +323,7 @@ octalNumeral ::= ‘0’ octalDigit {octalDigit} digit ::= ‘0’ | nonZeroDigit nonZeroDigit ::= ‘1’ | … | ‘9’ octalDigit ::= ‘0’ | … | ‘7’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Integer literals are usually of type `Int`, or of type `Long` when followed by a `L` or @@ -347,21 +347,21 @@ is _pt_. The numeric ranges given by these types are: (@) Here are some integer literals: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` 0 21 0xFFFFFFFF 0777L - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Floating Point Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` floatingPointLiteral ::= digit {digit} ‘.’ {digit} [exponentPart] [floatType] | ‘.’ digit {digit} [exponentPart] [floatType] | digit {digit} exponentPart [floatType] | digit {digit} [exponentPart] floatType exponentPart ::= (‘E’ | ‘e’) [‘+’ | ‘-’] digit {digit} floatType ::= ‘F’ | ‘f’ | ‘D’ | ‘d’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Floating point literals are of type `Float` when followed by a floating point type suffix `F` or `f`, and are @@ -376,9 +376,9 @@ whitespace character between the two tokens. (@) Here are some floating point literals: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` 0.0 1e30f 3.14159f 1.0e-100 .1 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) The phrase `1.toString` parses as three different tokens: `1`, `.`, and `toString`. On the @@ -389,9 +389,9 @@ whitespace character between the two tokens. ### Boolean Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` booleanLiteral ::= ‘true’ | ‘false’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The boolean literals `true` and `false` are members of type `Boolean`. @@ -399,10 +399,10 @@ members of type `Boolean`. ### Character Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` characterLiteral ::= ‘'’ printableChar ‘'’ | ‘'’ charEscapeSeq ‘'’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A character literal is a single character enclosed in quotes. The character is either a printable unicode character or is described @@ -410,9 +410,9 @@ by an [escape sequence](#escape-sequences). (@) Here are some character literals: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` 'a' '\u0041' '\n' '\t' - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Note that `'\u000A'` is _not_ a valid character literal because Unicode conversion is done before literal parsing and the Unicode @@ -423,10 +423,10 @@ the octal escape `'\12'` ([see here](#escape-sequences)). ### String Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` stringLiteral ::= ‘\"’ {stringElement} ‘\"’ stringElement ::= printableCharNoDoubleQuote | charEscapeSeq -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A string literal is a sequence of characters in double quotes. The characters are either printable unicode character or are described by @@ -437,17 +437,17 @@ class `String`. (@) Here are some string literals: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` "Hello,\nWorld!" "This string contains a \" character." - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` #### Multi-Line String Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` stringLiteral ::= ‘"""’ multiLineChars ‘"""’ multiLineChars ::= {[‘"’] [‘"’] charNoDoubleQuote} {‘"’} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A multi-line string literal is a sequence of characters enclosed in triple quotes `""" ... """`. The sequence of characters is @@ -459,37 +459,37 @@ of the escape sequences [here](#escape-sequences) are interpreted. (@) Here is a multi-line string literal: - ~~~~~~~~~~~~~~~~~~~~~~~~ + ``` """the present string spans three lines.""" - ~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This would produce the string: - ~~~~~~~~~~~~~~~~~~~ + ``` the present string spans three lines. - ~~~~~~~~~~~~~~~~~~~ + ``` The Scala library contains a utility method `stripMargin` which can be used to strip leading whitespace from multi-line strings. The expression -~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` """the present string spans three lines.""".stripMargin -~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` evaluates to -~~~~~~~~~~~~~~~~~~~~ +``` the present string spans three lines. -~~~~~~~~~~~~~~~~~~~~ +``` Method `stripMargin` is defined in class [scala.collection.immutable.StringLike](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringLike). @@ -524,20 +524,20 @@ string literal does not start a valid escape sequence. ### Symbol literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` symbolLiteral ::= ‘'’ plainid -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala final case class Symbol private (name: String) { override def toString: String = "'" + name } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The `apply` method of `Symbol`'s companion object caches weak references to `Symbol`s, thus ensuring that @@ -568,11 +568,11 @@ 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ( whitespace | ‘(’ | ‘{’ ) ‘<’ (XNameStart | ‘!’ | ‘?’) XNameStart ::= ‘_’ | BaseChar | Ideographic // as in W3C XML, but without ‘:’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The scanner switches from XML mode to Scala mode if either @@ -591,11 +591,11 @@ as text. (@) The following value definition uses an XML literal with two embedded Scala expressions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val b = <book> <title>The Scala Language Specification</title> <version>{scalaBook.version}</version> <authors>{scalaBook.authors.mkList("", ", ", "")}</authors> </book> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` diff --git a/04-identifiers-names-and-scopes.md b/04-identifiers-names-and-scopes.md index e4b92d2a8b..a102043691 100644 --- a/04-identifiers-names-and-scopes.md +++ b/04-identifiers-names-and-scopes.md @@ -31,11 +31,11 @@ scopes. Note that shadowing is only a partial order. In a situation like -~~~~~~~~~~~~~~ +``` val x = 1; { import p.x; x } -~~~~~~~~~~~~~~ +``` neither binding of `x` shadows the other. Consequently, the reference to `x` in the third line above would be ambiguous. @@ -57,7 +57,7 @@ of the referenced entity. (@) Assume the following two definitions of a objects named `X` in packages `P` and `Q`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` package P { object X { val x = 1; val y = 2 } } @@ -65,12 +65,12 @@ of the referenced entity. package Q { object X { val x = true; val y = "" } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The following program illustrates different kinds of bindings and precedences between them. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` package P { // `X' bound by package clause import Console._ // `println' bound by wildcard import object A { @@ -92,7 +92,7 @@ of the referenced entity. // println("L19: "+y) // reference to `y' is ambiguous here println("L20: "+x) // `x' refers to string ``abc'' here }}}}}} - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` A reference to a qualified (type- or term-) identifier $e.x$ refers to the member of the type $T$ of $e$ which has the name $x$ in the same diff --git a/05-types.md b/05-types.md index 03be174d75..9dd5ed9690 100644 --- a/05-types.md +++ b/05-types.md @@ -1,6 +1,6 @@ # Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Type ::= FunctionArgTypes ‘=>’ Type | InfixType [ExistentialClause] FunctionArgTypes ::= InfixType @@ -20,7 +20,7 @@ | ‘(’ Types ‘)’ TypeArgs ::= ‘[’ Types ‘]’ Types ::= Type {‘,’ Type} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` We distinguish between first-order types and type constructors, which take type parameters and yield types. A subset of first-order types @@ -60,14 +60,14 @@ the corresponding anonymous type function directly. ## Paths -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Path ::= StableId | [id ‘.’] this StableId ::= id | Path ‘.’ id | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id ClassQualifier ::= ‘[’ id ‘]’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Paths are not types themselves, but they can be a part of named types and in that function form a central role in Scala's type system. @@ -97,9 +97,9 @@ forms. ### Singleton Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleType ::= Path ‘.’ type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A singleton type is of the form `$p$.type`, where $p$ is a path pointing to a value expected to [conform](#expression-typing) @@ -111,9 +111,9 @@ declared to be a subtype of trait `scala.Singleton`. ### Type Projection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleType ::= SimpleType ‘#’ id -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A type projection `$T$#$x$` references the type member named $x$ of type $T$. @@ -126,9 +126,9 @@ If $x$ references an abstract type member, then $T$ must be a ### Type Designators -~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleType ::= StableId -~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A type designator refers to a named value type. It can be simple or qualified. All such type designators are shorthands for type projections. @@ -157,10 +157,10 @@ equivalent to the type projection `p.type#t`. ### Parameterized Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleType ::= SimpleType TypeArgs TypeArgs ::= ‘[’ Types ‘]’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A parameterized type $T[ U_1 , \ldots , U_n ]$ consists of a type designator $T$ and type parameters $U_1 , \ldots , U_n$ where @@ -175,7 +175,7 @@ substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. (@param-types) Given the partial type definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class TreeMap[A <: Comparable[A], B] { … } class List[A] { … } class I extends Comparable[I] { … } @@ -183,23 +183,23 @@ substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. class F[M[_], X] { … } class S[K <: String] { … } class G[M[ Z <: I ], I] { … } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` the following parameterized types are well formed: - ~~~~~~~~~~~~~~~~~~~~~~ + ``` TreeMap[I, String] List[I] List[List[Boolean]] F[List, Int] G[S, String] - ~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) Given the type definitions of (@param-types), the following types are ill-formed: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` TreeMap[I] // illegal: wrong number of parameters TreeMap[List[I], Int] // illegal: type parameter not within bound @@ -210,13 +210,13 @@ substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. // conform to String, // G expects type constructor with a parameter // that conforms to Int - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Tuple Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleType ::= ‘(’ Types ‘)’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A tuple type $(T_1 , \ldots , T_n)$ is an alias for the class `scala.Tuple$_n$[$T_1$, … , $T_n$]`, where $n \geq 2$. @@ -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). -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` case class Tuple$n$[+T1, … , +$T_n$](_1: T1, … , _n: $T_n$) extends Product_n[T1, … , $T_n$] @@ -238,13 +238,13 @@ trait Product_n[+T1, … , +$T_n$] { … def _n: $T_n$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Annotated Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` AnnotType ::= SimpleType {Annotation} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An annotated type $T$ `$a_1 , \ldots , a_n$` attaches [annotations](#user-defined-annotations) @@ -253,21 +253,21 @@ $a_1 , \ldots , a_n$ to the type $T$. (@) The following type adds the `@suspendable` annotation to the type `String`: - ~~~~~~~~~~~~~~~~~~~~ + ``` String @suspendable - ~~~~~~~~~~~~~~~~~~~~ + ``` ### Compound Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement] | Refinement Refinement ::= [nl] ‘{’ RefineStat {semi RefineStat} ‘}’ RefineStat ::= Dcl | ‘type’ TypeDef | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A compound type `$T_1$ with … with $T_n$ { $R$ }` represents objects with members as given in the component types @@ -300,7 +300,7 @@ equivalent to `AnyRef{ R }`. (@) The following example shows how to declare and use a function which parameter's type contains a refinement with structural declarations. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` case class Bird (val name: String) extends Object { def fly(height: Int) = … … @@ -320,7 +320,7 @@ equivalent to `AnyRef{ R }`. val a380 = new Plane("TZ-987") takeoff(42, bird) takeoff(89, a380) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Although `Bird` and `Plane` do not share any parent class other than `Object`, the parameter _r_ of function `takeoff` is defined using a @@ -330,9 +330,9 @@ equivalent to `AnyRef{ R }`. ### Infix Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` InfixType ::= CompoundType {id [nl] CompoundType} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An infix type `$T_1$ \mathit{op} $T_2$` consists of an infix operator $\mathit{op}$ which gets applied to two type operands $T_1$ and @@ -359,11 +359,11 @@ $t_0 \mathit{op_1} (t_1 \mathit{op_2} ( \ldots \mathit{op_n} t_n) \ldots)$. ### Function Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Type ::= FunctionArgs ‘=>’ Type FunctionArgs ::= InfixType | ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The type $(T_1 , \ldots , T_n) \Rightarrow U$ represents the set of function values that take arguments of types $T1 , \ldots , Tn$ and yield @@ -382,26 +382,26 @@ $(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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala trait Function_n[-T1 , … , -T$_n$, +R] { def apply(x1: T1 , … , x$_n$: T$_n$): R override def toString = "<function>" } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Hence, function types are [covariant](#variance-annotations) in their result type and contravariant in their argument types. ### Existential Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Type ::= InfixType ExistentialClauses ExistentialClauses ::= ‘forSome’ ‘{’ ExistentialDcl {semi ExistentialDcl} ‘}’ ExistentialDcl ::= ‘type’ TypeDcl | ‘val’ ValDcl -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An existential type has the form `$T$ forSome { $Q$ }` where $Q$ is a sequence of @@ -464,9 +464,9 @@ fresh type name and $T'$ results from $T$ by replacing every occurrence of #### Placeholder Syntax for Existential Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` WildcardType ::= ‘_’ TypeBounds -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Scala supports a placeholder syntax for existential types. A _wildcard type_ is of the form `_$\;$>:$\,L\,$<:$\,U$`. Both bound @@ -484,9 +484,9 @@ $T$ is a wildcard type `_$\;$>:$\,L\,$<:$\,U$`. Then $T$ is equivalent to the existential type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $p.c[\mathit{targs},t,\mathit{targs}']$ forSome { type $t$ >: $L$ <: $U$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` where $t$ is some fresh type variable. Wildcard types may also appear as parts of [infix types](#infix-types) @@ -497,49 +497,49 @@ type. (@) Assume the class definitions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class Ref[T] abstract class Outer { type T } . - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here are some examples of existential types: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Ref[T] forSome { type T <: java.lang.Number } Ref[x.T] forSome { val x: Outer } Ref[x_type # T] forSome { type x_type <: Outer with Singleton } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The last two types in this list are equivalent. An alternative formulation of the first type above using wildcard syntax is: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Ref[_ <: java.lang.Number] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) The type `List[List[_]]` is equivalent to the existential type - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` List[List[t] forSome { type t }] . - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) Assume a covariant type - ~~~~~~~~~~~~~~~ + ``` class List[+T] - ~~~~~~~~~~~~~~~ + ``` The type - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` List[T] forSome { type T <: java.lang.Number } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` is equivalent (by simplification rule 4 above) to - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` List[java.lang.Number] forSome { type T <: java.lang.Number } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` which is in turn equivalent (by simplification rules 2 and 3 above) to `List[java.lang.Number]`. @@ -575,19 +575,19 @@ corresponding function type. (@) The declarations - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def a: Int def b (x: Int): Boolean def c (x: Int) (y: String, z: String): String - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` produce the typings - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` a: => Int b: (Int) Boolean c: (Int) (String, String) String - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Polymorphic Method Types @@ -603,17 +603,17 @@ take type arguments `$S_1 , \ldots , S_n$` which (@) The declarations - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def empty[A]: List[A] def union[A <: Comparable[A]] (x: Set[A], xs: Set[A]): Set[A] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` produce the typings - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` empty : [A >: Nothing <: Any] List[A] union : [A >: Nothing <: Comparable[A]] (x: Set[A], xs: Set[A]) Set[A] . - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Type Constructors @@ -626,11 +626,11 @@ the corresponding type parameter clause. (@) Consider this fragment of the `Iterable[+X]` class: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait Iterable[+X] { def flatMap[newType[+X] <: Iterable[X], S](f: X => newType[S]): newType[S] } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Conceptually, the type constructor `Iterable` is a name for the anonymous type `[+X] Iterable[X]`, which may be passed to the @@ -884,11 +884,11 @@ are understood to be relative to that order. > of a set of types does not always exist. For instance, consider > the class definitions -~~~~~~~~~~~~~~~~~~~~~ +``` class A[+T] {} class B extends A[B] class C extends A[C] -~~~~~~~~~~~~~~~~~~~~~ +``` > Then the types `A[Any], A[A[Any]], A[A[A[Any]]], ...` form > a descending sequence of upper bounds for `B` and `C`. The @@ -920,14 +920,14 @@ to a type $T$, written $S <:_w T$, if $S <: T$ or both $S$ and $T$ are primitive number types and $S$ precedes $T$ in the following ordering. -~~~~~~~~~~~~~~~~~~~~ +``` Byte $<:_w$ Short Short $<:_w$ Int Char $<:_w$ Int Int $<:_w$ Long Long $<:_w$ Float Float $<:_w$ Double -~~~~~~~~~~~~~~~~~~~~ +``` A _weak least upper bound_ is a least upper bound with respect to weak conformance. diff --git a/06-basic-declarations-and-definitions.md b/06-basic-declarations-and-definitions.md index accf4400a1..21a3956916 100644 --- a/06-basic-declarations-and-definitions.md +++ b/06-basic-declarations-and-definitions.md @@ -1,7 +1,7 @@ # Basic Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Dcl ::= ‘val’ ValDcl | ‘var’ VarDcl | ‘def’ FunDcl @@ -12,7 +12,7 @@ Def ::= PatVarDef | ‘def’ FunDef | ‘type’ {nl} TypeDef | TmplDef -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A _declaration_ introduces names and assigns them types. It can form part of a [class definition](#templates) or of a @@ -37,13 +37,13 @@ between and including $s_i$ and $s_j$, ## Value Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Dcl ::= ‘val’ ValDcl ValDcl ::= ids ‘:’ Type PatVarDef ::= ‘val’ PatDef PatDef ::= Pattern2 {‘,’ Pattern2} [‘:’ Type] ‘=’ Expr ids ::= id {‘,’ id} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A value declaration `val $x$: $T$` introduces $x$ as a name of a value of type $T$. @@ -63,9 +63,9 @@ its right hand side $e$ the first time the value is accessed. A _constant value definition_ is of the form -~~~~~~~~~~~~~~~~ +``` final val x = e -~~~~~~~~~~~~~~~~ +``` where `e` is a [constant expression](#constant-expressions). The `final` modifier must be @@ -80,45 +80,45 @@ 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$: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` val $\$ x$ = $e$ match {case $p$ => ($x_1 , \ldots , x_n$)} val $x_1$ = $\$ x$._1 $\ldots$ val $x_n$ = $\$ x$._n . -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Here, $\$ x$ is a fresh name. 2. If $p$ has a unique bound variable $x$: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` val $x$ = $e$ match { case $p$ => $x$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 3. If $p$ has no bound variables: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $e$ match { case $p$ => ()} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` (@) The following are examples of value definitions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val pi = 3.1415 val pi: Double = 3.1415 // equivalent to first definition val Some(x) = f() // a pattern definition val x :: xs = mylist // an infix pattern definition - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The last two definitions have the following expansions. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val x = f() match { case Some(x) => x } val x$\$$ = mylist match { case x :: xs => (x, xs) } val x = x$\$$._1 val xs = x$\$$._2 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The name of any declared or defined value may not end in `_=`. @@ -133,22 +133,22 @@ sequence of value definitions `val $p_1: T$ = $e$; ...; val $p_n: T$ = $e$`. ## Variable Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Dcl ::= ‘var’ VarDcl PatVarDef ::= ‘var’ VarDef VarDcl ::= ids ‘:’ Type VarDef ::= PatDef | ids ‘:’ Type ‘=’ ‘_’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A variable declaration `var $x$: $T$` is equivalent to declarations of a _getter function_ $x$ and a _setter function_ `$x$_=`, defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def $x$: $T$ def $x$_= ($y$: $T$): Unit -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An implementation of a class containing variable declarations may define these variables using variable definitions, or it may @@ -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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class TimeOfDayVar { private var h: Int = 0 private var m: Int = 0 @@ -222,7 +222,7 @@ a template member. val d = new TimeOfDayVar d.hours = 8; d.minutes = 30; d.seconds = 0 d.hours = 25 // throws a DateError exception - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` A variable declaration `var $x_1 , \ldots , x_n$: $T$` is a shorthand for the @@ -237,12 +237,12 @@ the sequence of variable definitions <!-- TODO: Higher-kinded tdecls should have a separate section --> -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Dcl ::= ‘type’ {nl} TypeDcl TypeDcl ::= id [TypeParamClause] [‘>:’ Type] [‘<:’ Type] Def ::= type {nl} TypeDef TypeDef ::= id [TypeParamClause] ‘=’ Type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A _type declaration_ `type $t$[$\mathit{tps}\,$] >: $L$ <: $U$` declares $t$ to be an abstract type with lower bound type $L$ and upper bound @@ -285,16 +285,16 @@ an abstract type is directly or indirectly its own upper or lower bound. (@) The following are legal type declarations and definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` type IntList = List[Integer] type T <: Comparable[T] type Two[A] = Tuple2[A, A] type MyCollection[+X] <: Iterable[X] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The following are illegal: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` type Abs = Comparable[Abs] // recursive type alias type S <: T // S, T are bounded by themselves. @@ -304,7 +304,7 @@ an abstract type is directly or indirectly its own upper or lower bound. // T is a type, not a value type MyCollection <: Iterable // Type constructor members must explicitly // state their type parameters. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` If a type alias `type $t$[$\mathit{tps}\,$] = $S$` refers to a class type $S$, the name $t$ can also be used as a constructor for @@ -313,30 +313,30 @@ objects of type $S$. (@) The `Predef` object contains a definition which establishes `Pair` as an alias of the parameterized class `Tuple2`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` type Pair[+A, +B] = Tuple2[A, B] object Pair { def apply[A, B](x: A, y: B) = Tuple2(x, y) def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` As a consequence, for any two types $S$ and $T$, the type `Pair[$S$, $T\,$]` is equivalent to the type `Tuple2[$S$, $T\,$]`. `Pair` can also be used as a constructor instead of `Tuple2`, as in: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val x: Pair[Int, String] = new Pair(1, "abc") - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Type Parameters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’ VariantTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeParam TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] [‘:’ Type] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Type parameters appear in type definitions, class definitions, and function definitions. In this section we consider only type parameter @@ -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: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` [S, T] [@specialized T, U] [Ex <: Throwable] @@ -381,16 +381,16 @@ The above scoping restrictions are generalized to the case of nested type parame [M[_], N[_]] // equivalent to previous clause [M[X <: Bound[X]], Bound[_]] [M[+X] <: Iterable[X]] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The following type parameter clauses are illegal: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` [A >: A] // illegal, `A' has itself as bound [A <: B, B <: C, C <: A] // illegal, `A' has itself as bound [A, B, C >: A <: B] // illegal lower bound `A' of `C' does // not conform to upper bound `B'. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Variance Annotations @@ -444,67 +444,67 @@ appear anywhere without restricting its legal variance annotations. (@) The following variance annotation is legal. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class P[+A, +B] { def fst: A; def snd: B } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` With this variance annotation, type instances of $P$ subtype covariantly with respect to their arguments. For instance, - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` P[IOException, String] <: P[Throwable, AnyRef] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` If the members of $P$ are mutable variables, the same variance annotation becomes illegal. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class Q[+A, +B](x: A, y: B) { var fst: A = x // **** error: illegal variance: var snd: B = y // `A', `B' occur in invariant position. } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` If the mutable variables are object-private, the class definition becomes legal again: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class R[+A, +B](x: A, y: B) { private[this] var fst: A = x // OK private[this] var snd: B = y // OK } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) The following variance annotation is illegal, since $a$ appears in contravariant position in the parameter of `append`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class Sequence[+A] { def append(x: Sequence[A]): Sequence[A] // **** error: illegal variance: // `A' occurs in contravariant position. } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The problem can be avoided by generalizing the type of `append` by means of a lower bound: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class Sequence[+A] { def append[B >: A](x: Sequence[B]): Sequence[B] } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) Here is a case where a contravariant type parameter is useful. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class OutputChannel[-A] { def write(x: A): Unit } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` With that annotation, we have that `OutputChannel[AnyRef]` conforms to `OutputChannel[String]`. @@ -515,7 +515,7 @@ appear anywhere without restricting its legal variance annotations. ## Function Declarations and Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Dcl ::= ‘def’ FunDcl FunDcl ::= FunSig ‘:’ Type Def ::= ‘def’ FunDef @@ -529,7 +529,7 @@ Param ::= {Annotation} id [‘:’ ParamType] [‘=’ Expr] ParamType ::= Type | ‘=>’ Type | Type ‘*’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A function declaration has the form `def $f\,\mathit{psig}$: $T$`, where $f$ is the function's name, $\mathit{psig}$ is its parameter @@ -581,27 +581,27 @@ be pairwise distinct. (@) In the method - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def compare[T](a: T = 0)(b: T = a) = (a == b) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` the default expression `0` is type-checked with an undefined expected type. When applying `compare()`, the default value `0` is inserted and `T` is instantiated to `Int`. The methods computing the default arguments have the form: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def compare$\$$default$\$$1[T]: Int = 0 def compare$\$$default$\$$2[T](a: T): T = a - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### By-Name Parameters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ParamType ::= ‘=>’ Type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The type of a value parameter may be prefixed by `=>`, e.g.\ `$x$: => $T$`. The type of such a parameter is then the @@ -618,9 +618,9 @@ by-name modifier is also disallowed for (@) The declaration - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def whileLoop (cond: => Boolean) (stat: => Unit): Unit - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` indicates that both parameters of `whileLoop` are evaluated using call-by-name. @@ -628,9 +628,9 @@ by-name modifier is also disallowed for ### Repeated Parameters -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ParamType ::= Type ‘*’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The last value parameter of a parameter section may be suffixed by “*”, e.g. `(..., $x$:$T$*)`. The type of such a @@ -656,49 +656,49 @@ with a repeated parameter. (@) The following method definition computes the sum of the squares of a variable number of integer arguments. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def sum(args: Int*) = { var result = 0 for (arg <- args) result += arg * arg result } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The following applications of this method yield `0`, `1`, `6`, in that order. - ~~~~~~~~~~~~~~~~~ + ``` sum() sum(1) sum(1, 2, 3) - ~~~~~~~~~~~~~~~~~ + ``` Furthermore, assume the definition: - ~~~~~~~~~~~~~~~~~~~~~~~ + ``` val xs = List(1, 2, 3) - ~~~~~~~~~~~~~~~~~~~~~~~ + ``` The following application of method `sum` is ill-formed: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` sum(xs) // ***** error: expected: Int, found: List[Int] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` By contrast, the following application is well formed and yields again the result `6`: - ~~~~~~~~~~~~ + ``` sum(xs: _*) - ~~~~~~~~~~~~ + ``` ### Procedures -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` FunDcl ::= FunSig FunDef ::= FunSig [nl] ‘{’ Block ‘}’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Special syntax exists for procedures, i.e.\ functions that return the `Unit` value `()`. @@ -714,25 +714,25 @@ E.g., `def $f$($\mathit{ps}$) {$\mathit{stats}$}` is equivalent to (@) Here is a declaration and a definition of a procedure named `write`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait Writer { def write(str: String) } object Terminal extends Writer { def write(str: String) { System.out.println(str) } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The code above is implicitly completed to the following code: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait Writer { def write(str: String): Unit } object Terminal extends Writer { def write(str: String): Unit = { System.out.println(str) } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Method Return Type Inference @@ -748,14 +748,14 @@ as $R$ conforms to $R'$. (@) Assume the following definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait I { def factorial(x: Int): Int } class C extends I { def factorial(x: Int) = if (x == 0) 1 else x * factorial(x - 1) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here, it is OK to leave out the result type of `factorial` in `C`, even though the method is recursive. @@ -763,13 +763,13 @@ as $R$ conforms to $R'$. ## Import Clauses -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors) ImportSelectors ::= ‘{’ {ImportSelector ‘,’} (ImportSelector | ‘_’) ‘}’ ImportSelector ::= id [‘=>’ id | ‘=>’ ‘_’] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An import clause has the form `import $p$.$I$` where $p$ is a [stable identifier](#paths) and $I$ is an import expression. @@ -779,9 +779,9 @@ _importable_ if it is not [object-private](#modifiers). The most general form of an import expression is a list of {\em import selectors} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { $x_1$ => $y_1 , \ldots , x_n$ => $y_n$, _ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` for $n \geq 0$, where the final wildcard ‘_’ may be absent. It makes available each importable member `$p$.$x_i$` under the unqualified name @@ -829,21 +829,21 @@ sequence of import clauses (@) Consider the object definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` object M { def z = 0, one = 1 def add(x: Int, y: Int): Int = x + y } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Then the block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` { import M.{one, z => zero, _}; add(zero, one) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` is equivalent to the block - ~~~~~~~~~~~~~~~~~~~~~~ + ``` { M.add(M.z, M.one) } - ~~~~~~~~~~~~~~~~~~~~~~ + ``` diff --git a/07-classes-and-objects.md b/07-classes-and-objects.md index 4694c2eb13..12ad1f8d25 100644 --- a/07-classes-and-objects.md +++ b/07-classes-and-objects.md @@ -1,10 +1,10 @@ # Classes and Objects -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` TmplDef ::= [`case'] `class' ClassDef | [`case'] `object' ObjectDef | `trait' TraitDef -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` [Classes](#class-definitions) and [objects](#object-definitions) are both defined in terms of _templates_. @@ -12,7 +12,7 @@ are both defined in terms of _templates_. ## Templates -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ClassTemplate ::= [EarlyDefs] ClassParents [TemplateBody] TraitTemplate ::= [EarlyDefs] TraitParents [TemplateBody] ClassParents ::= Constr {`with' AnnotType} @@ -20,7 +20,7 @@ TraitParents ::= AnnotType {`with' AnnotType} TemplateBody ::= [nl] `{' [SelfType] TemplateStat {semi TemplateStat} `}' SelfType ::= id [`:' Type] `=>' | this `:' Type `=>' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A template defines the type signature, behavior and initial state of a trait or class of objects or of a single object. Templates form part of @@ -50,15 +50,15 @@ 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $sc$ with $mt_1$ with $\ldots$ with $mt_n$ { $\mathit{stats}$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` becomes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $mt_1$ with $\ldots$ with $mt_n$ with ScalaObject { $\mathit{stats}$ }. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The list of parents of a template must be well-formed. This means that the class denoted by the superclass constructor $sc$ must be a @@ -103,17 +103,17 @@ without introducing an alias name for it. (@) Consider the following class definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class Base extends Object {} trait Mixin extends Base {} object O extends Mixin {} - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` In this case, the definition of `O` is expanded to: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` object O extends Base with Mixin {} - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` <!-- TODO: Make all references to Java generic --> @@ -150,16 +150,16 @@ it. But templates inheriting the `scala.DelayedInit` trait can override the hook by re-implementing the `delayedInit` method, which is defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def delayedInit(body: => Unit) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Constructor Invocations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Constr ::= AnnotType {`(' [Exprs] `)'} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Constructor invocations define the type, members, and initial state of objects created by an instance creation expression, or of parts of an @@ -207,30 +207,30 @@ 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: > -> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +> ``` > \[ > \begin{array}{lcll} > \{a, A\} \;\vec{+}\; B &=& a, (A \;\vec{+}\; B) &{\bf if} \; a \not\in B \\ > &=& A \;\vec{+}\; B &{\bf if} \; a \in B > \end{array} > \] -> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +> ``` (@) Consider the following class definitions. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class AbsIterator extends AnyRef { ... } trait RichIterator extends AbsIterator { ... } class StringIterator extends AbsIterator { ... } class Iter extends StringIterator with RichIterator { ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Then the linearization of class `Iter` is - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` { Iter, RichIterator, StringIterator, AbsIterator, ScalaObject, AnyRef, Any } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Trait `ScalaObject` appears in this list because it is added as last mixin to every Scala class ( [see here](#templates) ). @@ -243,17 +243,17 @@ linearization of this graph is defined as follows. as a suffix. For instance, the linearization of `StringIterator` is - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` { StringIterator, AbsIterator, ScalaObject, AnyRef, Any } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` which is a suffix of the linearization of its subclass `Iter`. The same is not true for the linearization of mixins. For instance, the linearization of `RichIterator` is - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` { RichIterator, AbsIterator, ScalaObject, AnyRef, Any } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` which is not a suffix of the linearization of `Iter`. @@ -322,12 +322,12 @@ defined or inherited) with the same name which both define default arguments. (@) Consider the trait definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait A { def f: Int } trait B extends A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 } trait C extends A { override def f: Int = 4 ; def g: Int } trait D extends B with C { def h: Int } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Then trait `D` has a directly defined abstract member `h`. It inherits member `f` from trait `C` and member `g` from @@ -382,12 +382,12 @@ superclass (otherwise). (@compounda) Consider the definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait Root { type T <: Root } trait A extends Root { type T <: A } trait B extends Root { type T <: B } trait C extends A with B - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Then the class definition `C` is not well-formed because the binding of `T` in `C` is @@ -396,9 +396,9 @@ superclass (otherwise). in type `A`. The problem can be solved by adding an overriding definition of type `T` in class `C`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class C extends A with B { type T <: C } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Inheritance Closure @@ -418,21 +418,21 @@ necessary to make subtyping decidable [@kennedy-pierce:decidable]). ### Early Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` EarlyDefs ::= `{' [EarlyDef {semi EarlyDef}] `}' `with' EarlyDef ::= {Annotation} {Modifier} PatVarDef -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { val $p_1$: $T_1$ = $e_1$ ... val $p_n$: $T_n$ = $e_n$ } with $sc$ with $mt_1$ with $mt_n$ { $\mathit{stats}$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The initial pattern definitions of $p_1 , \ldots , p_n$ are called _early definitions_. They define fields @@ -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: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait Greeting { val name: String val msg = "How are you, "+name @@ -471,7 +471,7 @@ before the superclass constructor of the template is called. } with Greeting { println(msg) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` In the code above, the field `name` is initialized before the constructor of `Greeting` is called. Therefore, field `msg` in @@ -485,7 +485,7 @@ before the superclass constructor of the template is called. ## Modifiers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Modifier ::= LocalModifier | AccessModifier | `override' @@ -496,7 +496,7 @@ LocalModifier ::= `abstract' | `lazy' AccessModifier ::= (`private' | `protected') [AccessQualifier] AccessQualifier ::= `[' (id | `this') `]' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Member definitions may be preceded by modifiers which affect the accessibility and usage of the identifiers bound by them. If several @@ -626,7 +626,7 @@ the validity and meaning of a modifier are as follows. (@) The following code illustrates the use of qualified private: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` package outerpkg.innerpkg class Outer { class Inner { @@ -635,7 +635,7 @@ the validity and meaning of a modifier are as follows. private[outerpkg] def h() } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here, accesses to the method `f` can appear anywhere within `OuterClass`, but not outside it. Accesses to method @@ -650,24 +650,24 @@ the validity and meaning of a modifier are as follows. constructing new instances of that class is to declare the class `abstract` and `sealed`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` object m { abstract sealed class C (x: Int) { def nextC = new C(x + 1) {} } val empty = new C(0) {} } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` For instance, in the code above clients can create instances of class `m.C` only by calling the `nextC` method of an existing `m.C` object; it is not possible for clients to create objects of class `m.C` directly. Indeed the following two lines are both in error: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` new m.C(0) // **** error: C is abstract, so it cannot be instantiated. new m.C(0) {} // **** error: illegal inheritance from sealed class. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` A similar access restriction can be achieved by marking the primary constructor `private` (see \ref{ex:private-constr}). @@ -675,7 +675,7 @@ the validity and meaning of a modifier are as follows. ## Class Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` TmplDef ::= `class' ClassDef ClassDef ::= id [TypeParamClause] {Annotation} [AccessModifier] ClassParamClauses ClassTemplateOpt @@ -686,13 +686,13 @@ ClassParams ::= ClassParam {`,' ClassParam} ClassParam ::= {Annotation} [{Modifier} (`val' | `var')] id [`:' ParamType] [`=' Expr] ClassTemplateOpt ::= `extends' ClassTemplate | [[`extends'] TemplateBody] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The most general form of class definition is -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` class $c$[$\mathit{tps}\,$] $as$ $m$($\mathit{ps}_1$)$\ldots$($\mathit{ps}_n$) extends $t$ $\gap(n \geq 0)$. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Here, @@ -738,9 +738,9 @@ Here, [call-by-name parameter](#by-name-parameters). - $t$ is a [template](#templates) of the form - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` $sc$ with $mt_1$ with $\ldots$ with $mt_m$ { $\mathit{stats}$ } // $m \geq 0$ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` which defines the base classes, behavior and initial state of objects of the class. The extends clause @@ -759,16 +759,16 @@ $t$. (@) The following example illustrates `val` and `var` parameters of a class `C`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class C(x: Int, val y: String, var z: List[String]) val c = new C(1, "abc", List()) c.z = c.y :: c.z - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@privateconstr) The following class can be created only from its companion module. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` object Sensitive { def makeSensitive(credentials: Certificate): Sensitive = if (credentials == Admin) new Sensitive() @@ -777,19 +777,19 @@ $t$. class Sensitive private () { ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Constructor Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` FunDef ::= `this' ParamClause ParamClauses (`=' ConstrExpr | [nl] ConstrBlock) ConstrExpr ::= SelfInvocation | ConstrBlock ConstrBlock ::= `{' SelfInvocation {semi BlockStat} `}' SelfInvocation ::= `this' ArgumentExprs {ArgumentExprs} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A class may have additional constructors besides the primary constructor. These are defined by constructor definitions of the form @@ -834,7 +834,7 @@ primary constructor of the class). (@) Consider the class definition - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class LinkedList[A]() { var head = _ var tail = null @@ -842,7 +842,7 @@ primary constructor of the class). def this(head: A) = { this(); this.head = head } def this(head: A, tail: List[A]) = { this(head); this.tail = tail } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This defines a class `LinkedList` with three constructors. The second constructor constructs an singleton list, while the @@ -851,9 +851,9 @@ primary constructor of the class). ## Case Classes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` TmplDef ::= `case' `class' ClassDef -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` If a class definition is prefixed with `case`, the class is said to be a _case class_. @@ -871,14 +871,14 @@ parameters $\mathit{tps}$ and value parameters $\mathit{ps}$ implicitly generates an [extractor object](#extractor-patterns) which is defined as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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}\,$]) = if (x eq null) scala.None else scala.Some($x.\mathit{xs}_{11}, \ldots , x.\mathit{xs}_{1k}$) } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Here, $\mathit{Ts}$ stands for the vector of types defined in the type parameter section $\mathit{tps}$, @@ -896,9 +896,9 @@ 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def unapply[$\mathit{tps}\,$]($x$: $c$[$\mathit{tps}\,$]) = x ne null -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The name of the `unapply` method is changed to `unapplySeq` if the first parameter section $\mathit{ps}_1$ of $c$ ends in a @@ -911,9 +911,9 @@ 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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$) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Again, $\mathit{Ts}$ stands for the vector of types defined in the type parameter section $\mathit{tps}$ and each $\mathit{xs}_i$ denotes the parameter names of the parameter section $\mathit{ps}'_i$. Every value @@ -940,18 +940,18 @@ class different from `AnyRef`. In particular: (@) Here is the definition of abstract syntax for lambda calculus: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class Expr case class Var (x: String) extends Expr case class Apply (f: Expr, e: Expr) extends Expr case class Lambda(x: String, e: Expr) extends Expr - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This defines a class `Expr` with case classes `Var`, `Apply` and `Lambda`. A call-by-value evaluator for lambda expressions could then be written as follows. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` type Env = String => Value case class Value(e: Expr, env: Env) @@ -965,14 +965,14 @@ class different from `AnyRef`. In particular: case Lambda(_, _) => Value(e, env) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` It is possible to define further case classes that extend type `Expr` in other parts of the program, for instance - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` case class Number(x: Int) extends Expr - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This form of extensibility can be excluded by declaring the base class `Expr` `sealed`; in this case, all classes that @@ -982,11 +982,11 @@ class different from `AnyRef`. In particular: ### Traits -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` TmplDef ::= `trait' TraitDef TraitDef ::= id [TypeParamClause] TraitTemplateOpt TraitTemplateOpt ::= `extends' TraitTemplate | [[`extends'] TemplateBody] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A trait is a class that is meant to be added to some other class as a mixin. Unlike normal classes, traits cannot have @@ -1012,14 +1012,14 @@ least proper supertype (which is statically known). comparison operators `<=`, `>`, and `>=`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait Comparable[T <: Comparable[T]] { self: T => def < (that: T): Boolean def <=(that: T): Boolean = this < that || this == that def > (that: T): Boolean = that < this def >=(that: T): Boolean = that <= this } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) Consider an abstract class `Table` that implements maps from a type of keys `A` to a type of values `B`. The class @@ -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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class Table[A, B](defaultValue: B) { def get(key: A): Option[B] def set(key: A, value: B) @@ -1038,29 +1038,29 @@ least proper supertype (which is statically known). case None => defaultValue } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here is a concrete implementation of the `Table` class. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) { private var elems: List[(A, B)] def get(key: A) = elems.find(._1.==(key)).map(._2) def set(key: A, value: B) = { elems = (key, value) :: elems } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here is a trait that prevents concurrent access to the `get` and `set` operations of its parent class: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait SynchronizedTable[A, B] extends Table[A, B] { abstract override def get(key: A): B = synchronized { super.get(key) } abstract override def set((key: A, value: B) = synchronized { super.set(key, value) } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Note that `SynchronizedTable` does not pass an argument to its superclass, `Table`, even though `Table` is defined with a @@ -1074,9 +1074,9 @@ least proper supertype (which is statically known). table with strings as keys and integers as values and with a default value `0`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` object MyTable extends ListTable[String, Int](0) with SynchronizedTable - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The object `MyTable` inherits its `get` and `set` method from `SynchronizedTable`. The `super` calls in these @@ -1087,9 +1087,9 @@ least proper supertype (which is statically known). ## Object Definitions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ObjectDef ::= id ClassTemplate -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An object definition defines a single object of a new class. Its most general form is @@ -1097,9 +1097,9 @@ most general form is $m$ is the name of the object to be defined, and $t$ is a [template](#templates) of the form -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $sc$ with $mt_1$ with $\ldots$ with $mt_n$ { $\mathit{stats}$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` which defines the base classes, behavior and initial state of $m$. The extends clause `extends $sc$ with $mt_1$ with $\ldots$ with $mt_n$` @@ -1112,9 +1112,9 @@ 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` lazy val $m$ = new $sc$ with $mt_1$ with $\ldots$ with $mt_n$ { this: $m.type$ => $\mathit{stats}$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Note that the value defined by an object definition is instantiated lazily. The `new $m$\$cls` constructor is evaluated @@ -1135,7 +1135,7 @@ top-level objects are translated to static fields. effect can be achieved by an accompanying object definition E.g. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class Point { val x: Double val y: Double @@ -1144,7 +1144,7 @@ top-level objects are translated to static fields. object Point { val origin = new Point() { val x = 0.0; val y = 0.0 } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This defines a class `Point` and an object `Point` which contains `origin` as a member. Note that the double use of the diff --git a/08-expressions.md b/08-expressions.md index 18f5831f20..140dad39b9 100644 --- a/08-expressions.md +++ b/08-expressions.md @@ -1,6 +1,6 @@ # Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr ::= (Bindings | id | `_') `=>' Expr | Expr1 Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr] @@ -41,7 +41,7 @@ Ascription ::= `:' InfixType | `:' Annotation {Annotation} | `:' `_' `*' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expressions are composed of operators and operands. Expression forms are discussed subsequently in decreasing order of precedence. @@ -65,16 +65,16 @@ 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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $T$ forSome { type $t_1[\mathit{tps}_1] >: L_1 <: U_1$; $\ldots$; type $t_n[\mathit{tps}_n] >: L_n <: U_n$ }. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ## Literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= Literal -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Typing of literals is as described [here](#literals); their evaluation is immediate. @@ -102,10 +102,10 @@ A reference to any other member of the ``null'' object causes a ## Designators -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= Path | SimpleExpr `.' id -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A designator refers to a named term. It can be a _simple name_ or a _selection_. @@ -156,10 +156,10 @@ is thrown. ## This and Super -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= [id `.'] `this' | [id '.'] `super' [ClassQualifier] `.' id -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The expression `this` can appear in the statement part of a template or compound type. It stands for the object being defined by @@ -208,7 +208,7 @@ it must be concrete. (@super) Consider the following class definitions - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class Root { def x = "Root" } class A extends Root { override def x = "A" ; def superA = super.x } trait B extends Root { override def x = "B" ; def superB = super.x } @@ -218,17 +218,17 @@ it must be concrete. class D extends A with B { override def x = "D" ; def superD = super.x } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The linearization of class `C` is `{C, B, Root}` and the linearization of class `D` is `{D, B, A, Root}`. Then we have: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (new A).superA == "Root", (new C).superB = "Root", (new C).superC = "B", (new D).superA == "Root", (new D).superB = "A", (new D).superD = "B", - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Note that the `superB` function returns different results depending on whether `B` is mixed in with class `Root` or `A`. @@ -236,13 +236,13 @@ it must be concrete. ## Function Applications -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= SimpleExpr1 ArgumentExprs ArgumentExprs ::= `(' [Exprs] `)' | `(' [Exprs `,'] PostfixExpr `:' `_' `*' ')' | [nl] BlockExpr Exprs ::= Expr {`,' Expr} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An application `$f$($e_1 , \ldots , e_m$)` applies the function $f$ to the argument expressions $e_1 , \ldots , e_m$. If $f$ @@ -320,22 +320,22 @@ of the caller. (@) Assume the following function which computes the sum of a variable number of arguments: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def sum(xs: Int*) = (0 /: xs) ((x, y) => x + y) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Then - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` sum(1, 2, 3, 4) sum(List(1, 2, 3, 4): _*) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` both yield `10` as result. On the other hand, - ~~~~~~~~~~~~~~~~~~~~~~ + ``` sum(List(1, 2, 3, 4)) - ~~~~~~~~~~~~~~~~~~~~~~ + ``` would not typecheck. @@ -362,24 +362,24 @@ If the function $f$ has the form `$p.m$[$\mathit{targs}$]` it is transformed into the block -~~~~~~~~~~~~~~~~~~ +``` { val q = $p$ q.$m$[$\mathit{targs}$] } -~~~~~~~~~~~~~~~~~~ +``` 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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { val q = $p$ val $x_1$ = expr$_1$ $\ldots$ val $x_k$ = expr$_k$ q.$m$[$\mathit{targs}$]($\mathit{args}_1$)$, \ldots ,$($\mathit{args}_l$) } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` where every argument in $(\mathit{args}_1) , \ldots , (\mathit{args}_l)$ is a reference to one of the values $x_1 , \ldots , x_k$. To integrate the current application @@ -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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { val q = $p$ val $x_1$ = expr$_1$ $\ldots$ @@ -410,14 +410,14 @@ The final result of the transformation is a block of the form val $z_d$ = q.$m$\$default\$j[$\mathit{targs}$]($\mathit{args}_1$)$, \ldots ,$($\mathit{args}_l$) q.$m$[$\mathit{targs}$]($\mathit{args}_1$)$, \ldots ,$($\mathit{args}_l$)($\mathit{args}$) } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ## Method Values -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= SimpleExpr1 `_' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The expression ~`$e$ _`~ is well-formed if $e$ is of method type or if $e$ is a call-by-name parameter. If $e$ is a method with @@ -444,9 +444,9 @@ parameterlist `()`. ## Type Applications -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= SimpleExpr TypeArgs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A type application `$e$[$T_1 , \ldots , T_n$]` instantiates a polymorphic value $e$ of type @@ -471,9 +471,9 @@ and the expected result type. ## Tuples -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= `(' [Exprs] `)' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A tuple expression `($e_1 , \ldots , e_n$)` is an alias for the class instance creation @@ -484,9 +484,9 @@ The empty tuple ## Instance Creation Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr ::= `new' (ClassTemplate | TemplateBody) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A simple instance creation expression is of the form `new $c$` @@ -499,9 +499,9 @@ $T$. The concrete self type is normally $T$, except if the expression `new $c$` appears as the right hand side of a value definition -~~~~~~~~~~~~~~~~~~~~~~~ +``` val $x$: $S$ = new $c$ -~~~~~~~~~~~~~~~~~~~~~~~ +``` (where the type annotation `: $S$` may be missing). In the latter case, the concrete self type of the expression is the @@ -515,9 +515,9 @@ 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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { class $a$ extends $t$; new $a$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` where $a$ is a fresh name of an _anonymous class_ which is inaccessible to user programs. @@ -529,31 +529,31 @@ types: If `{$D$}` is a class body, then (@) Consider the following structural instance creation expression: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` new { def getName() = "aaron" } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This is a shorthand for the general instance creation expression - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` new AnyRef{ def getName() = "aaron" } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The latter is in turn a shorthand for the block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` { class anon\$X extends AnyRef{ def getName() = "aaron" }; new anon\$X } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` where `anon\$X` is some freshly created name. ## Blocks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` BlockExpr ::= `{' Block `}' Block ::= {BlockStat semi} [ResultExpr] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A block expression `{$s_1$; $\ldots$; $s_n$; $e\,$}` is constructed from a sequence of block statements $s_1 , \ldots , s_n$ @@ -595,16 +595,16 @@ $e$, which defines the result of the block. (@) Assuming a class `Ref[T](x: T)`, the block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` { class C extends B {$\ldots$} ; new Ref(new C) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` has the type `Ref[_1] forSome { type _1 <: B }`. The block - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` { class C extends B {$\ldots$} ; new C } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` simply has type `B`, because with the rules [here](#simplification-rules) the existentially quantified type @@ -613,12 +613,12 @@ $e$, which defines the result of the block. ## Prefix, Infix, and Postfix Operations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` PostfixExpr ::= InfixExpr [id [nl]] InfixExpr ::= PrefixExpr | InfixExpr id [nl] InfixExpr PrefixExpr ::= [`-' | `+' | `!' | `~'] SimpleExpr -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expressions can be constructed from operands and operators. @@ -654,7 +654,7 @@ The _precedence_ of an infix operator is determined by the operator's first character. Characters are listed below in increasing order of precedence, with characters on the same line having the same precedence. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $\mbox{\rm\sl(all letters)}$ | ^ @@ -665,7 +665,7 @@ $\mbox{\rm\sl(all letters)}$ + - * / % $\mbox{\rm\sl(all other special characters)}$ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` That is, operators starting with a letter have lowest precedence, followed by operators starting with ``|`', etc. @@ -728,9 +728,9 @@ operation `$l$ += $r$`, where $l$, $r$ are expressions. This operation can be re-interpreted as an operation which corresponds to the assignment -~~~~~~~~~~~~~~~~ +``` $l$ = $l$ + $r$ -~~~~~~~~~~~~~~~~ +``` except that the operation's left-hand-side $l$ is evaluated only once. @@ -748,9 +748,9 @@ The re-interpretation occurs if the following two conditions are fulfilled. ## Typed Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= PostfixExpr `:' CompoundType -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The typed expression $e: T$ has type $T$. The type of expression $e$ is expected to conform to $T$. The result of @@ -758,18 +758,18 @@ the expression is the value of $e$ converted to type $T$. (@) Here are examples of well-typed and illegally typed expressions. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` 1: Int // legal, of type Int 1: Long // legal, of type Long // 1: string // ***** illegal - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Annotated Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= PostfixExpr `:' Annotation {Annotation} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An annotated expression `$e$: @$a_1$ $\ldots$ @$a_n$` attaches [annotations](#user-defined-annotations) $a_1 , \ldots , a_n$ to the @@ -778,10 +778,10 @@ expression $e$. ## Assignments -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= [SimpleExpr `.'] id `=' Expr | SimpleExpr1 ArgumentExprs `=' Expr -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The interpretation of an assignment to a simple variable `$x$ = $e$` depends on the definition of $x$. If $x$ denotes a mutable @@ -811,7 +811,7 @@ the invocation of an `update` function defined by $f$. (@imp-mat-mul) Here is the usual imperative code for matrix multiplication. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { val zss: Array[Array[Double]] = new Array(xss.length, yss(0).length) var i = 0 @@ -831,12 +831,12 @@ the invocation of an `update` function defined by $f$. } zss } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Desugaring the array accesses and assignments yields the following expanded version: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { val zss: Array[Array[Double]] = new Array(xss.length, yss.apply(0).length) var i = 0 @@ -856,14 +856,14 @@ the invocation of an `update` function defined by $f$. } zss } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Conditional Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] `else' Expr] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The conditional expression `if ($e_1$) $e_2$ else $e_3$` chooses one of the values of $e_2$ and $e_3$, depending on the @@ -887,25 +887,25 @@ evaluated as if it was `if ($e_1$) $e_2$ else ()`. ## While Loop Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= `while' `(' Expr ')' {nl} Expr -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def whileLoop(cond: => Boolean)(body: => Unit): Unit = if (cond) { body ; whileLoop(cond)(body) } else {} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ## Do Loop Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= `do' Expr [semi] `while' `(' Expr ')' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The do loop expression `do $e_1$ while ($e_2$)` is typed and evaluated as if it was the expression `($e_1$ ; while ($e_2$) $e_1$)`. @@ -914,7 +914,7 @@ A semicolon preceding the `while` symbol of a do loop expression is ignored. ## For Comprehensions and For Loops -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= `for' (`(' Enumerators `)' | `{' Enumerators `}') {nl} [`yield'] Expr Enumerators ::= Generator {semi Enumerator} @@ -923,7 +923,7 @@ Enumerator ::= Generator | `val' Pattern1 `=' Expr Generator ::= Pattern1 `<-' Expr [Guard] Guard ::= `if' PostfixExpr -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A for loop `for ($\mathit{enums}\,$) $e$` executes expression $e$ for each binding generated by the enumerators $\mathit{enums}$. A for @@ -946,9 +946,9 @@ 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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $p$ <- $e$.withFilter { case $p$ => true; case _ => false } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Then, the following rules are applied repeatedly until all comprehensions have been eliminated. @@ -963,31 +963,31 @@ comprehensions have been eliminated. `$e$.foreach { case $p$ => $e'$ }`. - A for comprehension - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` for ($p$ <- $e$; $p'$ <- $e'; \ldots$) yield $e''$ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` where `$\ldots$` is a (possibly empty) sequence of generators, definitions, or guards, is translated to - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` $e$.flatMap { case $p$ => for ($p'$ <- $e'; \ldots$) yield $e''$ } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` - A for loop - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` for ($p$ <- $e$; $p'$ <- $e'; \ldots$) $e''$ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` where `$\ldots$` is a (possibly empty) sequence of generators, definitions, or guards, is translated to - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` $e$.foreach { case $p$ => for ($p'$ <- $e'; \ldots$) $e''$ } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` - A generator `$p$ <- $e$` followed by a guard `if $g$` is translated to a single generator @@ -998,30 +998,30 @@ comprehensions have been eliminated. `$p'$ = $e'$` is translated to the following generator of pairs of values, where $x$ and $x'$ are fresh names: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ($p$, $p'$) <- for ($x @ p$ <- $e$) yield { val $x' @ p'$ = $e'$; ($x$, $x'$) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) The following code produces all pairs of numbers between $1$ and $n-1$ whose sums are prime. - ~~~~~~~~~~~~~~~~~~~~~~~ + ``` for { i <- 1 until n j <- 1 until i if isPrime(i+j) } yield (i, j) - ~~~~~~~~~~~~~~~~~~~~~~~ + ``` The for comprehension is translated to: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (1 until n) .flatMap { case i => (1 until i) .withFilter { j => isPrime(i+j) } .map { case j => (i, j) } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (@) For comprehensions can be used to express vector and matrix algorithms concisely. @@ -1029,34 +1029,34 @@ comprehensions have been eliminated. <!-- see test/files/run/t0421.scala --> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def transpose[A](xss: Array[Array[A]]) = { for (i <- Array.range(0, xss(0).length)) yield for (xs <- xss) yield xs(i) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here is a function to compute the scalar product of two vectors: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def scalprod(xs: Array[Double], ys: Array[Double]) = { var acc = 0.0 for ((x, y) <- xs zip ys) acc = acc + x * y acc } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Finally, here is a function to compute the product of two matrices. Compare with the imperative version of \ref{ex:imp-mat-mul}. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { val ysst = transpose(yss) for (xs <- xss) yield for (yst <- ysst) yield scalprod(xs, yst) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The code above makes use of the fact that `map`, `flatMap`, `withFilter`, and `foreach` are defined for instances of class @@ -1065,9 +1065,9 @@ comprehensions have been eliminated. ## Return Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= `return' [Expr] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A return expression `return $e$` must occur inside the body of some enclosing named method or function. The innermost enclosing named @@ -1103,9 +1103,9 @@ and will propagate up the call stack. ## Throw Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= `throw' Expr -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A throw expression `throw $e$` evaluates the expression $e$. The type of this expression must conform to @@ -1121,18 +1121,18 @@ is `scala.Nothing`. ## Try Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr1 ::= `try' `{' Block `}' [`catch' `{' CaseClauses `}'] [`finally' Expr] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` This expression is evaluated by evaluating the block $b$. If evaluation of $b$ does not cause an exception to be @@ -1176,12 +1176,12 @@ for `try { try { $b$ } catch $e_1$ } finally $e_2$`. ## Anonymous Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr ::= (Bindings | [`implicit'] id | `_') `=>' Expr ResultExpr ::= (Bindings | ([`implicit'] id | `_') `:' CompoundType) `=>' Block Bindings ::= `(' Binding {`,' Binding} `)' Binding ::= (id | `_') [`:' Type] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The anonymous function `($x_1$: $T_1 , \ldots , x_n$: $T_n$) => e` maps parameters $x_i$ of types $T_i$ to a result given @@ -1204,11 +1204,11 @@ type which does not refer to any of the formal parameters $x_i$. The anonymous function is evaluated as the instance creation expression -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` new scala.Function$n$[$T_1 , \ldots , T_n$, $T$] { def apply($x_1$: $T_1 , \ldots , x_n$: $T_n$): $T$ = $e$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` In the case of a single untyped formal parameter, `($x\,$) => $e$` @@ -1229,7 +1229,7 @@ anonymous functions always have to be given explicitly. (@) Examples of anonymous functions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` x => x // The identity function f => g => x => f(g(x)) // Curried function composition @@ -1243,14 +1243,14 @@ anonymous functions always have to be given explicitly. _ => 5 // The function that ignores its argument // and always returns 5. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Placeholder Syntax for Anonymous Functions -~~~~~~~~~~~~~~~~~~~~~~ +``` SimpleExpr1 ::= `_' -~~~~~~~~~~~~~~~~~~~~~~ +``` An expression (of syntactic category `Expr`) may contain embedded underscore symbols `_` at places where identifiers @@ -1304,7 +1304,7 @@ include at least the expressions of the following forms: ## Statements -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` BlockStat ::= Import | {Annotation} [`implicit'] Def | {Annotation} {LocalModifier} TmplDef @@ -1315,7 +1315,7 @@ TemplateStat ::= Import | {Annotation} {Modifier} Dcl | Expr | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Statements occur as parts of blocks and templates. A statement can be an import, a definition or an expression, or it can be empty. @@ -1361,9 +1361,9 @@ is applied to pick a unique member. _Type Instantiation_ \ An expression $e$ of polymorphic type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` [$a_1$ >: $L_1$ <: $U_1 , \ldots , a_n$ >: $L_n$ <: $U_n$]$T$ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` which does not appear as the function part of a type application is converted to a type instance of $T$ @@ -1526,21 +1526,21 @@ alternatives in $\mathscr{B}$. (@) Consider the following definitions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class A extends B {} def f(x: B, y: B) = $\ldots$ def f(x: A, y: B) = $\ldots$ val a: A val b: B - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Then the application `f(b, b)` refers to the first definition of $f$ whereas the application `f(a, a)` refers to the second. Assume now we add a third overloaded definition - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def f(x: B, y: A) = $\ldots$ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Then the application `f(a, a)` is rejected for being ambiguous, since no most specific applicable signature exists. @@ -1640,16 +1640,16 @@ any one of them. (@) Consider the two methods: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def cons[A](x: A, xs: List[A]): List[A] = x :: xs def nil[B]: List[B] = Nil - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` and the definition - ~~~~~~~~~~~~~~~~~~~~~~ + ``` val xs = cons(1, nil) - ~~~~~~~~~~~~~~~~~~~~~~ + ``` The application of `cons` is typed with an undefined expected type. This application is completed by local type inference to @@ -1663,42 +1663,42 @@ any one of them. itself polymorphic. One tries to type-check `nil` with an expected type `List[a]`. This leads to the constraint system - ~~~~~~~~~~~~~~~~~~~~ + ``` List[b?] <: List[a] - ~~~~~~~~~~~~~~~~~~~~ + ``` where we have labeled `b?` with a question mark to indicate that it is a variable in the constraint system. Because class `List` is covariant, the optimal solution of this constraint is - ~~~~~~~~~~~~~~~~~~ + ``` b = scala.Nothing - ~~~~~~~~~~~~~~~~~~ + ``` In a second step, one solves the following constraint system for the type parameter `a` of `cons`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Int <: a? List[scala.Nothing] <: List[a?] List[a?] <: $\mbox{\sl undefined}$ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The optimal solution of this constraint system is - ~~~~~~~~ + ``` a = Int - ~~~~~~~~ + ``` so `Int` is the type inferred for `a`. (@) Consider now the definition - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val ys = cons("abc", xs) - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` where `xs` is defined of type `List[Int]` as before. In this case local type inference proceeds as follows. @@ -1714,17 +1714,17 @@ any one of them. In a second step, one solves the following constraint system for the type parameter `a` of `cons`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` String <: a? List[Int] <: List[a?] List[a?] <: $\mbox{\sl undefined}$ - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The optimal solution of this constraint system is - ~~~~~~~~~~~~~~ + ``` a = scala.Any - ~~~~~~~~~~~~~~ + ``` so `scala.Any` is the type inferred for `a`. @@ -1742,38 +1742,38 @@ 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { val $x_1$ = $e_1$; $\ldots$ val $x_m$ = $e_m$; ($y_1: T_1 , \ldots , y_n: T_n$) => $e'$($y_1 , \ldots , y_n$) } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Dynamic Member Selection The standard Scala library defines a trait `scala.Dynamic` which defines a member \@invokeDynamic@ as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala trait Dynamic { def applyDynamic (name: String, args: Any*): Any ... } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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: -~~~~~~~~~~~~~~~~~~~~~~~~ +``` $e$.applyDynamic("$x$") -~~~~~~~~~~~~~~~~~~~~~~~~ +``` If the selection is followed by some arguments, e.g.\ $e.x(\mathit{args})$, then that expression is rewritten to -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $e$.applyDynamic("$x$", $\mathit{args}$) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` diff --git a/09-implicit-parameters-and-views.md b/09-implicit-parameters-and-views.md index f943ae211a..5f41d25e34 100644 --- a/09-implicit-parameters-and-views.md +++ b/09-implicit-parameters-and-views.md @@ -2,10 +2,10 @@ ## The Implicit Modifier -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` LocalModifier ::= ‘implicit’ ParamClauses ::= {ParamClause} [nl] ‘(’ ‘implicit’ Params ‘)’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Template members and parameters labeled with an `implicit` modifier can be passed to [implicit parameters](#implicit-parameters) @@ -17,7 +17,7 @@ type members, as well as for [top-level objects](#packagings). two concrete implementations, `StringMonoid` and `IntMonoid`. The two implementations are marked implicit. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class Monoid[A] extends SemiGroup[A] { def unit: A def add(x: A, y: A): A @@ -32,7 +32,7 @@ type members, as well as for [top-level objects](#packagings). def unit: Int = 0 } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Implicit Parameters @@ -89,11 +89,11 @@ 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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def sum[A](xs: List[A])(implicit m: Monoid[A]): A = if (xs.isEmpty) m.unit else m.add(xs.head, sum(xs.tail)) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The monoid in question is marked as an implicit parameter, and can therefore be inferred based on the type of the list. @@ -114,57 +114,57 @@ is the following method from module `scala.List`, which injects lists into the `scala.Ordered` class, provided the element type of the list is also convertible to this type. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` implicit def list2ordered[A](x: List[A]) (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = ... -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Assume in addition a method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` implicit def int2ordered(x: Int): Ordered[Int] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` that injects integers into the `Ordered` class. We can now define a `sort` method over ordered lists: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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]]` as follows: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` sort(yss) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The call above will be completed by passing two nested implicit arguments: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` sort(yss)(xs: List[Int] => list2ordered[Int](xs)(int2ordered)) . -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The possibility of passing implicit arguments to implicit arguments 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` implicit def magic[A](x: A)(implicit a2ordered: A => Ordered[A]): Ordered[A] = a2ordered(x) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Now, if one tried to apply `sort` to an argument `arg` of a type that did not have another injection into the `Ordered` class, one would obtain an infinite expansion: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` sort(arg)(x => magic(x)(x => magic(x)(x => ... ))) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` To prevent such infinite expansions, the compiler keeps track of a stack of “open implicit types” for which implicit arguments are currently being @@ -214,11 +214,11 @@ the type: the sequence of types for which implicit arguments are searched is - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` List[List[Int]] => Ordered[List[List[Int]]], List[Int] => Ordered[List[Int]] Int => Ordered[Int] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` All types share the common type constructor `scala.Function1`, but the complexity of the each new type is lower than the complexity of the previous types. @@ -228,18 +228,18 @@ the type: (@) Let `ys` be a list of some type which cannot be converted to `Ordered`. For instance: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val ys = List(new IllegalArgumentException, new ClassCastException, new Error) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Assume that the definition of `magic` above is in scope. Then the sequence of types for which implicit arguments are searched is - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Throwable => Ordered[Throwable], Throwable => Ordered[Throwable], ... - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Since the second type in the sequence is equal to the first, the compiler will issue an error signalling a divergent implicit expansion. @@ -288,26 +288,26 @@ or the call-by-name category). (@impl-ordered) Class `scala.Ordered[A]` contains a method - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def <= [B >: A](that: B)(implicit b2ordered: B => Ordered[B]): Boolean . - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Assume two lists `xs` and `ys` of type `List[Int]` and assume that the `list2ordered` and `int2ordered` methods defined [here](#implicit-parameters) are in scope. Then the operation - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` xs <= ys - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` is legal, and is expanded to: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` list2ordered(xs)(int2ordered).<= (ys) (xs => list2ordered(xs)(int2ordered)) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The first application of `list2ordered` converts the list `xs` to an instance of class `Ordered`, whereas the second @@ -317,10 +317,10 @@ or the call-by-name category). ## Context Bounds and View Bounds -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] {‘<%’ Type} {‘:’ Type} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A type parameter $A$ of a method or non-trait class may have one or more view bounds `$A$ <% $T$`. In this case the type parameter may be @@ -337,16 +337,16 @@ 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def $f$[$A$ <% $T_1$ ... <% $T_m$ : $U_1$ : $U_n$]($\mathit{ps}$): $R$ = ... -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Then the method definition above is expanded to -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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$ = ... -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` where the $v_i$ and $w_j$ are fresh names for the newly introduced implicit parameters. These parameters are called _evidence parameters_. @@ -363,9 +363,9 @@ additional implicit parameters. (@) The `<=` method mentioned in \ref{ex:impl-ordered} can be declared more concisely as follows: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def <= [B >: A <% Ordered[B]](that: B): Boolean - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Manifests @@ -376,12 +376,12 @@ standard library contains a hierarchy of four manifest classes, with `OptManifest` at the top. Their signatures follow the outline below. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` trait OptManifest[+T] object NoManifest extends OptManifest[Nothing] trait ClassManifest[T] extends OptManifest[T] trait Manifest[T] extends ClassManifest[T] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` If an implicit parameter of a method or constructor is of a subtype $M[T]$ of class `OptManifest[T]`, _a manifest is determined for $M[S]$_, diff --git a/10-pattern-matching.md b/10-pattern-matching.md index e55003187a..04bc6e857d 100644 --- a/10-pattern-matching.md +++ b/10-pattern-matching.md @@ -2,7 +2,7 @@ ## Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Pattern ::= Pattern1 { ‘|’ Pattern1 } Pattern1 ::= varid ‘:’ TypePat | ‘_’ ‘:’ TypePat @@ -20,7 +20,7 @@ | ‘(’ [Patterns] ‘)’ | XmlPattern Patterns ::= Pattern {‘,’ Patterns} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A pattern is built from constants, constructors, variables and type tests. Pattern matching tests whether a given value (or sequence of values) @@ -49,10 +49,10 @@ than once in a pattern. ### Variable Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimplePattern ::= `_' | varid -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A variable pattern $x$ is a simple identifier which starts with a lower case letter. It matches any value, and binds the variable name @@ -63,10 +63,10 @@ which is treated as if it was a fresh variable on each occurrence. ### Typed Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Pattern1 ::= varid `:' TypePat | `_' `:' TypePat -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A typed pattern $x: T$ consists of a pattern variable $x$ and a type pattern $T$. The type of $x$ is the type pattern $T$, where @@ -77,9 +77,9 @@ that value. ### Pattern Binders -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Pattern2 ::= varid `@' Pattern3 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A pattern binder `$x$@$p$` consists of a pattern variable $x$ and a pattern $p$. The type of the variable $x$ is the static type $T$ of the pattern $p$. @@ -89,9 +89,9 @@ and it binds the variable name to that value. ### Literal Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimplePattern ::= Literal -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A literal pattern $L$ matches any value that is equal (in terms of $==$) to the literal $L$. The type of $L$ must conform to the @@ -99,9 +99,9 @@ expected type of the pattern. ### Stable Identifier Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimplePattern ::= StableId -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A stable identifier pattern is a [stable identifier](#paths) $r$. The type of $r$ must conform to the expected @@ -115,21 +115,21 @@ backquotes; then it is treated as a stable identifier pattern. (@) Consider the following function definition: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def f(x: Int, y: Int) = x match { case y => ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here, `y` is a variable pattern, which matches any value. If we wanted to turn the pattern into a stable identifier pattern, this can be achieved as follows: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def f(x: Int, y: Int) = x match { case `y` => ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Now, the pattern matches the `y` parameter of the enclosing function `f`. That is, the match succeeds only if the `x` argument and the `y` @@ -137,9 +137,9 @@ backquotes; then it is treated as a stable identifier pattern. ### Constructor Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimplePattern ::= StableId `(' [Patterns] `) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A constructor pattern is of the form $c(p_1 , \ldots , p_n)$ where $n \geq 0$. It consists of a stable identifier $c$, followed by element @@ -163,9 +163,9 @@ repeated parameter. This is further discussed [here](#pattern-sequences). ### Tuple Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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$)`, @@ -174,9 +174,9 @@ where $n \geq 2$. The empty tuple ### Extractor Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimplePattern ::= StableId `(' [Patterns] `)' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An extractor pattern $x(p_1 , \ldots , p_n)$ where $n \geq 0$ is of the same syntactic form as a constructor pattern. However, instead of @@ -214,29 +214,29 @@ This case is further discussed [here](#pattern-seqs). (@) The `Predef` object contains a definition of an extractor object `Pair`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` object Pair { def apply[A, B](x: A, y: B) = Tuple2(x, y) def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This means that the name `Pair` can be used in place of `Tuple2` for tuple formation as well as for deconstruction of tuples in patterns. Hence, the following is possible: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val x = (1, 2) val y = x match { case Pair(i, s) => Pair(s + i, i * i) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Pattern Sequences -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` SimplePattern ::= StableId `(' [Patterns `,'] [varid `@'] `_' `*' `)' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A pattern sequence $p_1 , \ldots , p_n$ appears in two contexts. First, in a constructor pattern @@ -262,9 +262,9 @@ p_n$. ### Infix Operation Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Pattern3 ::= SimplePattern {id [nl] SimplePattern} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An infix operation pattern $p;\mathit{op};q$ is a shorthand for the constructor or extractor pattern $\mathit{op}(p, q)$. The precedence and @@ -277,9 +277,9 @@ shorthand for the constructor or extractor pattern $\mathit{op}(p, q_1 ### Pattern Alternatives -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Pattern ::= Pattern1 { `|' Pattern1 } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A pattern alternative `$p_1$ | $\ldots$ | $p_n$` consists of a number of alternative patterns $p_i$. All alternative @@ -320,9 +320,9 @@ A pattern $p$ is _irrefutable_ for a type $T$, if one of the following applies: ## Type Patterns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` TypePat ::= Type -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Type patterns consist of types, type variables, and wildcards. A type pattern $T$ is of one of the following forms: @@ -457,12 +457,12 @@ are inferred in the same way as for the typed pattern (@) Consider the program fragment: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val x: Any x match { case y: List[a] => ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here, the type pattern `List[a]` is matched against the expected type `Any`. The pattern binds the type variable @@ -473,9 +473,9 @@ are inferred in the same way as for the typed pattern On the other hand, if `x` is declared as - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val x: List[List[String]], - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` this generates the constraint `List[a] <: List[List[String]]`, which simplifies to @@ -485,12 +485,12 @@ are inferred in the same way as for the typed pattern (@) Consider the program fragment: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` val x: Any x match { case y: List[String] => ... } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Scala does not maintain information about type arguments at run-time, so there is no way to check that `x` is a list of strings. @@ -506,13 +506,13 @@ are inferred in the same way as for the typed pattern (@) Consider the program fragment - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` class Term[A] class Number(val n: Int) extends Term[Int] def f[B](t: Term[B]): B = t match { case y: Number => y.n } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The expected type of the pattern `y: Number` is `Term[B]`. The type `Number` does not conform to @@ -529,17 +529,17 @@ are inferred in the same way as for the typed pattern ## Pattern Matching Expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Expr ::= PostfixExpr `match' `{' CaseClauses `}' CaseClauses ::= CaseClause {CaseClause} CaseClause ::= `case' Pattern [Guard] `=>' Block -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A pattern matching expression -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` e match { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` consists of a selector expression $e$ and a number $n > 0$ of cases. Each case consists of a (possibly guarded) pattern $p_i$ and a @@ -607,7 +607,7 @@ possibility of a `MatchError` being raised at run-time. (@eval) Consider the following definitions of arithmetic terms: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` abstract class Term[T] case class Lit(x: Int) extends Term[Int] case class Succ(t: Term[Int]) extends Term[Int] @@ -615,7 +615,7 @@ possibility of a `MatchError` being raised at run-time. case class If[T](c: Term[Boolean], t1: Term[T], t2: Term[T]) extends Term[T] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` There are terms to represent numeric literals, incrementation, a zero test, and a conditional. Every term carries as a type parameter the @@ -623,14 +623,14 @@ possibility of a `MatchError` being raised at run-time. A type-safe evaluator for such terms can be written as follows. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def eval[T](t: Term[T]): T = t match { case Lit(n) => n case Succ(u) => eval(u) + 1 case IsZero(u) => eval(u) == 0 case If(c, u1, u2) => eval(if (eval(c)) u1 else u2) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Note that the evaluator makes crucial use of the fact that type parameters of enclosing methods can acquire new bounds through pattern @@ -646,15 +646,15 @@ possibility of a `MatchError` being raised at run-time. ## Pattern Matching Anonymous Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` BlockExpr ::= `{' CaseClauses `}' -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` An anonymous function can be defined by a sequence of cases -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` which appear as an expression without a prior `match`. The expected type of such an expression must in part be defined. It must @@ -666,29 +666,29 @@ $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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ($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$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Here, each $x_i$ is a fresh name. 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$. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` 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$ } } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` If the expected type is `scala.PartialFunction[$S$, $R$]`, the expression is taken to be equivalent to the following instance creation expression: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` new scala.PartialFunction[$S$, $T$] { def apply($x$: $S$): $T$ = x match { case $p_1$ => $b_1$ $\ldots$ case $p_n$ => $b_n$ @@ -698,7 +698,7 @@ new scala.PartialFunction[$S$, $T$] { case _ => false } } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Here, $x$ is a fresh name and $T$ is the weak least upper bound of the types of all $b_i$. The final default case in the `isDefinedAt` @@ -709,19 +709,19 @@ already a variable or wildcard pattern. `/:` to compute the scalar product of two vectors: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def scalarProduct(xs: Array[Double], ys: Array[Double]) = (0.0 /: (xs zip ys)) { case (a, (b, c)) => a + b * c } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` The case clauses in this code are equivalent to the following anonymous function: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` (x, y) => (x, y) match { case (a, (b, c)) => a + b * c } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` diff --git a/11-top-level-definitions.md b/11-top-level-definitions.md index 215e16c426..e7d6a9c192 100644 --- a/11-top-level-definitions.md +++ b/11-top-level-definitions.md @@ -2,7 +2,7 @@ ## Compilation Units -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` CompilationUnit ::= {‘package’ QualId semi} TopStatSeq TopStatSeq ::= TopStat {semi TopStat} TopStat ::= {Annotation} {Modifier} TmplDef @@ -11,7 +11,7 @@ TopStat ::= {Annotation} {Modifier} TmplDef | PackageObject | QualId ::= id {‘.’ id} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A compilation unit consists of a sequence of packagings, import clauses, and class and object definitions, which may be preceded by a @@ -19,24 +19,24 @@ package clause. A compilation unit -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package $p_1$; $\ldots$ package $p_n$; $\mathit{stats}$ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` starting with one or more package clauses is equivalent to a compilation unit consisting of the packaging -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package $p_1$ { $\ldots$ package $p_n$ { $\mathit{stats}$ } $\ldots$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Implicitly imported into every compilation unit are, in that order : the package `java.lang`, the package `scala`, and the object @@ -46,9 +46,9 @@ that order hide members of an earlier import. ## Packagings -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A package is a special object which defines a set of member classes, objects and packages. Unlike other objects, packages are not introduced @@ -65,11 +65,11 @@ 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$. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package org.net.prj { ... } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` all members of package `org.net.prj` are visible under their simple names, but members of packages `org` or `org.net` require @@ -88,9 +88,9 @@ are visible to each other without qualification. ## Package Objects -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` PackageObject ::= ‘package’ ‘object’ ObjectDef -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A package object `package object $p$ extends $t$` adds the members of template $t$ to the package $p$. There can be only one @@ -107,9 +107,9 @@ future version of Scala. ## Package References -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` QualId ::= id {‘.’ id} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A reference to a package takes the form of a qualified identifier. Like all other references, package references are relative. That is, @@ -121,7 +121,7 @@ outermost root package which contains all top-level packages. (@package-ids) Consider the following program: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` package b { class B } @@ -131,7 +131,7 @@ outermost root package which contains all top-level packages. val x = new _root_.b.B } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Here, the reference `_root_.b.B` refers to class `B` in the toplevel package `b`. If the `_root_` prefix had been @@ -157,34 +157,34 @@ 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`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` package test object HelloWorld { def main(args: Array[String]) { println("Hello World") } } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` This program can be started by the command - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` scala test.HelloWorld - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` In a Java environment, the command - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` java test.HelloWorld - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` would work as well. `HelloWorld` can also be defined without a `main` method by inheriting from `App` instead: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` 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 4d4ed87169..974fbc6b78 100644 --- a/12-xml-expressions-and-patterns.md +++ b/12-xml-expressions-and-patterns.md @@ -12,9 +12,9 @@ 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). -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` XmlExpr ::= XmlContent {Element} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Well-formedness constraints of the XML specification apply, which means for instance that start tags and end tags must match, and @@ -28,7 +28,7 @@ are changed. Scala does not support declarations, CDATA sections or processing instructions. Entity references are not resolved at runtime. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Element ::= EmptyElemTag | STag Content ETag @@ -44,7 +44,7 @@ XmlContent ::= Element | CDSect | PI | Comment -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` If an XML expression is a single element, its value is a runtime representation of an XML node (an instance of a subclass of @@ -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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Attribute ::= Name Eq AttValue AttValue ::= ‘"’ {CharQ | CharRef} ‘"’ @@ -73,7 +73,7 @@ ScalaExpr ::= Block CharData ::= { CharNoRef } $\mbox{\rm\em without}$ {CharNoRef}`{'CharB {CharNoRef} $\mbox{\rm\em and without}$ {CharNoRef}`]]>'{CharNoRef} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` XML expressions may contain Scala expressions as attribute values or within nodes. In the latter case, these are embedded using a single opening @@ -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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` BaseChar, Char, Comment, CombiningChar, Ideographic, NameChar, S, Reference ::= $\mbox{\rm\em “as in W3C XML”}$ @@ -96,7 +96,7 @@ Name ::= XNameStart {NameChar} XNameStart ::= ‘_’ | BaseChar | Ideographic $\mbox{\rm\em (as in W3C XML, but without }$ ‘:’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ## XML patterns @@ -104,9 +104,9 @@ 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). -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` XmlPattern ::= ElementPattern -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Well-formedness constraints of the XML specification apply. @@ -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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ElemPattern ::= EmptyElemTagP | STagP ContentP ETagP @@ -141,5 +141,5 @@ ContentP1 ::= ElemPattern | Comment | ScalaPatterns ScalaPatterns ::= ‘{’ Patterns ‘}’ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` diff --git a/13-user-defined-annotations.md b/13-user-defined-annotations.md index 1aa5e7e613..717a6dcb1f 100644 --- a/13-user-defined-annotations.md +++ b/13-user-defined-annotations.md @@ -1,9 +1,9 @@ # User-Defined Annotations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Annotation ::= ‘@’ SimpleType {ArgumentExprs} ConstrAnnotation ::= ‘@’ SimpleType ArgumentExprs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` User-defined annotations associate meta-information with definitions. A simple annotation has the form `@$c$` or `@$c(a_1 , \ldots , a_n)$`. @@ -20,12 +20,12 @@ does not matter. Examples: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` @serializable class C { ... } // A class annotation. @transient @volatile var m: Int // A variable annotation String @local // A type annotation (e: @unchecked) match { ... } // An expression annotation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The meaning of annotation clauses is implementation-dependent. On the Java platform, the following annotations have a standard meaning. @@ -55,9 +55,9 @@ Java platform, the following annotations have a standard meaning. This is equivalent to a the following field definition in Java: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` private final static SerialVersionUID = <longlit> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` * `@throws(<classlit>)` \ A Java compiler checks that a program contains handlers for checked exceptions @@ -95,11 +95,11 @@ 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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def f(x: Option[Int]) = (x: @unchecked) match { case Some(y) => y } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Without the `@unchecked` annotation, a Scala compiler could infer that the pattern match is non-exhaustive, and could produce a @@ -110,12 +110,12 @@ 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: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` type A { type T } type B @uncheckedStable val x: A with B // volatile type val y: x.T // OK since `x' is still a path - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Without the `@uncheckedStable` annotation, the designator `x` would not be a path since its type `A with B` is volatile. Hence, @@ -135,11 +135,11 @@ Java platform, the following annotations have a standard meaning. For instance, the following code would generate specialized traits for `Unit`, `Int` and `Double` - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` trait Function0[@specialized(Unit, Int, Double) T] { def apply: T } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Whenever the static type of an expression matches a specialized variant of a definition, diff --git a/14-the-scala-standard-library.md b/14-the-scala-standard-library.md index b6fd1ceb77..d6bb9eca52 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala /** The universal root class */ abstract class Any { @@ -86,17 +86,17 @@ class AnyRef extends Any { /** A mixin class for every user-defined Scala class */ trait ScalaObject extends AnyRef -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The type test `$x$.isInstanceOf[$T$]` is equivalent to a typed pattern match -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` $x$ match { case _: $T'$ => true case _ => false } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` where the type $T'$ is the same as $T$ except if $T$ is of the form $D$ or $D[\mathit{tps}]$ where $D$ is a type member of some outer @@ -132,13 +132,13 @@ Subrange types, as well as `Int` and `Long` are called _integer types_, whereas Numeric value types are ranked in the following partial order: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Byte - Short \ Int - Long - Float - Double / Char -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` `Byte` and `Short` are the lowest-ranked types in this order, whereas `Double` is the highest-ranked. Ranking does _not_ @@ -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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def equals(other: Any): Boolean = other match { case that: Byte => this == that case that: Short => this == that @@ -227,7 +227,7 @@ def equals(other: Any): Boolean = other match { case that: Double => this == that case _ => false } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The `hashCode` method returns an integer hashcode that maps equal numeric values to equal results. It is guaranteed to be the identity for @@ -238,7 +238,7 @@ floating point number. (@) As an example, here is the signature of the numeric value type `Int`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` package scala abstract sealed class Int extends AnyVal { def == (that: Double): Boolean // double equality @@ -282,7 +282,7 @@ floating point number. def toFloat: Float // convert to Float def toDouble: Double // convert to Double } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ### Class `Boolean` @@ -291,7 +291,7 @@ Class `Boolean` has only two values: `true` and `false`. It implements operations as given in the following class definition. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala abstract sealed class Boolean extends AnyVal { def && (p: => Boolean): Boolean = // boolean and @@ -309,7 +309,7 @@ abstract sealed class Boolean extends AnyVal { def unary_!: Boolean = // boolean negation if (this) false else true } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The class also implements operations `equals`, `hashCode`, and `toString` from class `Any`. @@ -347,9 +347,9 @@ 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 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def + (that: Any): String -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` which concatenates its left operand with the textual representation of its right operand. @@ -359,12 +359,12 @@ right operand. Scala defines tuple classes `Tuple$n$` for $n = 2 , \ldots , 9$. These are defined as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala case class Tuple$n$[+A_1, ..., +A_n](_1: A_1, ..., _$n$: A_$n$) { def toString = "(" ++ _1 ++ "," ++ $\ldots$ ++ "," ++ _$n$ ++ ")" } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The implicitly imported [`Predef`](#the-predef-object) object defines the names `Pair` as an alias of `Tuple2` and `Triple` @@ -375,13 +375,13 @@ as an alias for `Tuple3`. Scala defines function classes `Function$n$` for $n = 1 , \ldots , 9$. These are defined as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala trait Function$n$[-A_1, ..., -A_$n$, +B] { def apply(x_1: A_1, ..., x_$n$: A_$n$): B def toString = "<function>" } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` A subclass of `Function1` represents partial functions, which are undefined on some points in their domain. In addition to the @@ -389,11 +389,11 @@ 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` class PartialFunction[-A, +B] extends Function1[A, B] { def isDefinedAt(x: A): Boolean } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The implicitly imported [`Predef`](#the-predef-object) object defines the name `Function` as an alias of `Function1`. @@ -402,7 +402,7 @@ The implicitly imported [`Predef`](#the-predef-object) object defines the name The class of generic arrays is given as follows. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` final class Array[A](len: Int) extends Seq[A] { def length: Int = len def apply(i: Int): A = $\ldots$ @@ -413,7 +413,7 @@ final class Array[A](len: Int) extends Seq[A] { def map[B](f: A => B): Array[B] = $\ldots$ def flatMap[B](f: A => Array[B]): Array[B] = $\ldots$ } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` If $T$ is not a type parameter or abstract type, the type Array[$T$] is represented as the native array type `[]$T$` in the @@ -454,11 +454,11 @@ 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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` val xs = new Array[String](2) // val ys: Array[Object] = xs // **** error: incompatible types val ys: Array[Object] = xs.asInstanceOf[Array[Object]] // OK -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Second, for _polymorphic arrays_, that have a type parameter or abstract type $T$ as their element type, a representation different @@ -467,7 +467,7 @@ from `isInstanceOf` and `asInstanceOf` still work as if the array used the standard representation of monomorphic arrays: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` val ss = new Array[String](2) def f[T](xs: Array[T]): Array[String] = @@ -475,7 +475,7 @@ def f[T](xs: Array[T]): Array[String] = else throw new Error("not an instance") f(ss) // returns ss -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The representation chosen for polymorphic arrays also guarantees that polymorphic array creations work as expected. An example is the @@ -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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` def mkArray[T](elems: Seq[T]): Array[T] = { val result = new Array[T](elems.length) var i = 0 @@ -492,7 +492,7 @@ def mkArray[T](elems: Seq[T]): Array[T] = { i += 1 } } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Note that under Java's erasure model of arrays the method above would not work as expected -- in fact it would always return an array of @@ -510,7 +510,7 @@ constructor methods for arrays, as well as the [extractor method](#extractor-patterns) `unapplySeq` which enables pattern matching over arrays. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala object Array { /** copies array elements from `src' to `dest'. */ @@ -543,23 +543,23 @@ object Array { /** Enables pattern matching over arrays */ def unapplySeq[A](x: Array[A]): Option[Seq[A]] = Some(x) } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` (@) The following method duplicates a given argument array and returns a pair consisting of the original and the duplicate: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def duplicate[T](xs: Array[T]) = { val ys = new Array[T](xs.length) Array.copy(xs, 0, ys, 0, xs.length) (xs, ys) } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` ## Class Node -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala.xml trait Node { @@ -628,7 +628,7 @@ trait Node { override def toString = Utility.toXML(this) } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ## The `Predef` Object @@ -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: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` package scala object Predef { @@ -712,10 +712,10 @@ object Predef { if (!requirement) throw new IllegalArgumentException("requirement failed: "+ message) } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` // tupling --------------------------------------------------------- @@ -757,7 +757,7 @@ object Predef { ... } -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Predefined Implicit Definitions @@ -787,19 +787,19 @@ 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`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` 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 } def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` * An implicit wrapper that adds a `->` method with the following implementation to type `Any`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def -> [B](y: B): (A, B) = (x, y) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` * For every array type with elements of primitive type, a wrapper that takes the arrays of that type to instances of a `runtime.ArrayOps` @@ -811,27 +811,27 @@ 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`. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` def +(other: String) = String.valueOf(self) + other def formatted(fmtstr: String): String = fmtstr format self - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` * Numeric primitive conversions that implement the transitive closure of the following mappings: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Byte -> Short Short -> Int Char -> Int Int -> Long Long -> Float Float -> Double - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` * Boxing and unboxing conversions between primitive types and their boxed versions: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Byte <-> java.lang.Byte Short <-> java.lang.Short Char <-> java.lang.Character @@ -840,14 +840,14 @@ The available high-priority implicits include definitions falling into the follo Float <-> java.lang.Float Double <-> java.lang.Double Boolean <-> java.lang.Boolean - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` * An implicit definition that generates instances of type `T <:< T`, for any type `T`. Here, `<:<` is a class defined as follows. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` sealed abstract class <:<[-From, +To] extends (From => To) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` Implicit parameters of `<:<` types are typically used to implement type constraints. diff --git a/15-scala-syntax-summary.md b/15-scala-syntax-summary.md index 33cd29c09c..8e17360622 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. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` upper ::= ‘A’ | … | ‘Z’ | ‘\$’ | ‘_’ // and Unicode category Lu lower ::= ‘a’ | … | ‘z’ // and Unicode category Ll letter ::= upper | lower // and Unicode categories Lo, Lt, Nl @@ -56,12 +56,12 @@ comment ::= ‘/*’ “any sequence of characters” ‘*/’ nl ::= $\mathit{“new line character”}$ semi ::= ‘;’ | nl {nl} -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` The context-free syntax of Scala is given by the following EBNF grammar. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` Literal ::= [‘-’] integerLiteral | [‘-’] floatingPointLiteral | booleanLiteral @@ -291,7 +291,7 @@ grammar. PackageObject ::= ‘package’ ‘object’ ObjectDef CompilationUnit ::= {‘package’ QualId semi} TopStatSeq -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` <!-- TODO add: @@ -133,11 +133,11 @@ Code blocks using the listings package of form can be replaced with pandoc code blocks of form - ~~~~~~~~~~~~~~{#ref-identifier .scala .numberLines} + ```{#ref-identifier .scala .numberLines} val x = 1 val y = x + 1 x + y - ~~~~~~~~~~~~~~ + ``` Where `#ref-identifier` is an identifier that can be used for producing links to the code block, while `.scala` and `.numberLines` are classes that get |