From 62db8d98559766c06d490d9d4c18ff27587fde0b Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Tue, 16 Sep 2014 18:48:09 +0200 Subject: Spec improvements --- spec/01-lexical-syntax.md | 348 +++++---- spec/02-identifiers-names-and-scopes.md | 4 +- spec/03-types.md | 23 +- spec/04-basic-declarations-and-definitions.md | 4 +- spec/05-classes-and-objects.md | 10 +- spec/06-expressions.md | 16 +- spec/07-implicit-parameters-and-views.md | 432 ------------ spec/07-implicits.md | 434 ++++++++++++ spec/08-pattern-matching.md | 6 +- spec/10-xml-expressions-and-patterns.md | 2 +- spec/11-annotations.md | 174 +++++ spec/11-user-defined-annotations.md | 163 ----- spec/12-the-scala-standard-library.md | 6 +- spec/13-syntax-summary.md | 6 +- spec/15-changelog.md | 823 ++++++++++++++++++++++ spec/README.md | 2 +- spec/_includes/numbering.css | 2 - spec/_layouts/default.yml | 72 +- spec/_layouts/toc.yml | 26 +- spec/index.md | 21 +- spec/public/fonts/Heuristica-Bold.woff | Bin 0 -> 106188 bytes spec/public/fonts/Heuristica-BoldItalic.woff | Bin 0 -> 104316 bytes spec/public/fonts/Heuristica-Regular.woff | Bin 0 -> 141416 bytes spec/public/fonts/Heuristica-RegularItalic.woff | Bin 0 -> 104700 bytes spec/public/fonts/LuxiMono-Bold.woff | Bin 0 -> 26560 bytes spec/public/fonts/LuxiMono-BoldOblique.woff | Bin 0 -> 29480 bytes spec/public/fonts/LuxiMono-Regular.woff | Bin 0 -> 26432 bytes spec/public/fonts/LuxiMono-RegularOblique.woff | Bin 0 -> 29300 bytes spec/public/fonts/LuxiSans-Bold.woff | Bin 0 -> 13592 bytes spec/public/fonts/LuxiSans-Regular.woff | Bin 0 -> 13568 bytes spec/public/highlight/LICENSE | 24 - spec/public/highlight/highlight.pack.js | 1 - spec/public/images/github-logo@2x.png | Bin 0 -> 1753 bytes spec/public/images/scala-logo-red-spiral-dark.png | Bin 13021 -> 0 bytes spec/public/images/scala-spiral-white.png | Bin 0 -> 1442 bytes spec/public/scripts/LICENSE-highlight | 24 + spec/public/scripts/LICENSE-toc | 18 + spec/public/scripts/highlight.pack.js | 1 + spec/public/scripts/main.js | 57 ++ spec/public/scripts/navigation.js | 70 -- spec/public/scripts/toc.js | 128 ++++ spec/public/stylesheets/fonts.css | 73 ++ spec/public/stylesheets/screen-small.css | 57 ++ spec/public/stylesheets/screen-toc.css | 37 + spec/public/stylesheets/screen.css | 225 ++++-- 45 files changed, 2221 insertions(+), 1068 deletions(-) delete mode 100644 spec/07-implicit-parameters-and-views.md create mode 100644 spec/07-implicits.md create mode 100644 spec/11-annotations.md delete mode 100644 spec/11-user-defined-annotations.md create mode 100644 spec/15-changelog.md create mode 100644 spec/public/fonts/Heuristica-Bold.woff create mode 100644 spec/public/fonts/Heuristica-BoldItalic.woff create mode 100644 spec/public/fonts/Heuristica-Regular.woff create mode 100644 spec/public/fonts/Heuristica-RegularItalic.woff create mode 100644 spec/public/fonts/LuxiMono-Bold.woff create mode 100644 spec/public/fonts/LuxiMono-BoldOblique.woff create mode 100644 spec/public/fonts/LuxiMono-Regular.woff create mode 100644 spec/public/fonts/LuxiMono-RegularOblique.woff create mode 100644 spec/public/fonts/LuxiSans-Bold.woff create mode 100644 spec/public/fonts/LuxiSans-Regular.woff delete mode 100644 spec/public/highlight/LICENSE delete mode 100644 spec/public/highlight/highlight.pack.js create mode 100644 spec/public/images/github-logo@2x.png delete mode 100644 spec/public/images/scala-logo-red-spiral-dark.png create mode 100644 spec/public/images/scala-spiral-white.png create mode 100644 spec/public/scripts/LICENSE-highlight create mode 100644 spec/public/scripts/LICENSE-toc create mode 100644 spec/public/scripts/highlight.pack.js create mode 100644 spec/public/scripts/main.js delete mode 100644 spec/public/scripts/navigation.js create mode 100644 spec/public/scripts/toc.js create mode 100644 spec/public/stylesheets/fonts.css create mode 100644 spec/public/stylesheets/screen-small.css create mode 100644 spec/public/stylesheets/screen-toc.css (limited to 'spec') diff --git a/spec/01-lexical-syntax.md b/spec/01-lexical-syntax.md index 3972961f58..e26cb796c8 100644 --- a/spec/01-lexical-syntax.md +++ b/spec/01-lexical-syntax.md @@ -101,19 +101,18 @@ _ : = => <- <: <% >: # @ The Unicode operators `\u21D2` ‘$\Rightarrow$’ and `\u2190` ‘$\leftarrow$’, which have the ASCII equivalents `=>` and `<-`, are also reserved. -### Example -Here are examples of identifiers: -```scala - x Object maxIndex p2p empty_? - + `yield` αρετη _y dot_product_* - __system _MAX_LEN_ -``` +> Here are examples of identifiers: +> ```scala +> x Object maxIndex p2p empty_? +> + `yield` αρετη _y dot_product_* +> __system _MAX_LEN_ +> ``` + + -### Example -When one needs to access Java identifiers that are reserved words in Scala, use backquote-enclosed strings. -For instance, the statement `Thread.yield()` is illegal, since -`yield` is a reserved word in Scala. However, here's a -work-around: `` Thread.`yield`() `` +> When one needs to access Java identifiers that are reserved words in Scala, use backquote-enclosed strings. +> For instance, the statement `Thread.yield()` is illegal, since `yield` is a reserved word in Scala. +> However, here's a work-around: `` Thread.`yield`() `` ## Newline Characters @@ -205,99 +204,96 @@ A single new line token is accepted - after an [infix operator](06-expressions.html#prefix,-infix,-and-postfix-operations), if the first token on the next line can start an expression, - in front of a [parameter clause](04-basic-declarations-and-definitions.html#function-declarations-and-definitions), and -- after an [annotation](11-user-defined-annotations.html#user-defined-annotations). - -### Example - -The newline tokens between the two lines are not -treated as statement separators. - -```scala -if (x > 0) - x = x - 1 - -while (x > 0) - x = x / 2 - -for (x <- 1 to 10) - println(x) - -type - IntList = List[Int] -``` - -### Example - -```scala -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: - -```scala -new Iterator[Int] - -{ - private var x = 0 - def hasNext = true - def next = { x += 1; x } -} -``` - -### Example - -```scala - x < 0 || - x > 10 -``` - -With an additional newline character, the same code is interpreted as -two expressions: - -```scala - x < 0 || - - x > 10 -``` - -### Example - -```scala -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: - -```scala -def func(x: Int) - - (y: Int) = x + y -``` - -### Example - -```scala -@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). - -```scala -@serializable - -protected class Data { ... } -``` +- after an [annotation](11-annotations.html#user-defined-annotations). + +> The newline tokens between the two lines are not +> treated as statement separators. +> +> ```scala +> if (x > 0) +> x = x - 1 +> +> while (x > 0) +> x = x / 2 +> +> for (x <- 1 to 10) +> println(x) +> +> type +> IntList = List[Int] +> ``` + + + +> ```scala +> 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: +> +> ```scala +> new Iterator[Int] +> +> { +> private var x = 0 +> def hasNext = true +> def next = { x += 1; x } +> } +> ``` + + + +> ```scala +> x < 0 || +> x > 10 +> ``` +> +> With an additional newline character, the same code is interpreted as +> two expressions: +> +> ```scala +> x < 0 || +> +> x > 10 +> ``` + + + +> ```scala +> 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: +> +> ```scala +> def func(x: Int) +> +> (y: Int) = x + y +> ``` + + + +> ```scala +> @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). +> +> ```scala +> @serializable +> +> protected class Data { ... } +> ``` ## Literals @@ -351,11 +347,9 @@ is _pt_. The numeric ranges given by these types are: |`Short` | $-2\^{15}$ to $2\^{15}-1$| |`Char` | $0$ to $2\^{16}-1$ | -### Example - -```scala -0 21 0xFFFFFFFF -42L -``` +> ```scala +> 0 21 0xFFFFFFFF -42L +> ``` ### Floating Point Literals @@ -379,20 +373,18 @@ If a floating point literal in a program is followed by a token starting with a letter, there must be at least one intervening whitespace character between the two tokens. -### Example +> ```scala +> 0.0 1e30f 3.14159f 1.0e-100 .1 +> ``` -```scala -0.0 1e30f 3.14159f 1.0e-100 .1 -``` + -### Example +> The phrase `1.toString` parses as three different tokens: +> the integer literal `1`, a `.`, and the identifier `toString`. -The phrase `1.toString` parses as three different tokens: -the integer literal `1`, a `.`, and the identifier `toString`. + -### Example - -`1.` is not a valid floating point literal because the mandatory digit after the `.` is missing. +> `1.` is not a valid floating point literal because the mandatory digit after the `.` is missing. ### Boolean Literals @@ -413,11 +405,9 @@ A character literal is a single character enclosed in quotes. The character is either a printable unicode character or is described by an [escape sequence](#escape-sequences). -### Example - -```scala -'a' '\u0041' '\n' '\t' -``` +> ```scala +> 'a' '\u0041' '\n' '\t' +> ``` Note that `'\u000A'` is _not_ a valid character literal because Unicode conversion is done before literal parsing and the Unicode @@ -439,12 +429,10 @@ contains a double quote character, it must be escaped, i.e. `"\""`. The value of a string literal is an instance of class `String`. -### Example - -```scala -"Hello,\nWorld!" -"This string contains a \" character." -``` +> ```scala +> "Hello,\nWorld!" +> "This string contains a \" character." +> ``` #### Multi-Line String Literals @@ -461,45 +449,43 @@ must not necessarily be printable; newlines or other control characters are also permitted. Unicode escapes work as everywhere else, but none of the escape sequences [here](#escape-sequences) are interpreted. -### Example - -```scala - """the present string - spans three - lines.""" -``` - -This would produce the string: - -```scala -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 - -```scala - """the present string - |spans three - |lines.""".stripMargin -``` - -evaluates to - -```scala -the present string -spans three -lines. -``` - -Method `stripMargin` is defined in class -[scala.collection.immutable.StringLike](http://www.scala-lang.org/api/current/#scala.collection.immutable.StringLike). -Because there is a predefined -[implicit conversion](06-expressions.html#implicit-conversions) from `String` to -`StringLike`, the method is applicable to all strings. +> ```scala +> """the present string +> spans three +> lines.""" +> ``` +> +> This would produce the string: +> +> ```scala +> 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 +> +> ```scala +> """the present string +> |spans three +> |lines.""".stripMargin +> ``` +> +> evaluates to +> +> ```scala +> the present string +> spans three +> lines. +> ``` +> +> Method `stripMargin` is defined in class +> [scala.collection.immutable.StringLike](http://www.scala-lang.org/api/current/#scala.collection.immutable.StringLike). +> Because there is a predefined +> [implicit conversion](06-expressions.html#implicit-conversions) from `String` to +> `StringLike`, the method is applicable to all strings. ### Escape Sequences @@ -587,15 +573,13 @@ The scanner switches from XML mode to Scala mode if either Note that no Scala tokens are constructed in XML mode, and that comments are interpreted as text. -### Example - -The following value definition uses an XML literal with two embedded -Scala expressions: - -```scala -val b = - The Scala Language Specification - {scalaBook.version} - {scalaBook.authors.mkList("", ", ", "")} - -``` +> The following value definition uses an XML literal with two embedded +> Scala expressions: +> +> ```scala +> val b = +> The Scala Language Specification +> {scalaBook.version} +> {scalaBook.authors.mkList("", ", ", "")} +> +> ``` diff --git a/spec/02-identifiers-names-and-scopes.md b/spec/02-identifiers-names-and-scopes.md index 62d326934f..0a9c5dfe77 100644 --- a/spec/02-identifiers-names-and-scopes.md +++ b/spec/02-identifiers-names-and-scopes.md @@ -1,5 +1,5 @@ --- -title: Identifiers, Names and Scopes +title: Identifiers, Names & Scopes layout: default chapter: 2 --- @@ -69,7 +69,7 @@ the member of the type $T$ of $e$ which has the name $x$ in the same namespace as the identifier. It is an error if $T$ is not a [value type](03-types.html#value-types). The type of $e.x$ is the member type of the referenced entity in $T$. -### Example +###### Example Assume the following two definitions of objects named `X` in packages `P` and `Q`. diff --git a/spec/03-types.md b/spec/03-types.md index 5658e15f44..9741286a5d 100644 --- a/spec/03-types.md +++ b/spec/03-types.md @@ -147,7 +147,7 @@ A qualified type designator has the form `p.t` where `p` is a [path](#paths) and _t_ is a type name. Such a type designator is equivalent to the type projection `p.type#t`. -### Example +###### Example Some type designators and their expansions are listed below. We assume a local type parameter $t$, a value `maintable` @@ -178,7 +178,8 @@ well-formed if each actual type parameter _conforms to its bounds_, i.e. $\sigma L_i <: T_i <: \sigma U_i$ where $\sigma$ is the substitution $[ a_1 := T_1 , \ldots , a_n := T_n ]$. -### Example Parameterized Types +###### Example Parameterized Types + Given the partial type definitions: ```scala @@ -202,7 +203,7 @@ F[List, Int] G[S, String] ``` -### Example +###### Example Given the [above type definitions](#example-parameterized-types), the following types are ill-formed: @@ -255,10 +256,10 @@ AnnotType ::= SimpleType {Annotation} ``` An annotated type $T$ $a_1, \ldots, a_n$ -attaches [annotations](11-user-defined-annotations.html#user-defined-annotations) +attaches [annotations](11-annotations.html#user-defined-annotations) $a_1 , \ldots , a_n$ to the type $T$. -### Example +###### Example The following type adds the `@suspendable` annotation to the type `String`: @@ -304,7 +305,7 @@ A compound type may also consist of just a refinement $\\{ R \\}$ with no preceding component types. Such a type is equivalent to `AnyRef` $\\{ R \\}$. -### Example +###### Example The following example shows how to declare and use a method which a parameter type that contains a refinement with structural declarations. @@ -500,7 +501,7 @@ or [tuple types](#tuple-types). Their expansion is then the expansion in the equivalent parameterized type. -### Example +###### Example Assume the class definitions @@ -524,7 +525,7 @@ An alternative formulation of the first type above using wildcard syntax is: Ref[_ <: java.lang.Number] ``` -### Example +###### Example The type `List[List[_]]` is equivalent to the existential type @@ -532,7 +533,7 @@ The type `List[List[_]]` is equivalent to the existential type List[List[t] forSome { type t }] . ``` -### Example +###### Example Assume a covariant type @@ -658,7 +659,7 @@ same name, we model An overloaded type consisting of type alternatives $T_1 \commadots T_n (n \geq 2)$ is denoted internally $T_1 \overload \ldots \overload T_n$. -### Example +###### Example ``` def println: Unit def println(s: String): Unit = $\ldots$ @@ -676,7 +677,7 @@ println: => Unit $\overload$ [A] (A) (A => String) Unit ``` -### Example +###### Example ``` def f(x: T): T = $\ldots$ val f = 0 diff --git a/spec/04-basic-declarations-and-definitions.md b/spec/04-basic-declarations-and-definitions.md index 65d79dd5f4..7fb5427d36 100644 --- a/spec/04-basic-declarations-and-definitions.md +++ b/spec/04-basic-declarations-and-definitions.md @@ -1,5 +1,5 @@ --- -title: Basic Declarations and Definitions +title: Basic Declarations & Definitions layout: default chapter: 4 --- @@ -563,7 +563,7 @@ abstract class Sequence[+A] { } ``` -### Example +###### Example ```scala abstract class OutputChannel[-A] { diff --git a/spec/05-classes-and-objects.md b/spec/05-classes-and-objects.md index 8681c93193..a6908ba39f 100644 --- a/spec/05-classes-and-objects.md +++ b/spec/05-classes-and-objects.md @@ -1,5 +1,5 @@ --- -title: Classes and Objects +title: Classes & Objects layout: default chapter: 5 --- @@ -368,7 +368,7 @@ it is possible to add new defaults (if the corresponding parameter in the superclass does not have a default) or to override the defaults of the superclass (otherwise). -### Example +###### Example Consider the definitions: @@ -699,7 +699,7 @@ Here, parameter section is called _polymorphic_, otherwise it is called _monomorphic_. - $as$ is a possibly empty sequence of - [annotations](11-user-defined-annotations.html#user-defined-annotations). + [annotations](11-annotations.html#user-defined-annotations). If any annotations are given, they apply to the primary constructor of the class. - $m$ is an [access modifier](#modifiers) such as @@ -744,7 +744,7 @@ which when applied to parameters conforming to types $\mathit{ps}$ initializes instances of type `$c$[$\mathit{tps}\,$]` by evaluating the template $t$. -### Example +###### Example The following example illustrates `val` and `var` parameters of a class `C`: ```scala @@ -990,7 +990,7 @@ it is not statically known at the time the trait is defined. If $D$ is not a trait, then its actual supertype is simply its least proper supertype (which is statically known). -### Example +###### Example The following trait defines the property of being comparable to objects of some type. It contains an abstract method `<` and default implementations of the other diff --git a/spec/06-expressions.md b/spec/06-expressions.md index 133ec3c8e5..db206631a8 100644 --- a/spec/06-expressions.md +++ b/spec/06-expressions.md @@ -205,7 +205,7 @@ to the type or method of $x$ in the parent trait of $C$ whose simple name is $T$. That member must be uniquely defined. If it is a method, it must be concrete. -### Example +###### Example Consider the following class definitions ```scala @@ -778,7 +778,7 @@ Expr1 ::= PostfixExpr `:' Annotation {Annotation} ``` An annotated expression `$e$: @$a_1$ $\ldots$ @$a_n$` -attaches [annotations](11-user-defined-annotations.html#user-defined-annotations) $a_1 , \ldots , a_n$ to the +attaches [annotations](11-annotations.html#user-defined-annotations) $a_1 , \ldots , a_n$ to the expression $e$. ## Assignments @@ -815,7 +815,7 @@ Here are some assignment expressions and their equivalent expansions. |`x.f(i) = e` | `x.f.update(i, e)` | |`x.f(i, j) = e` | `x.f.update(i, j, e)`| -### Example Imperative Matrix Multiplication +###### Example Imperative Matrix Multiplication Here is the usual imperative code for matrix multiplication. @@ -1221,9 +1221,9 @@ In that case, a fresh name for the parameter is chosen arbitrarily. A named parameter of an anonymous function may be optionally preceded by an `implicit` modifier. In that case the parameter is -labeled [`implicit`](07-implicit-parameters-and-views.html#implicit-parameters-and-views); however the +labeled [`implicit`](07-implicits.html#implicit-parameters-and-views); however the parameter section itself does not count as an implicit parameter -section in the sense defined [here](07-implicit-parameters-and-views.html#implicit-parameters). Hence, arguments to +section in the sense defined [here](07-implicits.html#implicit-parameters). Hence, arguments to anonymous functions always have to be given explicitly. ###### Example @@ -1341,7 +1341,7 @@ available implicit conversions are given in the next two sub-sections. We say, a type $T$ is _compatible_ to a type $U$ if $T$ weakly conforms to $U$ after applying [eta-expansion](#eta-expansion) and -[view applications](07-implicit-parameters-and-views.html#views). +[view applications](07-implicits.html#views). ### Value Conversions @@ -1389,7 +1389,7 @@ term `{ $e$; () }`. ###### View Application If none of the previous conversions applies, and $e$'s type does not conform to the expected type $\mathit{pt}$, it is attempted to convert -$e$ to the expected type with a [view](07-implicit-parameters-and-views.html#views). +$e$ to the expected type with a [view](07-implicits.html#views). ###### Dynamic Member Selection If none of the previous conversions applies, and $e$ is a prefix @@ -1408,7 +1408,7 @@ type $T$ by evaluating the expression to which $m$ is bound. ###### Implicit Application If the method takes only implicit parameters, implicit -arguments are passed following the rules [here](07-implicit-parameters-and-views.html#implicit-parameters). +arguments are passed following the rules [here](07-implicits.html#implicit-parameters). ###### Eta Expansion Otherwise, if the method is not a constructor, diff --git a/spec/07-implicit-parameters-and-views.md b/spec/07-implicit-parameters-and-views.md deleted file mode 100644 index 27a50cf058..0000000000 --- a/spec/07-implicit-parameters-and-views.md +++ /dev/null @@ -1,432 +0,0 @@ ---- -title: Implicit Parameters and Views -layout: default -chapter: 7 ---- - -# Implicit Parameters and Views - -## The Implicit Modifier - -```ebnf -LocalModifier ::= ‘implicit’ -ParamClauses ::= {ParamClause} [nl] ‘(’ ‘implicit’ Params ‘)’ -``` - -Template members and parameters labeled with an `implicit` -modifier can be passed to [implicit parameters](#implicit-parameters) -and can be used as implicit conversions called [views](#views). -The `implicit` modifier is illegal for all -type members, as well as for [top-level objects](09-top-level-definitions.html#packagings). - -### Example Monoid -The following code defines an abstract class of monoids and -two concrete implementations, `StringMonoid` and -`IntMonoid`. The two implementations are marked implicit. - -```scala -abstract class Monoid[A] extends SemiGroup[A] { - def unit: A - def add(x: A, y: A): A -} -object Monoids { - implicit object stringMonoid extends Monoid[String] { - def add(x: String, y: String): String = x.concat(y) - def unit: String = "" - } - implicit object intMonoid extends Monoid[Int] { - def add(x: Int, y: Int): Int = x + y - def unit: Int = 0 - } -} -``` - -## Implicit Parameters - -An implicit parameter list -`(implicit $p_1$,$\ldots$,$p_n$)` of a method marks the parameters $p_1 , \ldots , p_n$ as -implicit. A method or constructor can have only one implicit parameter -list, and it must be the last parameter list given. - -A method with implicit parameters can be applied to arguments just -like a normal method. In this case the `implicit` label has no -effect. However, if such a method misses arguments for its implicit -parameters, such arguments will be automatically provided. - -The actual arguments that are eligible to be passed to an implicit -parameter of type $T$ fall into two categories. First, eligible are -all identifiers $x$ that can be accessed at the point of the method -call without a prefix and that denote an -[implicit definition](#the-implicit-modifier) -or an implicit parameter. An eligible -identifier may thus be a local name, or a member of an enclosing -template, or it may be have been made accessible without a prefix -through an [import clause](04-basic-declarations-and-definitions.html#import-clauses). If there are no eligible -identifiers under this rule, then, second, eligible are also all -`implicit` members of some object that belongs to the implicit -scope of the implicit parameter's type, $T$. - -The _implicit scope_ of a type $T$ consists of all [companion modules](05-classes-and-objects.html#object-definitions) of classes that are associated with the implicit parameter's type. -Here, we say a class $C$ is _associated_ with a type $T$ if it is a [base class](05-classes-and-objects.html#class-linearization) of some part of $T$. - -The _parts_ of a type $T$ are: - -- if $T$ is a compound type `$T_1$ with $\ldots$ with $T_n$`, - the union of the parts of $T_1 , \ldots , T_n$, as well as $T$ itself; -- if $T$ is a parameterized type `$S$[$T_1 , \ldots , T_n$]`, - the union of the parts of $S$ and $T_1 , \ldots , T_n$; -- if $T$ is a singleton type `$p$.type`, - the parts of the type of $p$; -- if $T$ is a type projection `$S$#$U$`, - the parts of $S$ as well as $T$ itself; -- if $T$ is a type alias, the parts of its expansion; -- if $T$ is an abstract type, the parts of its upper bound; -- if $T$ denotes an implicit conversion to a type with a method with argument types $T_1 , \ldots , T_n$ and result type $U$, - the union of the parts of $T_1 , \ldots , T_n$ and $U$; -- the parts of quantified (existential or univeral) and annotated types are defined as the parts of the underlying types (e.g., the parts of `T forSome { ... }` are the parts of `T`); -- in all other cases, just $T$ itself. - -Note that packages are internally represented as classes with companion modules to hold the package members. -Thus, implicits defined in a package object are part of the implicit scope of a type prefixed by that package. - -If there are several eligible arguments which match the implicit -parameter's type, a most specific one will be chosen using the rules -of static [overloading resolution](06-expressions.html#overloading-resolution). -If the parameter has a default argument and no implicit argument can -be found the default argument is used. - -###### Example -Assuming the classes from the [`Monoid` example](#example-monoid), here is a -method which computes the sum of a list of elements using the -monoid's `add` and `unit` operations. - -```scala -def sum[A](xs: List[A])(implicit m: Monoid[A]): A = - if (xs.isEmpty) m.unit - else m.add(xs.head, sum(xs.tail)) -``` - -The monoid in question is marked as an implicit parameter, and can therefore -be inferred based on the type of the list. -Consider for instance the call `sum(List(1, 2, 3))` -in a context where `stringMonoid` and `intMonoid` -are visible. We know that the formal type parameter `a` of -`sum` needs to be instantiated to `Int`. The only -eligible object which matches the implicit formal parameter type -`Monoid[Int]` is `intMonoid` so this object will -be passed as implicit parameter. - -This discussion also shows that implicit parameters are inferred after -any type arguments are [inferred](06-expressions.html#local-type-inference). - -Implicit methods can themselves have implicit parameters. An example -is the following method from module `scala.List`, which injects -lists into the `scala.Ordered` class, provided the element -type of the list is also convertible to this type. - -```scala -implicit def list2ordered[A](x: List[A]) - (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = - ... -``` - -Assume in addition a method - -```scala -implicit def int2ordered(x: Int): Ordered[Int] -``` - -that injects integers into the `Ordered` class. We can now -define a `sort` method over ordered lists: - -```scala -def sort[A](xs: List[A])(implicit a2ordered: A => Ordered[A]) = ... -``` - -We can apply `sort` to a list of lists of integers -`yss: List[List[Int]]` -as follows: - -```scala -sort(yss) -``` - -The call above will be completed by passing two nested implicit arguments: - -```scala -sort(yss)(xs: List[Int] => list2ordered[Int](xs)(int2ordered)) . -``` - -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: - -```scala -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: - -```scala -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 -searched. Whenever an implicit argument for type $T$ is searched, the -“core type” of $T$ is added to the stack. Here, the _core type_ -of $T$ is $T$ with aliases expanded, top-level type [annotations](11-user-defined-annotations.html#user-defined-annotations) and -[refinements](03-types.html#compound-types) removed, and occurrences -of top-level existentially bound variables replaced by their upper -bounds. The core type is removed from the stack once the search for -the implicit argument either definitely fails or succeeds. Everytime a -core type is added to the stack, it is checked that this type does not -dominate any of the other types in the set. - -Here, a core type $T$ _dominates_ a type $U$ if $T$ is -[equivalent](03-types.html#equivalence) -to $U$, or if the top-level type constructors of $T$ and $U$ have a -common element and $T$ is more complex than $U$. - -The set of _top-level type constructors_ $\mathit{ttcs}(T)$ of a type $T$ depends on the form of -the type: - -- For a type designator, $\mathit{ttcs}(p.c) ~=~ \{c\}$; -- For a parameterized type, $\mathit{ttcs}(p.c[\mathit{targs}]) ~=~ \{c\}$; -- For a singleton type, $\mathit{ttcs}(p.type) ~=~ \mathit{ttcs}(T)$, provided $p$ has type $T$; -- For a compound type, `$\mathit{ttcs}(T_1$ with $\ldots$ with $T_n)$` $~=~ \mathit{ttcs}(T_1) \cup \ldots \cup \mathit{ttcs}(T_n)$. - -The _complexity_ $\operatorname{complexity}(T)$ of a core type is an integer which also depends on the form of -the type: - -- For a type designator, $\operatorname{complexity}(p.c) ~=~ 1 + \operatorname{complexity}(p)$ -- For a parameterized type, $\operatorname{complexity}(p.c[\mathit{targs}]) ~=~ 1 + \Sigma \operatorname{complexity}(\mathit{targs})$ -- For a singleton type denoting a package $p$, $\operatorname{complexity}(p.type) ~=~ 0$ -- For any other singleton type, $\operatorname{complexity}(p.type) ~=~ 1 + \operatorname{complexity}(T)$, provided $p$ has type $T$; -- For a compound type, `$\operatorname{complexity}(T_1$ with $\ldots$ with $T_n)$` $= \Sigma\operatorname{complexity}(T_i)$ - -###### Example -When typing `sort(xs)` for some list `xs` of type `List[List[List[Int]]]`, -the sequence of types for -which implicit arguments are searched is - -```scala -List[List[Int]] => Ordered[List[List[Int]]], -List[Int] => Ordered[List[Int]] -Int => Ordered[Int] -``` - -All types share the common type constructor `scala.Function1`, -but the complexity of the each new type is lower than the complexity of the previous types. -Hence, the code typechecks. - -###### Example -Let `ys` be a list of some type which cannot be converted -to `Ordered`. For instance: - -```scala -val ys = List(new IllegalArgumentException, new ClassCastException, new Error) -``` - -Assume that the definition of `magic` above is in scope. Then the sequence -of types for which implicit arguments are searched is - -```scala -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. - -## Views - -Implicit parameters and methods can also define implicit conversions -called views. A _view_ from type $S$ to type $T$ is -defined by an implicit value which has function type -`$S$=>$T$` or `(=>$S$)=>$T$` or by a method convertible to a value of that -type. - -Views are applied in three situations: - -1. If an expression $e$ is of type $T$, and $T$ does not conform to the - expression's expected type $\mathit{pt}$. In this case an implicit $v$ is - searched which is applicable to $e$ and whose result type conforms to - $\mathit{pt}$. The search proceeds as in the case of implicit parameters, - where the implicit scope is the one of `$T$ => $\mathit{pt}$`. If - such a view is found, the expression $e$ is converted to - `$v$($e$)`. -1. In a selection $e.m$ with $e$ of type $T$, if the selector $m$ does - not denote an accessible member of $T$. In this case, a view $v$ is searched - which is applicable to $e$ and whose result contains a member named - $m$. The search proceeds as in the case of implicit parameters, where - the implicit scope is the one of $T$. If such a view is found, the - selection $e.m$ is converted to `$v$($e$).$m$`. -1. In a selection $e.m(\mathit{args})$ with $e$ of type $T$, if the selector - $m$ denotes some member(s) of $T$, but none of these members is applicable to the arguments - $\mathit{args}$. In this case a view $v$ is searched which is applicable to $e$ - and whose result contains a method $m$ which is applicable to $\mathit{args}$. - The search proceeds as in the case of implicit parameters, where - the implicit scope is the one of $T$. If such a view is found, the - selection $e.m$ is converted to `$v$($e$).$m(\mathit{args})$`. - -The implicit view, if it is found, can accept is argument $e$ as a -call-by-value or as a call-by-name parameter. However, call-by-value -implicits take precedence over call-by-name implicits. - -As for implicit parameters, overloading resolution is applied -if there are several possible candidates (of either the call-by-value -or the call-by-name category). - -### Example Ordered -Class `scala.Ordered[A]` contains a method - -```scala - 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 - -```scala - xs <= ys -``` - -is legal, and is expanded to: - -```scala - list2ordered(xs)(int2ordered).<= - (ys) - (xs => list2ordered(xs)(int2ordered)) -``` - -The first application of `list2ordered` converts the list -`xs` to an instance of class `Ordered`, whereas the second -occurrence is part of an implicit parameter passed to the `<=` -method. - -## Context Bounds and View Bounds - -```ebnf - 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 -instantiated to any type $S$ which is convertible by application of a -view to the bound $T$. - -A type parameter $A$ of a method or non-trait class may also have one -or more context bounds `$A$ : $T$`. In this case the type parameter may be -instantiated to any type $S$ for which _evidence_ exists at the -instantiation point that $S$ satisfies the bound $T$. Such evidence -consists of an implicit value with type $T[S]$. - -A method or class containing type parameters with view or context bounds is treated as being -equivalent to a method with implicit parameters. Consider first the case of a -single parameter with view and/or context bounds such as: - -```scala -def $f$[$A$ <% $T_1$ ... <% $T_m$ : $U_1$ : $U_n$]($\mathit{ps}$): $R$ = ... -``` - -Then the method definition above is expanded to - -```scala -def $f$[$A$]($\mathit{ps}$)(implicit $v_1$: $A$ => $T_1$, ..., $v_m$: $A$ => $T_m$, - $w_1$: $U_1$[$A$], ..., $w_n$: $U_n$[$A$]): $R$ = ... -``` - -where the $v_i$ and $w_j$ are fresh names for the newly introduced implicit parameters. These -parameters are called _evidence parameters_. - -If a class or method has several view- or context-bounded type parameters, each -such type parameter is expanded into evidence parameters in the order -they appear and all the resulting evidence parameters are concatenated -in one implicit parameter section. Since traits do not take -constructor parameters, this translation does not work for them. -Consequently, type-parameters in traits may not be view- or context-bounded. -Also, a method or class with view- or context bounds may not define any -additional implicit parameters. - -###### Example -The `<=` method from the [`Ordered` example](#example-ordered) can be declared -more concisely as follows: - -```scala -def <= [B >: A <% Ordered[B]](that: B): Boolean -``` - -## Manifests - -Manifests are type descriptors that can be automatically generated by -the Scala compiler as arguments to implicit parameters. The Scala -standard library contains a hierarchy of four manifest classes, -with `OptManifest` -at the top. Their signatures follow the outline below. - -```scala -trait OptManifest[+T] -object NoManifest extends OptManifest[Nothing] -trait ClassManifest[T] extends OptManifest[T] -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]$_, -according to the following rules. - -First if there is already an implicit argument that matches $M[T]$, this -argument is selected. - -Otherwise, let $\mathit{Mobj}$ be the companion object `scala.reflect.Manifest` -if $M$ is trait `Manifest`, or be -the companion object `scala.reflect.ClassManifest` otherwise. Let $M'$ be the trait -`Manifest` if $M$ is trait `Manifest`, or be the trait `OptManifest` otherwise. -Then the following rules apply. - -1. If $T$ is a value class or one of the classes `Any`, `AnyVal`, `Object`, - `Null`, or `Nothing`, - a manifest for it is generated by selecting - the corresponding manifest value `Manifest.$T$`, which exists in the - `Manifest` module. -1. If $T$ is an instance of `Array[$S$]`, a manifest is generated - with the invocation `$\mathit{Mobj}$.arrayType[S](m)`, where $m$ is the manifest - determined for $M[S]$. -1. If $T$ is some other class type $S$#$C[U_1, \ldots, U_n]$ where the prefix - type $S$ cannot be statically determined from the class $C$, - a manifest is generated with the invocation `$\mathit{Mobj}$.classType[T]($m_0$, classOf[T], $ms$)` - where $m_0$ is the manifest determined for $M'[S]$ and $ms$ are the - manifests determined for $M'[U_1], \ldots, M'[U_n]$. -1. If $T$ is some other class type with type arguments $U_1 , \ldots , U_n$, - a manifest is generated - with the invocation `$\mathit{Mobj}$.classType[T](classOf[T], $ms$)` - where $ms$ are the - manifests determined for $M'[U_1] , \ldots , M'[U_n]$. -1. If $T$ is a singleton type `$p$.type`, a manifest is generated with - the invocation `$\mathit{Mobj}$.singleType[T]($p$)` -1. If $T$ is a refined type $T' \{ R \}$, a manifest is generated for $T'$. - (That is, refinements are never reflected in manifests). -1. If $T$ is an intersection type - `$T_1$ with $, \ldots ,$ with $T_n$` - where $n > 1$, the result depends on whether a full manifest is - to be determined or not. - If $M$ is trait `Manifest`, then - a manifest is generated with the invocation - `Manifest.intersectionType[T]($ms$)` where $ms$ are the manifests - determined for $M[T_1] , \ldots , M[T_n]$. - Otherwise, if $M$ is trait `ClassManifest`, - then a manifest is generated for the [intersection dominator](03-types.html#type-erasure) - of the types $T_1 , \ldots , T_n$. -1. If $T$ is some other type, then if $M$ is trait `OptManifest`, - a manifest is generated from the designator `scala.reflect.NoManifest`. - If $M$ is a type different from `OptManifest`, a static error results. diff --git a/spec/07-implicits.md b/spec/07-implicits.md new file mode 100644 index 0000000000..5e10373959 --- /dev/null +++ b/spec/07-implicits.md @@ -0,0 +1,434 @@ +--- +title: Implicits +layout: default +chapter: 7 +--- + +# Implicits + +## The Implicit Modifier + +```ebnf +LocalModifier ::= ‘implicit’ +ParamClauses ::= {ParamClause} [nl] ‘(’ ‘implicit’ Params ‘)’ +``` + +Template members and parameters labeled with an `implicit` +modifier can be passed to [implicit parameters](#implicit-parameters) +and can be used as implicit conversions called [views](#views). +The `implicit` modifier is illegal for all +type members, as well as for [top-level objects](09-top-level-definitions.html#packagings). + +###### Example Monoid + +The following code defines an abstract class of monoids and +two concrete implementations, `StringMonoid` and +`IntMonoid`. The two implementations are marked implicit. + +```scala +abstract class Monoid[A] extends SemiGroup[A] { + def unit: A + def add(x: A, y: A): A +} +object Monoids { + implicit object stringMonoid extends Monoid[String] { + def add(x: String, y: String): String = x.concat(y) + def unit: String = "" + } + implicit object intMonoid extends Monoid[Int] { + def add(x: Int, y: Int): Int = x + y + def unit: Int = 0 + } +} +``` + +## Implicit Parameters + +An implicit parameter list +`(implicit $p_1$,$\ldots$,$p_n$)` of a method marks the parameters $p_1 , \ldots , p_n$ as +implicit. A method or constructor can have only one implicit parameter +list, and it must be the last parameter list given. + +A method with implicit parameters can be applied to arguments just +like a normal method. In this case the `implicit` label has no +effect. However, if such a method misses arguments for its implicit +parameters, such arguments will be automatically provided. + +The actual arguments that are eligible to be passed to an implicit +parameter of type $T$ fall into two categories. First, eligible are +all identifiers $x$ that can be accessed at the point of the method +call without a prefix and that denote an +[implicit definition](#the-implicit-modifier) +or an implicit parameter. An eligible +identifier may thus be a local name, or a member of an enclosing +template, or it may be have been made accessible without a prefix +through an [import clause](04-basic-declarations-and-definitions.html#import-clauses). If there are no eligible +identifiers under this rule, then, second, eligible are also all +`implicit` members of some object that belongs to the implicit +scope of the implicit parameter's type, $T$. + +The _implicit scope_ of a type $T$ consists of all [companion modules](05-classes-and-objects.html#object-definitions) of classes that are associated with the implicit parameter's type. +Here, we say a class $C$ is _associated_ with a type $T$ if it is a [base class](05-classes-and-objects.html#class-linearization) of some part of $T$. + +The _parts_ of a type $T$ are: + +- if $T$ is a compound type `$T_1$ with $\ldots$ with $T_n$`, + the union of the parts of $T_1 , \ldots , T_n$, as well as $T$ itself; +- if $T$ is a parameterized type `$S$[$T_1 , \ldots , T_n$]`, + the union of the parts of $S$ and $T_1 , \ldots , T_n$; +- if $T$ is a singleton type `$p$.type`, + the parts of the type of $p$; +- if $T$ is a type projection `$S$#$U$`, + the parts of $S$ as well as $T$ itself; +- if $T$ is a type alias, the parts of its expansion; +- if $T$ is an abstract type, the parts of its upper bound; +- if $T$ denotes an implicit conversion to a type with a method with argument types $T_1 , \ldots , T_n$ and result type $U$, + the union of the parts of $T_1 , \ldots , T_n$ and $U$; +- the parts of quantified (existential or univeral) and annotated types are defined as the parts of the underlying types (e.g., the parts of `T forSome { ... }` are the parts of `T`); +- in all other cases, just $T$ itself. + +Note that packages are internally represented as classes with companion modules to hold the package members. +Thus, implicits defined in a package object are part of the implicit scope of a type prefixed by that package. + +If there are several eligible arguments which match the implicit +parameter's type, a most specific one will be chosen using the rules +of static [overloading resolution](06-expressions.html#overloading-resolution). +If the parameter has a default argument and no implicit argument can +be found the default argument is used. + +###### Example +Assuming the classes from the [`Monoid` example](#example-monoid), here is a +method which computes the sum of a list of elements using the +monoid's `add` and `unit` operations. + +```scala +def sum[A](xs: List[A])(implicit m: Monoid[A]): A = + if (xs.isEmpty) m.unit + else m.add(xs.head, sum(xs.tail)) +``` + +The monoid in question is marked as an implicit parameter, and can therefore +be inferred based on the type of the list. +Consider for instance the call `sum(List(1, 2, 3))` +in a context where `stringMonoid` and `intMonoid` +are visible. We know that the formal type parameter `a` of +`sum` needs to be instantiated to `Int`. The only +eligible object which matches the implicit formal parameter type +`Monoid[Int]` is `intMonoid` so this object will +be passed as implicit parameter. + +This discussion also shows that implicit parameters are inferred after +any type arguments are [inferred](06-expressions.html#local-type-inference). + +Implicit methods can themselves have implicit parameters. An example +is the following method from module `scala.List`, which injects +lists into the `scala.Ordered` class, provided the element +type of the list is also convertible to this type. + +```scala +implicit def list2ordered[A](x: List[A]) + (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = + ... +``` + +Assume in addition a method + +```scala +implicit def int2ordered(x: Int): Ordered[Int] +``` + +that injects integers into the `Ordered` class. We can now +define a `sort` method over ordered lists: + +```scala +def sort[A](xs: List[A])(implicit a2ordered: A => Ordered[A]) = ... +``` + +We can apply `sort` to a list of lists of integers +`yss: List[List[Int]]` +as follows: + +```scala +sort(yss) +``` + +The call above will be completed by passing two nested implicit arguments: + +```scala +sort(yss)(xs: List[Int] => list2ordered[Int](xs)(int2ordered)) . +``` + +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: + +```scala +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: + +```scala +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 +searched. Whenever an implicit argument for type $T$ is searched, the +“core type” of $T$ is added to the stack. Here, the _core type_ +of $T$ is $T$ with aliases expanded, top-level type [annotations](11-annotations.html#user-defined-annotations) and +[refinements](03-types.html#compound-types) removed, and occurrences +of top-level existentially bound variables replaced by their upper +bounds. The core type is removed from the stack once the search for +the implicit argument either definitely fails or succeeds. Everytime a +core type is added to the stack, it is checked that this type does not +dominate any of the other types in the set. + +Here, a core type $T$ _dominates_ a type $U$ if $T$ is +[equivalent](03-types.html#equivalence) +to $U$, or if the top-level type constructors of $T$ and $U$ have a +common element and $T$ is more complex than $U$. + +The set of _top-level type constructors_ $\mathit{ttcs}(T)$ of a type $T$ depends on the form of +the type: + +- For a type designator, $\mathit{ttcs}(p.c) ~=~ \{c\}$; +- For a parameterized type, $\mathit{ttcs}(p.c[\mathit{targs}]) ~=~ \{c\}$; +- For a singleton type, $\mathit{ttcs}(p.type) ~=~ \mathit{ttcs}(T)$, provided $p$ has type $T$; +- For a compound type, `$\mathit{ttcs}(T_1$ with $\ldots$ with $T_n)$` $~=~ \mathit{ttcs}(T_1) \cup \ldots \cup \mathit{ttcs}(T_n)$. + +The _complexity_ $\operatorname{complexity}(T)$ of a core type is an integer which also depends on the form of +the type: + +- For a type designator, $\operatorname{complexity}(p.c) ~=~ 1 + \operatorname{complexity}(p)$ +- For a parameterized type, $\operatorname{complexity}(p.c[\mathit{targs}]) ~=~ 1 + \Sigma \operatorname{complexity}(\mathit{targs})$ +- For a singleton type denoting a package $p$, $\operatorname{complexity}(p.type) ~=~ 0$ +- For any other singleton type, $\operatorname{complexity}(p.type) ~=~ 1 + \operatorname{complexity}(T)$, provided $p$ has type $T$; +- For a compound type, `$\operatorname{complexity}(T_1$ with $\ldots$ with $T_n)$` $= \Sigma\operatorname{complexity}(T_i)$ + +###### Example +When typing `sort(xs)` for some list `xs` of type `List[List[List[Int]]]`, +the sequence of types for +which implicit arguments are searched is + +```scala +List[List[Int]] => Ordered[List[List[Int]]], +List[Int] => Ordered[List[Int]] +Int => Ordered[Int] +``` + +All types share the common type constructor `scala.Function1`, +but the complexity of the each new type is lower than the complexity of the previous types. +Hence, the code typechecks. + +###### Example +Let `ys` be a list of some type which cannot be converted +to `Ordered`. For instance: + +```scala +val ys = List(new IllegalArgumentException, new ClassCastException, new Error) +``` + +Assume that the definition of `magic` above is in scope. Then the sequence +of types for which implicit arguments are searched is + +```scala +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. + +## Views + +Implicit parameters and methods can also define implicit conversions +called views. A _view_ from type $S$ to type $T$ is +defined by an implicit value which has function type +`$S$=>$T$` or `(=>$S$)=>$T$` or by a method convertible to a value of that +type. + +Views are applied in three situations: + +1. If an expression $e$ is of type $T$, and $T$ does not conform to the + expression's expected type $\mathit{pt}$. In this case an implicit $v$ is + searched which is applicable to $e$ and whose result type conforms to + $\mathit{pt}$. The search proceeds as in the case of implicit parameters, + where the implicit scope is the one of `$T$ => $\mathit{pt}$`. If + such a view is found, the expression $e$ is converted to + `$v$($e$)`. +1. In a selection $e.m$ with $e$ of type $T$, if the selector $m$ does + not denote an accessible member of $T$. In this case, a view $v$ is searched + which is applicable to $e$ and whose result contains a member named + $m$. The search proceeds as in the case of implicit parameters, where + the implicit scope is the one of $T$. If such a view is found, the + selection $e.m$ is converted to `$v$($e$).$m$`. +1. In a selection $e.m(\mathit{args})$ with $e$ of type $T$, if the selector + $m$ denotes some member(s) of $T$, but none of these members is applicable to the arguments + $\mathit{args}$. In this case a view $v$ is searched which is applicable to $e$ + and whose result contains a method $m$ which is applicable to $\mathit{args}$. + The search proceeds as in the case of implicit parameters, where + the implicit scope is the one of $T$. If such a view is found, the + selection $e.m$ is converted to `$v$($e$).$m(\mathit{args})$`. + +The implicit view, if it is found, can accept is argument $e$ as a +call-by-value or as a call-by-name parameter. However, call-by-value +implicits take precedence over call-by-name implicits. + +As for implicit parameters, overloading resolution is applied +if there are several possible candidates (of either the call-by-value +or the call-by-name category). + +###### Example Ordered + +Class `scala.Ordered[A]` contains a method + +```scala + 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 + +```scala + xs <= ys +``` + +is legal, and is expanded to: + +```scala + list2ordered(xs)(int2ordered).<= + (ys) + (xs => list2ordered(xs)(int2ordered)) +``` + +The first application of `list2ordered` converts the list +`xs` to an instance of class `Ordered`, whereas the second +occurrence is part of an implicit parameter passed to the `<=` +method. + +## Context Bounds and View Bounds + +```ebnf + 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 +instantiated to any type $S$ which is convertible by application of a +view to the bound $T$. + +A type parameter $A$ of a method or non-trait class may also have one +or more context bounds `$A$ : $T$`. In this case the type parameter may be +instantiated to any type $S$ for which _evidence_ exists at the +instantiation point that $S$ satisfies the bound $T$. Such evidence +consists of an implicit value with type $T[S]$. + +A method or class containing type parameters with view or context bounds is treated as being +equivalent to a method with implicit parameters. Consider first the case of a +single parameter with view and/or context bounds such as: + +```scala +def $f$[$A$ <% $T_1$ ... <% $T_m$ : $U_1$ : $U_n$]($\mathit{ps}$): $R$ = ... +``` + +Then the method definition above is expanded to + +```scala +def $f$[$A$]($\mathit{ps}$)(implicit $v_1$: $A$ => $T_1$, ..., $v_m$: $A$ => $T_m$, + $w_1$: $U_1$[$A$], ..., $w_n$: $U_n$[$A$]): $R$ = ... +``` + +where the $v_i$ and $w_j$ are fresh names for the newly introduced implicit parameters. These +parameters are called _evidence parameters_. + +If a class or method has several view- or context-bounded type parameters, each +such type parameter is expanded into evidence parameters in the order +they appear and all the resulting evidence parameters are concatenated +in one implicit parameter section. Since traits do not take +constructor parameters, this translation does not work for them. +Consequently, type-parameters in traits may not be view- or context-bounded. +Also, a method or class with view- or context bounds may not define any +additional implicit parameters. + +###### Example +The `<=` method from the [`Ordered` example](#example-ordered) can be declared +more concisely as follows: + +```scala +def <= [B >: A <% Ordered[B]](that: B): Boolean +``` + +## Manifests + +Manifests are type descriptors that can be automatically generated by +the Scala compiler as arguments to implicit parameters. The Scala +standard library contains a hierarchy of four manifest classes, +with `OptManifest` +at the top. Their signatures follow the outline below. + +```scala +trait OptManifest[+T] +object NoManifest extends OptManifest[Nothing] +trait ClassManifest[T] extends OptManifest[T] +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]$_, +according to the following rules. + +First if there is already an implicit argument that matches $M[T]$, this +argument is selected. + +Otherwise, let $\mathit{Mobj}$ be the companion object `scala.reflect.Manifest` +if $M$ is trait `Manifest`, or be +the companion object `scala.reflect.ClassManifest` otherwise. Let $M'$ be the trait +`Manifest` if $M$ is trait `Manifest`, or be the trait `OptManifest` otherwise. +Then the following rules apply. + +1. If $T$ is a value class or one of the classes `Any`, `AnyVal`, `Object`, + `Null`, or `Nothing`, + a manifest for it is generated by selecting + the corresponding manifest value `Manifest.$T$`, which exists in the + `Manifest` module. +1. If $T$ is an instance of `Array[$S$]`, a manifest is generated + with the invocation `$\mathit{Mobj}$.arrayType[S](m)`, where $m$ is the manifest + determined for $M[S]$. +1. If $T$ is some other class type $S$#$C[U_1, \ldots, U_n]$ where the prefix + type $S$ cannot be statically determined from the class $C$, + a manifest is generated with the invocation `$\mathit{Mobj}$.classType[T]($m_0$, classOf[T], $ms$)` + where $m_0$ is the manifest determined for $M'[S]$ and $ms$ are the + manifests determined for $M'[U_1], \ldots, M'[U_n]$. +1. If $T$ is some other class type with type arguments $U_1 , \ldots , U_n$, + a manifest is generated + with the invocation `$\mathit{Mobj}$.classType[T](classOf[T], $ms$)` + where $ms$ are the + manifests determined for $M'[U_1] , \ldots , M'[U_n]$. +1. If $T$ is a singleton type `$p$.type`, a manifest is generated with + the invocation `$\mathit{Mobj}$.singleType[T]($p$)` +1. If $T$ is a refined type $T' \{ R \}$, a manifest is generated for $T'$. + (That is, refinements are never reflected in manifests). +1. If $T$ is an intersection type + `$T_1$ with $, \ldots ,$ with $T_n$` + where $n > 1$, the result depends on whether a full manifest is + to be determined or not. + If $M$ is trait `Manifest`, then + a manifest is generated with the invocation + `Manifest.intersectionType[T]($ms$)` where $ms$ are the manifests + determined for $M[T_1] , \ldots , M[T_n]$. + Otherwise, if $M$ is trait `ClassManifest`, + then a manifest is generated for the [intersection dominator](03-types.html#type-erasure) + of the types $T_1 , \ldots , T_n$. +1. If $T$ is some other type, then if $M$ is trait `OptManifest`, + a manifest is generated from the designator `scala.reflect.NoManifest`. + If $M$ is a type different from `OptManifest`, a static error results. diff --git a/spec/08-pattern-matching.md b/spec/08-pattern-matching.md index e75bddc096..c494fbcef5 100644 --- a/spec/08-pattern-matching.md +++ b/spec/08-pattern-matching.md @@ -371,7 +371,7 @@ bound type variables in a typed pattern or constructor pattern. Inference takes into account the expected type of the pattern. -### Type parameter inference for typed patterns. +### Type parameter inference for typed patterns Assume a typed pattern $p: T'$. Let $T$ result from $T'$ where all wildcards in $T'$ are renamed to fresh variable names. Let $a_1 , \ldots , a_n$ be @@ -437,7 +437,7 @@ complexity of inferred bounds. Minimality and maximality of types have to be understood relative to the set of types of acceptable complexity. -#### Type parameter inference for constructor patterns. +### Type parameter inference for constructor patterns Assume a constructor pattern $C(p_1 , \ldots , p_n)$ where class $C$ has type type parameters $a_1 , \ldots , a_n$. These type parameters are inferred in the same way as for the typed pattern @@ -593,7 +593,7 @@ the compilation of pattern matching can emit warnings which diagnose that a given set of patterns is not exhaustive, i.e. that there is a possibility of a `MatchError` being raised at run-time. -### Example +###### Example Consider the following definitions of arithmetic terms: diff --git a/spec/10-xml-expressions-and-patterns.md b/spec/10-xml-expressions-and-patterns.md index 407b2b9a67..b70fb86471 100644 --- a/spec/10-xml-expressions-and-patterns.md +++ b/spec/10-xml-expressions-and-patterns.md @@ -1,5 +1,5 @@ --- -title: XML Expressions and Patterns +title: XML layout: default chapter: 10 --- diff --git a/spec/11-annotations.md b/spec/11-annotations.md new file mode 100644 index 0000000000..d66f24abf8 --- /dev/null +++ b/spec/11-annotations.md @@ -0,0 +1,174 @@ +--- +title: Annotations +layout: default +chapter: 11 +--- + +# Annotations + +```ebnf + Annotation ::= ‘@’ SimpleType {ArgumentExprs} + ConstrAnnotation ::= ‘@’ SimpleType ArgumentExprs +``` + +## Definition + +Annotations associate meta-information with definitions. +A simple annotation has the form `@$c$` or `@$c(a_1 , \ldots , a_n)$`. +Here, $c$ is a constructor of a class $C$, which must conform +to the class `scala.Annotation`. + +Annotations may apply to definitions or declarations, types, or +expressions. An annotation of a definition or declaration appears in +front of that definition. An annotation of a type appears after +that type. An annotation of an expression $e$ appears after the +expression $e$, separated by a colon. More than one annotation clause +may apply to an entity. The order in which these annotations are given +does not matter. + +Examples: + +```scala +@deprecated("Use D", "1.0") class C { ... } // Class annotation +@transient @volatile var m: Int // Variable annotation +String @local // Type annotation +(e: @unchecked) match { ... } // Expression annotation +``` + +## Predefined Annotations + +### Java Platform Annotations + +The meaning of annotation clauses is implementation-dependent. On the +Java platform, the following annotations have a standard meaning. + + * `@transient` Marks a field to be non-persistent; this is + equivalent to the `transient` + modifier in Java. + + * `@volatile` Marks a field which can change its value + outside the control of the program; this + is equivalent to the `volatile` + modifier in Java. + + * `@SerialVersionUID()` Attaches a serial version identifier (a + `long` constant) to a class. + This is equivalent to a the following field + definition in Java: + + ``` + private final static SerialVersionUID = + ``` + + * `@throws()` A Java compiler checks that a program contains handlers for checked exceptions + by analyzing which checked exceptions can result from execution of a method or + constructor. For each checked exception which is a possible result, the + `throws` + clause for the method or constructor must mention the class of that exception + or one of the superclasses of the class of that exception. + +### Java Beans Annotations + + * `@scala.beans.BeanProperty` When prefixed to a definition of some variable `X`, this + annotation causes getter and setter methods `getX`, `setX` + in the Java bean style to be added in the class containing the + variable. The first letter of the variable appears capitalized after + the `get` or `set`. When the annotation is added to the + definition of an immutable value definition `X`, only a getter is + generated. The construction of these methods is part of + code-generation; therefore, these methods become visible only once a + classfile for the containing class is generated. + + * `@scala.beans.BooleanBeanProperty` This annotation is equivalent to `scala.reflect.BeanProperty`, but + the generated getter method is named `isX` instead of `getX`. + +### Deprecation Annotations + + * `@deprecated(message: , since: )`
+ Marks a definition as deprecated. Accesses to the + defined entity will then cause a deprecated warning mentioning the + _message_ `` to be issued from the compiler. + The argument _since_ documents since when the definition should be considered deprecated.
+ Deprecated warnings are suppressed in code that belongs itself to a definition + that is labeled deprecated. + + * `@deprecatedName(name: )`
+ Marks a formal parameter name as deprecated. Invocations of this entity + using named parameter syntax refering to the deprecated parameter name cause a deprecation warning. + +### Scala Compiler Annotations + + * `@unchecked` When applied to the selector of a `match` expression, + this attribute suppresses any warnings about non-exhaustive pattern + 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 + warning because `Option` is a `sealed` class. + + * `@uncheckedStable` When applied a value declaration or definition, it allows the defined + value to appear in a path, even if its type is [volatile](03-types.html#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, + the reference `x.T` would be malformed. + + When applied to value declarations or definitions that have non-volatile + types, the annotation has no effect. + + * `@specialized` When applied to the definition of a type parameter, this annotation causes + the compiler + to generate specialized definitions for primitive types. An optional list of + primitive + types may be given, in which case specialization takes into account only + those types. + 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, the compiler will instead use the specialized version. + See the [specialization sid](http://docs.scala-lang.org/sips/completed/scala-specialization.html) for more details of the implementation. + +## User-defined Annotations + +Other annotations may be interpreted by platform- or +application-dependent tools. Class `scala.Annotation` has two +sub-traits which are used to indicate how these annotations are +retained. Instances of an annotation class inheriting from trait +`scala.ClassfileAnnotation` will be stored in the generated class +files. Instances of an annotation class inheriting from trait +`scala.StaticAnnotation` will be visible to the Scala type-checker +in every compilation unit where the annotated symbol is accessed. An +annotation class can inherit from both `scala.ClassfileAnnotation` +and `scala.StaticAnnotation`. If an annotation class inherits from +neither `scala.ClassfileAnnotation` nor +`scala.StaticAnnotation`, its instances are visible only locally +during the compilation run that analyzes them. + +Classes inheriting from `scala.ClassfileAnnotation` may be +subject to further restrictions in order to assure that they can be +mapped to the host environment. In particular, on both the Java and +the .NET platforms, such classes must be toplevel; i.e. they may not +be contained in another class or object. Additionally, on both +Java and .NET, all constructor arguments must be constant expressions. diff --git a/spec/11-user-defined-annotations.md b/spec/11-user-defined-annotations.md deleted file mode 100644 index 2c5830c103..0000000000 --- a/spec/11-user-defined-annotations.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: User-Defined Annotations -layout: default -chapter: 11 ---- - -# User-Defined Annotations - -```ebnf - 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)$`. -Here, $c$ is a constructor of a class $C$, which must conform -to the class `scala.Annotation`. - -Annotations may apply to definitions or declarations, types, or -expressions. An annotation of a definition or declaration appears in -front of that definition. An annotation of a type appears after -that type. An annotation of an expression $e$ appears after the -expression $e$, separated by a colon. More than one annotation clause -may apply to an entity. The order in which these annotations are given -does not matter. - -Examples: - -```scala -@deprecated("Use D", "1.0") class C { ... } // Class annotation -@transient @volatile var m: Int // Variable annotation -String @local // Type annotation -(e: @unchecked) match { ... } // Expression annotation -``` - -The meaning of annotation clauses is implementation-dependent. On the -Java platform, the following annotations have a standard meaning. - - * `@transient` Marks a field to be non-persistent; this is - equivalent to the `transient` - modifier in Java. - - * `@volatile` Marks a field which can change its value - outside the control of the program; this - is equivalent to the `volatile` - modifier in Java. - - * `@SerialVersionUID()` Attaches a serial version identifier (a - `long` constant) to a class. - This is equivalent to a the following field - definition in Java: - - ``` - private final static SerialVersionUID = - ``` - - * `@throws()` A Java compiler checks that a program contains handlers for checked exceptions - by analyzing which checked exceptions can result from execution of a method or - constructor. For each checked exception which is a possible result, the - `throws` - clause for the method or constructor must mention the class of that exception - or one of the superclasses of the class of that exception. - -## Java Beans Annotations - - * `@scala.beans.BeanProperty` When prefixed to a definition of some variable `X`, this - annotation causes getter and setter methods `getX`, `setX` - in the Java bean style to be added in the class containing the - variable. The first letter of the variable appears capitalized after - the `get` or `set`. When the annotation is added to the - definition of an immutable value definition `X`, only a getter is - generated. The construction of these methods is part of - code-generation; therefore, these methods become visible only once a - classfile for the containing class is generated. - - * `@scala.beans.BooleanBeanProperty` This annotation is equivalent to `scala.reflect.BeanProperty`, but - the generated getter method is named `isX` instead of `getX`. - -## Deprecation Annotations - - * `@deprecated()` Marks a definition as deprecated. Accesses to the - defined entity will then cause a deprecated warning mentioning the - message `` to be issued from the compiler. Deprecated - warnings are suppressed in code that belongs itself to a definition - that is labeled deprecated. - - * `@deprecatedName(name: )` Marks a formal parameter name as deprecated. Invocations of this entity - using named parameter syntax refering to the deprecated parameter name cause a deprecation warning. - -## Scala Compiler Annotations - - * `@unchecked` When applied to the selector of a `match` expression, - this attribute suppresses any warnings about non-exhaustive pattern - 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 - warning because `Option` is a `sealed` class. - - * `@uncheckedStable` When applied a value declaration or definition, it allows the defined - value to appear in a path, even if its type is [volatile](03-types.html#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, - the reference `x.T` would be malformed. - - When applied to value declarations or definitions that have non-volatile - types, the annotation has no effect. - - * `@specialized` When applied to the definition of a type parameter, this annotation causes - the compiler - to generate specialized definitions for primitive types. An optional list of - primitive - types may be given, in which case specialization takes into account only - those types. - 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, the compiler will instead use the specialized version. - See the [specialization sid](http://docs.scala-lang.org/sips/completed/scala-specialization.html) for more details of the implementation. - -Other annotations may be interpreted by platform- or -application-dependent tools. Class `scala.Annotation` has two -sub-traits which are used to indicate how these annotations are -retained. Instances of an annotation class inheriting from trait -`scala.ClassfileAnnotation` will be stored in the generated class -files. Instances of an annotation class inheriting from trait -`scala.StaticAnnotation` will be visible to the Scala type-checker -in every compilation unit where the annotated symbol is accessed. An -annotation class can inherit from both `scala.ClassfileAnnotation` -and `scala.StaticAnnotation`. If an annotation class inherits from -neither `scala.ClassfileAnnotation` nor -`scala.StaticAnnotation`, its instances are visible only locally -during the compilation run that analyzes them. - -Classes inheriting from `scala.ClassfileAnnotation` may be -subject to further restrictions in order to assure that they can be -mapped to the host environment. In particular, on both the Java and -the .NET platforms, such classes must be toplevel; i.e. they may not -be contained in another class or object. Additionally, on both -Java and .NET, all constructor arguments must be constant expressions. diff --git a/spec/12-the-scala-standard-library.md b/spec/12-the-scala-standard-library.md index 988d9804ec..e76035f458 100644 --- a/spec/12-the-scala-standard-library.md +++ b/spec/12-the-scala-standard-library.md @@ -1,5 +1,5 @@ --- -title: The Scala Standard Library +title: Standard Library layout: default chapter: 12 --- @@ -233,7 +233,7 @@ for type `Int` and for all subrange types. The `toString` method displays its receiver as an integer or floating point number. -### Example +###### Example This is the signature of the numeric value type `Int`: @@ -332,7 +332,7 @@ The `toString` method returns `"()"`. ## Standard Reference Classes This section presents some standard Scala reference classes which are -treated in a special way by the Scala compiler -- either Scala provides +treated in a special way by the Scala compiler – either Scala provides syntactic sugar for them, or the Scala compiler generates special code for their operations. Other classes in the standard Scala library are documented in the Scala library documentation by HTML pages. diff --git a/spec/13-syntax-summary.md b/spec/13-syntax-summary.md index 2b9571cc73..7f73e107de 100644 --- a/spec/13-syntax-summary.md +++ b/spec/13-syntax-summary.md @@ -15,6 +15,8 @@ UnicodeEscape ::= ‘\‘ ‘u‘ {‘u‘} hexDigit hexDigit hexDigit hexDigit hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ ``` +## Lexical Syntax + The lexical syntax of Scala is given by the following grammar in EBNF form: ```ebnf @@ -72,8 +74,10 @@ nl ::= $\mathit{“new line character”}$ semi ::= ‘;’ | nl {nl} ``` +## Context-free Syntax + The context-free syntax of Scala is given by the following EBNF -grammar. +grammar: ```ebnf Literal ::= [‘-’] integerLiteral diff --git a/spec/15-changelog.md b/spec/15-changelog.md new file mode 100644 index 0000000000..54310c921c --- /dev/null +++ b/spec/15-changelog.md @@ -0,0 +1,823 @@ +--- +title: Changelog +layout: default +chapter: 15 +--- + +# Changelog + +Changes in Version 2.8.0 +------------------------ + +#### Trailing commas + +Trailing commas in expression, argument, type or pattern sequences are +no longer supported. + +Changes in Version 2.8 +---------------------- + +Changed visibility rules for nested packages (where done?) + +Changed [visibility rules](02-identifiers-names-and-scopes.html) +so that packages are no longer treated specially. + +Added section on [weak conformance](03-types.html#weak-conformance). +Relaxed type rules for conditionals, +match expressions, try expressions to compute their result type using +least upper bound wrt weak conformance. Relaxed type rule for local type +inference so that argument types need only weekly conform to inferred +formal parameter types. Added section on +[numeric widening](06-expressions.html#numeric-widening) to support +weak conformance. + +Tightened rules to avoid accidential [overrides](05-classes-and-objects.html#overriding). + +Removed class literals. + +Added section on [context bounds](07-implicits.html#context-bounds-and-view-bounds). + +Clarified differences between [`isInstanceOf` and pattern matches](12-the-scala-standard-library.html#root-classes). + +Allowed [`implicit` modifier on function literals](06-expressions.html#anonymous-functions) with a single parameter. + +Changes in Version 2.7.2 +------------------------ + +_(10-Nov-2008)_ + +#### Precedence of Assignment Operators + +The [precedence of assignment operators](06-expressions.html#prefix,-infix,-and-postfix-operations) +has been brought in line with. From now on `+=`, has the same precedence as `=`. + +#### Wildcards as function parameters + +A formal parameter to an anonymous fucntion may now be a +[wildcard represented by an underscore](06-expressions.html#placeholder-syntax-for-anonymous-functions). + +> _ => 7 // The function that ignores its argument +> // and always returns 7. + +#### Unicode alternative for left arrow + +The Unicode glyph ‘\\(\leftarrow\\)’ \\(`\u2190`\\) is now treated as a reserved +identifier, equivalent to the ASCII symbol ‘`<-`’. + +Changes in Version 2.7.1 +------------------------ + +_(09-April-2008)_ + +#### Change in Scoping Rules for Wildcard Placeholders in Types + +A wildcard in a type now binds to the closest enclosing type +application. For example `List[List[_]]` is now equivalent to this +existential type: + + List[List[t] forSome { type t }] + +In version 2.7.0, the type expanded instead to: + + List[List[t]] forSome { type t } + +The new convention corresponds exactly to the way wildcards in Java are +interpreted. + +#### No Contractiveness Requirement for Implicits + +The contractiveness requirement for +[implicit method definitions](07-implicits.html#implicit-parameters) +has been dropped. Instead it is checked for each implicit expansion individually +that the expansion does not result in a cycle or a tree of infinitely +growing types. + +Changes in Version 2.7.0 +------------------------ + +_(07-Feb-2008)_ + +#### Java Generics + +Scala now supports Java generic types by default: + +- A generic type in Java such as `ArrayList` is translated to + a generic type in Scala: `ArrayList[String]`. + +- A wildcard type such as `ArrayList` is translated + to `ArrayList[_ <: Number]`. This is itself a shorthand for the + existential type `ArrayList[T] forSome { type T <: Number }`. + +- A raw type in Java such as `ArrayList` is translated to + `ArrayList[_]`, which is a shorthand for + `ArrayList[T] forSome { type T }`. + +This translation works if `-target:jvm-1.5` is specified, which is the +new default. For any other target, Java generics are not recognized. To +ensure upgradability of Scala codebases, extraneous type parameters for +Java classes under `-target:jvm-1.4` are simply ignored. For instance, +when compiling with `-target:jvm-1.4`, a Scala type such as +`ArrayList[String]` is simply treated as the unparameterized type +`ArrayList`. + +#### Changes to Case Classes + +The Scala compiler generates now for every case class a companion +extractor object (). For instance, given the case class: + + case class X(elem: String) + +the following companion object is generated: + + object X { + def unapply(x: X): Some[String] = Some(x.elem) + def apply(s: String): X = new X(s) + } + +If the object exists already, only the `apply` and `unapply` methods are +added to it. + +Three restrictions on case classes have been removed. + +1. Case classes can now inherit from other case classes. + +2. Case classes may now be `abstract`. + +3. Case classes may now come with companion objects. + +Changes in Version 2.6.1 +------------------------ + +_(30-Nov-2007)_ + +#### Mutable variables introduced by pattern binding + +Mutable variables can now be introduced by a pattern matching definition +(), just like values can. Examples: + + var (x, y) = if (positive) (1, 2) else (-1, -3) + var hd :: tl = mylist + +#### Self-types + +Self types can now be introduced without defining an alias name for +`this` (). Example: + + class C { + type T <: Trait + trait Trait { this: T => ... } + } + +Changes in Version 2.6 +---------------------- + +_(27-July-2007)_ + +#### Existential types + +It is now possible to define existential types (). An existential type +has the form `T forSome {Q}` where `Q` is a sequence of value and/or +type declarations. Given the class definitions + + class Ref[T] + abstract class Outer { type T } + +one may for example write the following existential types + + Ref[T] forSome { type T <: java.lang.Number } + Ref[x.T] forSome { val x: Outer } + +#### Lazy values + +It is now possible to define lazy value declarations using the new +modifier `lazy` (). A `lazy` value definition evaluates its right hand +side \\(e\\) the first time the value is accessed. Example: + + import compat.Platform._ + val t0 = currentTime + lazy val t1 = currentTime + val t2 = currentTime + + println("t0 <= t2: " + (t0 <= t2)) //true + println("t1 <= t2: " + (t1 <= t2)) //false (lazy evaluation of t1) + +#### Structural types + +It is now possible to declare structural types using type refinements +(). For example: + + class File(name: String) { + def getName(): String = name + def open() { /*..*/ } + def close() { println("close file") } + } + def test(f: { def getName(): String }) { println(f.getName) } + + test(new File("test.txt")) + test(new java.io.File("test.txt")) + +There’s also a shorthand form for creating values of structural types. +For instance, + + new { def getName() = "aaron" } + +is a shorthand for + + new AnyRef{ def getName() = "aaron" } + +Changes in Version 2.5 +---------------------- + +_(02-May-2007)_ + +#### Type constructor polymorphism[^1] + +Type parameters () and abstract type members () can now also abstract +over type constructors (). + +This allows a more precise `Iterable` interface: + + trait Iterable[+T] { + type MyType[+T] <: Iterable[T] // MyType is a type constructor + + def filter(p: T => Boolean): MyType[T] = ... + def map[S](f: T => S): MyType[S] = ... + } + + abstract class List[+T] extends Iterable[T] { + type MyType[+T] = List[T] + } + +This definition of `Iterable` makes explicit that mapping a function +over a certain structure (e.g., a `List`) will yield the same structure +(containing different elements). + +#### Early object initialization + +It is now possible to initialize some fields of an object before any +parent constructors are called (). This is particularly useful for +traits, which do not have normal constructor parameters. Example: + + trait Greeting { + val name: String + val msg = "How are you, "+name + } + class C extends { + val name = "Bob" + } with Greeting { + println(msg) + } + +In the code above, the field is initialized before the constructor of is +called. Therefore, field `msg` in class is properly initialized to . + +#### For-comprehensions, revised + +The syntax of for-comprehensions has changed (). In the new syntax, +generators do not start with a anymore, but filters start with an (and +are called guards). A semicolon in front of a guard is optional. For +example: + + for (val x <- List(1, 2, 3); x % 2 == 0) println(x) + +is now written + + for (x <- List(1, 2, 3) if x % 2 == 0) println(x) + +The old syntax is still available but will be deprecated in the future. + +#### Implicit anonymous functions + +It is now possible to define anonymous functions using underscores in +parameter position (). For instance, the expressions in the left column +are each function values which expand to the anonymous functions on +their right. + + _ + 1 x => x + 1 + _ * _ (x1, x2) => x1 * x2 + (_: int) * 2 (x: int) => (x: int) * 2 + if (_) x else y z => if (z) x else y + _.map(f) x => x.map(f) + _.map(_ + 1) x => x.map(y => y + 1) + +As a special case (), a partially unapplied method is now designated + `m _`   instead of the previous notation  `&m`. + +The new notation will displace the special syntax forms `.m()` for +abstracting over method receivers and `&m` for treating an unapplied +method as a function value. For the time being, the old syntax forms are +still available, but they will be deprecated in the future. + +#### Pattern matching anonymous functions, refined + +It is now possible to use case clauses to define a function value +directly for functions of arities greater than one (). Previously, only +unary functions could be defined that way. Example: + + def scalarProduct(xs: Array[Double], ys: Array[Double]) = + (0.0 /: (xs zip ys)) { + case (a, (b, c)) => a + b * c + } + +Changes in Version 2.4 +---------------------- + +_(09-Mar-2007)_ + +#### Object-local private and protected + +The `private` and `protected` modifiers now accept a `[this]` qualifier +(). A definition \\(M\\) which is labelled `private[this]` is private, +and in addition can be accessed only from within the current object. +That is, the only legal prefixes for \\(M\\) are `this` or `$C$.this`. +Analogously, a definition \\(M\\) which is labelled `protected[this]` is +protected, and in addition can be accessed only from within the current +object. + +#### Tuples, revised + +The syntax for [tuples](06-expressions.html#tuples) has been changed from \\(\\{…\\}\\) to +\\((…)\\). For any sequence of types \\(T_1 , … , T_n\\), + +\\((T_1 , … , T_n)\\) is a shorthand for `Tuple$n$[$T_1 , … , T_n$]`. + +Analogously, for any sequence of expressions or patterns \\(x_1 +, … , x_n\\), + +\\((x_1 , … , x_n)\\) is a shorthand for `Tuple$n$($x_1 , … , x_n$)`. + +#### Access modifiers for primary constructors + +The primary constructor of a class can now be marked or (). If such an +access modifier is given, it comes between the name of the class and its +value parameters. Example: + + class C[T] private (x: T) { ... } + +#### Annotations + +The support for attributes has been extended and its syntax changed (). +Attributes are now called *annotations*. The syntax has +been changed to follow Java’s conventions, e.g. `@attribute` instead of +`[attribute]`. The old syntax is still available but will be deprecated +in the future. + +Annotations are now serialized so that they can be read by compile-time +or run-time tools. Class has two sub-traits which are used to indicate +how annotations are retained. Instances of an annotation class +inheriting from trait will be stored in the generated class files. +Instances of an annotation class inheriting from trait will be visible +to the Scala type-checker in every compilation unit where the annotated +symbol is accessed. + +#### Decidable subtyping + +The implementation of subtyping has been changed to prevent infinite +recursions. Termination of subtyping is now ensured by a new restriction +of class graphs to be finitary (). + +#### Case classes cannot be abstract + +It is now explicitly ruled out that case classes can be abstract (). The +specification was silent on this point before, but did not explain how +abstract case classes were treated. The Scala compiler allowed the +idiom. + +#### New syntax for self aliases and self types + +It is now possible to give an explicit alias name and/or type for the +self reference (). For instance, in + + class C { self: D => + ... + } + +the name is introduced as an alias for within and the self type () of is +assumed to be . This construct is introduced now in order to replace +eventually both the qualified this construct and the clause in Scala. + +#### Assignment Operators + +It is now possible to combine operators with assignments (). Example: + + var x: int = 0 + x += 1 + +Changes in Version 2.3.2 +------------------------ + +_(23-Jan-2007)_ + +#### Extractors + +It is now possible to define patterns independently of case classes, +using methods in extractor objects (). Here is an example: + + object Twice { + def apply(x:Int): int = x*2 + def unapply(z:Int): Option[int] = if (z%2==0) Some(z/2) else None + } + val x = Twice(21) + x match { case Twice(n) => Console.println(n) } // prints 21 + +In the example, `Twice` is an extractor object with two methods: + +- The method is used to build even numbers. + +- The method is used to decompose an even number; it is in a sense the + reverse of . `unapply` methods return option types: for a match that + suceeds, for a match that fails. Pattern variables are returned as + the elements of . If there are several variables, they are grouped + in a tuple. + +In the second-to-last line, ’s method is used to construct a number . In +the last line, is tested against the pattern . This pattern succeeds for +even numbers and assigns to the variable one half of the number that was +tested. The pattern match makes use of the method of object . More +details on extractors can be found in the paper “Matching Objects with +Patterns” by Emir, Odersky and Williams. + +#### Tuples + +A new lightweight syntax for tuples has been introduced (). For any +sequence of types \\(T_1 , … , T_n\\), + +\\(\{T_1 , … , T_n \}\\) is a shorthand for `Tuple$n$[$T_1 , … , T_n$]`. + +Analogously, for any sequence of expressions or patterns \\(x_1, … , x_n\\), + +\\(\{x_1 , … , x_n \}\\) is a shorthand for `Tuple$n$($x_1 , … , x_n$)`. + +#### Infix operators of greater arities + +It is now possible to use methods which have more than one parameter as +infix operators (). In this case, all method arguments are written as a +normal parameter list in parentheses. Example: + + class C { + def +(x: int, y: String) = ... + } + val c = new C + c + (1, "abc") + +#### Deprecated attribute + +A new standard attribute `deprecated` is available (11-annotations.html#deprecation-annotations). If a member +definition is marked with this attribute, any reference to the member +will cause a “deprecated” warning message to be emitted. + +Changes in Version 2.3 +---------------------- + +_(23-Nov-2006)_ + +#### Procedures + +A simplified syntax for functions returning `unit` has been introduced +(). Scala now allows the following shorthands: + +`def f(params)` \\(\mbox{for}\\) `def f(params): unit` +`def f(params) { ... }` \\(\mbox{for}\\) `def f(params): unit = { ... }` + +#### Type Patterns + +The syntax of types in patterns has been refined (). Scala now +distinguishes between type variables (starting with a lower case letter) +and types as type arguments in patterns. Type variables are bound in the +pattern. Other type arguments are, as in previous versions, erased. The +Scala compiler will now issue an “unchecked” warning at places where +type erasure might compromise type-safety. + +#### Standard Types + +The recommended names for the two bottom classes in Scala’s type +hierarchy have changed as follows: + + All ==> Nothing + AllRef ==> Null + +The old names are still available as type aliases. + +Changes in Version 2.1.8 +------------------------ + +_(23-Aug-2006)_ + +#### Visibility Qualifier for protected + +Protected members can now have a visibility qualifier (), e.g. +`protected[]`. In particular, one can now simulate package +protected access as in Java writing + + protected[P] def X ... + +where would name the package containing . + +#### Relaxation of Private Acess + +Private members of a class can now be referenced from the companion +module of the class and vice versa () + +#### Implicit Lookup + +The lookup method for implicit definitions has been generalized (). When +searching for an implicit definition matching a type \\(T\\), now are +considered + +1. all identifiers accessible without prefix, and + +2. all members of companion modules of classes associated with \\(T\\). + +(The second clause is more general than before). Here, a class is +*associated* with a type \\(T\\) if it is referenced by +some part of \\(T\\), or if it is a base class of some part of \\(T\\). +For instance, to find implicit members corresponding to the type + + HashSet[List[Int], String] + +one would now look in the companion modules (aka static parts) of , , , +and . Before, it was just the static part of . + +#### Tightened Pattern Match + +A typed pattern match with a singleton type now tests whether the +selector value is reference-equal to p (). Example: + + val p = List(1, 2, 3) + val q = List(1, 2) + val r = q + r match { + case _: p.type => Console.println("p") + case _: q.type => Console.println("q") + } + +This will match the second case and hence will print “”. Before, the +singleton types were erased to , and therefore the first case would have +matched, which is non-sensical. + +Changes in Version 2.1.7 +------------------------ + +_(19-Jul-2006)_ + +#### Multi-Line string literals + +It is now possible to write multi-line string-literals enclosed in +triple quotes (). Example: + + """this is a + multi-line + string literal""" + +No escape substitutions except for unicode escapes are performed in such +string literals. + +#### Closure Syntax + +The syntax of closures has been slightly restricted (). The form + + x: T => E + +is valid only when enclosed in braces, i.e.  `{ x: T => E }`. The +following is illegal, because it might be read as the value x typed with +the type T =\> E: + + val f = x: T => E + +Legal alternatives are: + + val f = { x: T => E } + val f = (x: T) => E + +Changes in Version 2.1.5 +------------------------ + +_(24-May-2006)_ + +#### Class Literals + +There is a new syntax for class literals (): For any class type \\(C\\), +`classOf[$C$]` designates the run-time representation of \\(C\\). + +Changes in Version 2.0 +---------------------- + +_(12-Mar-2006)_ + +Scala in its second version is different in some details from the first +version of the language. There have been several additions and some old +idioms are no longer supported. This appendix summarizes the main +changes. + +#### New Keywords + +The following three words are now reserved; they cannot be used as +identifiers () + + implicit match requires + +#### Newlines as Statement Separators + +Newlines can now be used as statement separators in place of semicolons +() + +#### Syntax Restrictions + +There are some other situations where old constructs no longer work: + +##### *Pattern matching expressions* + +The `match` keyword now appears only as infix operator between a +selector expression and a number of cases, as in: + + expr match { + case Some(x) => ... + case None => ... + } + +Variants such as ` expr.match {...} ` or just ` match {...} ` are no +longer supported. + +##### *“With” in extends clauses* + +The idiom + + class C with M { ... } + +is no longer supported. A `with` connective is only allowed following an +`extends` clause. For instance, the line above would have to be written + + class C extends AnyRef with M { ... } . + +However, assuming `M` is a trait (see [sec:traits]), it is also legal to +write + + class C extends M { ... } + +The latter expression is treated as equivalent to + + class C extends S with M { ... } + +where `S` is the superclass of `M`. + +##### *Regular Expression Patterns* + +The only form of regular expression pattern that is currently supported +is a sequence pattern, which might end in a sequence wildcard . Example: + + case List(1, 2, _*) => ... // will match all lists starting with \code{1,2}. + +It is at current not clear whether this is a permanent restriction. We +are evaluating the possibility of re-introducing full regular expression +patterns in Scala. + +#### Selftype Annotations + +The recommended syntax of selftype annotations has changed. + + class C: T extends B { ... } + +becomes + + class C requires T extends B { ... } + +That is, selftypes are now indicated by the new `requires` keyword. The +old syntax is still available but is considered deprecated. + +#### For-comprehensions + +For-comprehensions () now admit value and pattern definitions. Example: + + for { + val x <- List.range(1, 100) + val y <- List.range(1, x) + val z = x + y + isPrime(z) + } yield Pair(x, y) + +Note the definition  `val z = x + y` as the third item in the +for-comprehension. + +#### Conversions + +The rules for implicit conversions of methods to functions () have been +tightened. Previously, a parameterized method used as a value was always +implicitly converted to a function. This could lead to unexpected +results when method arguments where forgotten. Consider for instance the +statement below: + + show(x.toString) + +where `show` is defined as follows: + + def show(x: String) = Console.println(x) . + +Most likely, the programmer forgot to supply an empty argument list `()` +to `toString`. The previous Scala version would treat this code as a +partially applied method, and expand it to: + + show(() => x.toString()) + +As a result, the address of a closure would be printed instead of the +value of `s`. + +Scala version 2.0 will apply a conversion from partially applied method +to function value only if the expected type of the expression is indeed +a function type. For instance, the conversion would not be applied in +the code above because the expected type of `show`’s parameter is +`String`, not a function type. + +The new convention disallows some previously legal code. Example: + + def sum(f: int => double)(a: int, b: int): double = + if (a > b) 0 else f(a) + sum(f)(a + 1, b) + + val sumInts = sum(x => x) // error: missing arguments + +The partial application of `sum` in the last line of the code above will +not be converted to a function type. Instead, the compiler will produce +an error message which states that arguments for method `sum` are +missing. The problem can be fixed by providing an expected type for the +partial application, for instance by annotating the definition of +`sumInts` with its type: + + val sumInts: (int, int) => double = sum(x => x) // OK + +On the other hand, Scala version 2.0 now automatically applies methods +with empty parameter lists to `()` argument lists when necessary. For +instance, the `show` expression above will now be expanded to + + show(x.toString()) . + +Scala version 2.0 also relaxes the rules of overriding with respect to +empty parameter lists. The revised definition of *matching +members* () makes it now possible to override a method with an +explicit, but empty parameter list `()` with a parameterless method, and +*vice versa*. For instance, the following class definition +is now legal: + + class C { + override def toString: String = ... + } + +Previously this definition would have been rejected, because the +`toString` method as inherited from `java.lang.Object` takes an empty +parameter list. + +#### Class Parameters + +A class parameter may now be prefixed by `val` or `var` (). + +#### Private Qualifiers + +Previously, Scala had three levels of visibility: +*private*, *protected* and +*public*. There was no way to restrict accesses to members +of the current package, as in Java. Scala 2 now defines access +qualifiers that let one express this level of visibility, among others. +In the definition + + private[C] def f(...) + +access to `f` is restricted to all code within the class or package `C` +(which must contain the definition of `f`) () + +#### Changes in the Mixin Model + +The model which details mixin composition of classes has changed +significantly. The main differences are: + +1. We now distinguish between *traits* that are used as + mixin classes and normal classes. The syntax of traits has been + generalized from version 1.0, in that traits are now allowed to have + mutable fields. However, as in version 1.0, traits still may not + have constructor parameters. + +2. Member resolution and super accesses are now both defined in terms + of a *class linearization*. + +3. Scala’s notion of method overloading has been generalized; in + particular, it is now possible to have overloaded variants of the + same method in a subclass and in a superclass, or in several + different mixins. This makes method overloading in Scala + conceptually the same as in Java. + +The new mixin model is explained in more detail in . + +#### Implicit Parameters + +Views in Scala 1.0 have been replaced by the more general concept of +implicit parameters () + +#### Flexible Typing of Pattern Matching + +The new version of Scala implements more flexible typing rules when it +comes to pattern matching over heterogeneous class hierarchies (). A +*heterogeneous class hierarchy* is one where subclasses +inherit a common superclass with different parameter types. With the new +rules in Scala version 2.0 one can perform pattern matches over such +hierarchies with more precise typings that keep track of the information +gained by comparing the types of a selector and a matching pattern (). +This gives Scala capabilities analogous to guarded algebraic data types. + +[^1]: Implemented by Adriaan Moors diff --git a/spec/README.md b/spec/README.md index 97c3fdf832..2f582dec5c 100644 --- a/spec/README.md +++ b/spec/README.md @@ -8,7 +8,7 @@ Third, we'd like to support different output formats. An html page per chapter w ## Editing -We use redcarpet 3.1 and jekyll 2 (currently in alpha) to generate the html. Essentially, this is what github pages use. +We use redcarpet 3.1 and jekyll 2 to generate the html. Essentially, this is what github pages use. ## Building diff --git a/spec/_includes/numbering.css b/spec/_includes/numbering.css index 8df08098bc..2a22ce28b5 100644 --- a/spec/_includes/numbering.css +++ b/spec/_includes/numbering.css @@ -1,4 +1,3 @@ -// based on http://philarcher.org/css/numberheadings.css, h1 { /* must reset here */ counter-reset: chapter {{ page.chapter }}; @@ -40,7 +39,6 @@ h3:before { display: inline; margin-right: 1em; } - h3[id*='example'] { /* must increment here */ counter-increment: example; diff --git a/spec/_layouts/default.yml b/spec/_layouts/default.yml index 64ba4a1639..69791d26ad 100644 --- a/spec/_layouts/default.yml +++ b/spec/_layouts/default.yml @@ -16,75 +16,31 @@ }); - + - - - - - - + + {{ page.title }} - -
- -
+
+ +
+ + +
{{ content }} -
-
+ + + + + diff --git a/spec/_layouts/toc.yml b/spec/_layouts/toc.yml index caf0be1a3a..4da7d41bea 100644 --- a/spec/_layouts/toc.yml +++ b/spec/_layouts/toc.yml @@ -6,23 +6,25 @@ - - + {{ page.title }} - + + + - +
+
+ + Scala Language Specification + Edit at Github +
+
Version 2.11
+
+
{{ content }} - +
diff --git a/spec/index.md b/spec/index.md index ee9c2a5f78..d7e79dafb7 100644 --- a/spec/index.md +++ b/spec/index.md @@ -1,18 +1,9 @@ --- -title: Scala Language Reference +title: Scala Language Specification layout: toc --- -# The Scala Language Specification -# Version 2.11 - -### Maintained online at [https://github.com/scala/scala/tree/2.11.x/spec](https://github.com/scala/scala/tree/2.11.x/spec) - -### Martin Odersky, Philippe Altherr, Vincent Cremet, Gilles Dubochet, Burak Emir, Philipp Haller, Stéphane Micheloud, Nikolay Mihaylov, Adriaan Moors, Lukas Rytz, Michel Schinz, Erik Stenman, Matthias Zenger - -### Markdown Conversion by Iain McGinniss. - -## Table of Contents +# Table of Contents
    {% assign sorted_pages = site.pages | sort:"name" %} @@ -27,7 +18,13 @@ layout: toc {% endfor %}
-## Preface +#### Authors and Contributors + +Martin Odersky, Philippe Altherr, Vincent Cremet, Gilles Dubochet, Burak Emir, Philipp Haller, Stéphane Micheloud, Nikolay Mihaylov, Adriaan Moors, Lukas Rytz, Michel Schinz, Erik Stenman, Matthias Zenger + +Markdown Conversion by Iain McGinniss. + +#### Preface Scala is a Java-like programming language which unifies object-oriented and functional programming. It is a pure diff --git a/spec/public/fonts/Heuristica-Bold.woff b/spec/public/fonts/Heuristica-Bold.woff new file mode 100644 index 0000000000..904579683d Binary files /dev/null and b/spec/public/fonts/Heuristica-Bold.woff differ diff --git a/spec/public/fonts/Heuristica-BoldItalic.woff b/spec/public/fonts/Heuristica-BoldItalic.woff new file mode 100644 index 0000000000..a3c5234453 Binary files /dev/null and b/spec/public/fonts/Heuristica-BoldItalic.woff differ diff --git a/spec/public/fonts/Heuristica-Regular.woff b/spec/public/fonts/Heuristica-Regular.woff new file mode 100644 index 0000000000..f5c1f8b2db Binary files /dev/null and b/spec/public/fonts/Heuristica-Regular.woff differ diff --git a/spec/public/fonts/Heuristica-RegularItalic.woff b/spec/public/fonts/Heuristica-RegularItalic.woff new file mode 100644 index 0000000000..d2c8664593 Binary files /dev/null and b/spec/public/fonts/Heuristica-RegularItalic.woff differ diff --git a/spec/public/fonts/LuxiMono-Bold.woff b/spec/public/fonts/LuxiMono-Bold.woff new file mode 100644 index 0000000000..8581bb5aa4 Binary files /dev/null and b/spec/public/fonts/LuxiMono-Bold.woff differ diff --git a/spec/public/fonts/LuxiMono-BoldOblique.woff b/spec/public/fonts/LuxiMono-BoldOblique.woff new file mode 100644 index 0000000000..607ccf5cd0 Binary files /dev/null and b/spec/public/fonts/LuxiMono-BoldOblique.woff differ diff --git a/spec/public/fonts/LuxiMono-Regular.woff b/spec/public/fonts/LuxiMono-Regular.woff new file mode 100644 index 0000000000..a478ad9ef2 Binary files /dev/null and b/spec/public/fonts/LuxiMono-Regular.woff differ diff --git a/spec/public/fonts/LuxiMono-RegularOblique.woff b/spec/public/fonts/LuxiMono-RegularOblique.woff new file mode 100644 index 0000000000..26999f990f Binary files /dev/null and b/spec/public/fonts/LuxiMono-RegularOblique.woff differ diff --git a/spec/public/fonts/LuxiSans-Bold.woff b/spec/public/fonts/LuxiSans-Bold.woff new file mode 100644 index 0000000000..162621568b Binary files /dev/null and b/spec/public/fonts/LuxiSans-Bold.woff differ diff --git a/spec/public/fonts/LuxiSans-Regular.woff b/spec/public/fonts/LuxiSans-Regular.woff new file mode 100644 index 0000000000..89d980218f Binary files /dev/null and b/spec/public/fonts/LuxiSans-Regular.woff differ diff --git a/spec/public/highlight/LICENSE b/spec/public/highlight/LICENSE deleted file mode 100644 index 422deb7350..0000000000 --- a/spec/public/highlight/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2006, Ivan Sagalaev -All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of highlight.js nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/spec/public/highlight/highlight.pack.js b/spec/public/highlight/highlight.pack.js deleted file mode 100644 index bfeca09abb..0000000000 --- a/spec/public/highlight/highlight.pack.js +++ /dev/null @@ -1 +0,0 @@ -var hljs=new function(){function j(v){return v.replace(/&/gm,"&").replace(//gm,">")}function t(v){return v.nodeName.toLowerCase()}function h(w,x){var v=w&&w.exec(x);return v&&v.index==0}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^lang(uage)?-/,"")});return v.filter(function(x){return i(x)||/no(-?)highlight/.test(x)})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);if(!t(A).match(/br|hr|img|input/)){v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset"}function E(G){F+=""}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=j(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+j(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};var E=function(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})};if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b="\\b("+D.bK.split(" ").join("|")+")\\b"}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?("+F.b+")\\.?":F.b}).concat([D.tE,D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}}}x(y)}function c(T,L,J,R){function v(V,W){for(var U=0;U";V+=aa+'">';return V+Y+Z}function N(){if(!I.k){return j(C)}var U="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(C);while(V){U+=j(C.substr(X,V.index-X));var W=E(I,V);if(W){H+=W[1];U+=w(W[0],j(V[0]))}else{U+=j(V[0])}X=I.lR.lastIndex;V=I.lR.exec(C)}return U+j(C.substr(X))}function F(){if(I.sL&&!f[I.sL]){return j(C)}var U=I.sL?c(I.sL,C,true,S):e(C);if(I.r>0){H+=U.r}if(I.subLanguageMode=="continuous"){S=U.top}return w(U.language,U.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(W,V){var U=W.cN?w(W.cN,"",true):"";if(W.rB){D+=U;C=""}else{if(W.eB){D+=j(V)+U;C=""}else{D+=U;C=V}}I=Object.create(W,{parent:{value:I}})}function G(U,Y){C+=U;if(Y===undefined){D+=Q();return 0}var W=v(Y,I);if(W){D+=Q();P(W,Y);return W.rB?0:Y.length}var X=z(I,Y);if(X){var V=I;if(!(V.rE||V.eE)){C+=Y}D+=Q();do{if(I.cN){D+=""}H+=I.r;I=I.parent}while(I!=X.parent);if(V.eE){D+=j(Y)}C="";if(X.starts){P(X.starts,"")}return V.rE?0:Y.length}if(A(Y,I)){throw new Error('Illegal lexeme "'+Y+'" for mode "'+(I.cN||"")+'"')}C+=Y;return Y.length||1}var M=i(T);if(!M){throw new Error('Unknown language: "'+T+'"')}m(M);var I=R||M;var S;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,"",true)+D}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+=""}}return{r:H,value:D,language:T,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:j(L)}}else{throw O}}}function e(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:j(y)};var w=v;x.forEach(function(z){if(!i(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function g(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"
")}return v}function p(A){var B=r(A);if(/no(-?)highlight/.test(B)){return}var y;if(b.useBR){y=document.createElementNS("http://www.w3.org/1999/xhtml","div");y.innerHTML=A.innerHTML.replace(/\n/g,"").replace(//g,"\n")}else{y=A}var z=y.textContent;var v=B?c(B,z,true):e(z);var x=u(y);if(x.length){var w=document.createElementNS("http://www.w3.org/1999/xhtml","div");w.innerHTML=v.value;v.value=q(x,u(w),z)}v.value=g(v.value);A.innerHTML=v.value;A.className+=" hljs "+(!B&&v.language||"");A.result={language:v.language,re:v.r};if(v.second_best){A.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function d(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function k(){return Object.keys(f)}function i(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=e;this.fixMarkup=g;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=d;this.listLanguages=k;this.getLanguage=i;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/};this.CLCM={cN:"comment",b:"//",e:"$",c:[this.PWM]};this.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[this.PWM]};this.HCM={cN:"comment",b:"#",e:"$",c:[this.PWM]};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.CSSNM={cN:"number",b:this.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0};this.RM={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("scala",function(d){var b={cN:"annotation",b:"@[A-Za-z]+"};var c={cN:"string",b:'u?r?"""',e:'"""',r:10};var a={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"};var e={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0};var h={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0};var i={cN:"class",bK:"class object trait type",e:/[:={\[(\n;]/,c:[{cN:"keyword",bK:"extends with",r:10},h]};var g={cN:"function",bK:"def val",e:/[:={\[(\n;]/,c:[h]};var f={cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[d.CLCM,d.CBCM,c,d.QSM,a,e,g,i,d.CNM,b]}}); \ No newline at end of file diff --git a/spec/public/images/github-logo@2x.png b/spec/public/images/github-logo@2x.png new file mode 100644 index 0000000000..285b0fee2f Binary files /dev/null and b/spec/public/images/github-logo@2x.png differ diff --git a/spec/public/images/scala-logo-red-spiral-dark.png b/spec/public/images/scala-logo-red-spiral-dark.png deleted file mode 100644 index 09b66b5e6a..0000000000 Binary files a/spec/public/images/scala-logo-red-spiral-dark.png and /dev/null differ diff --git a/spec/public/images/scala-spiral-white.png b/spec/public/images/scala-spiral-white.png new file mode 100644 index 0000000000..46aaf80824 Binary files /dev/null and b/spec/public/images/scala-spiral-white.png differ diff --git a/spec/public/scripts/LICENSE-highlight b/spec/public/scripts/LICENSE-highlight new file mode 100644 index 0000000000..fe2f67b162 --- /dev/null +++ b/spec/public/scripts/LICENSE-highlight @@ -0,0 +1,24 @@ +Copyright (c) 2006, Ivan Sagalaev +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of highlight.js nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/spec/public/scripts/LICENSE-toc b/spec/public/scripts/LICENSE-toc new file mode 100644 index 0000000000..4e236e8696 --- /dev/null +++ b/spec/public/scripts/LICENSE-toc @@ -0,0 +1,18 @@ +(The MIT License) +Copyright (c) 2013 Greg Allen +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/spec/public/scripts/highlight.pack.js b/spec/public/scripts/highlight.pack.js new file mode 100644 index 0000000000..bfeca09abb --- /dev/null +++ b/spec/public/scripts/highlight.pack.js @@ -0,0 +1 @@ +var hljs=new function(){function j(v){return v.replace(/&/gm,"&").replace(//gm,">")}function t(v){return v.nodeName.toLowerCase()}function h(w,x){var v=w&&w.exec(x);return v&&v.index==0}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^lang(uage)?-/,"")});return v.filter(function(x){return i(x)||/no(-?)highlight/.test(x)})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);if(!t(A).match(/br|hr|img|input/)){v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset"}function E(G){F+=""}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=j(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+j(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};var E=function(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})};if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b="\\b("+D.bK.split(" ").join("|")+")\\b"}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?("+F.b+")\\.?":F.b}).concat([D.tE,D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}}}x(y)}function c(T,L,J,R){function v(V,W){for(var U=0;U";V+=aa+'">';return V+Y+Z}function N(){if(!I.k){return j(C)}var U="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(C);while(V){U+=j(C.substr(X,V.index-X));var W=E(I,V);if(W){H+=W[1];U+=w(W[0],j(V[0]))}else{U+=j(V[0])}X=I.lR.lastIndex;V=I.lR.exec(C)}return U+j(C.substr(X))}function F(){if(I.sL&&!f[I.sL]){return j(C)}var U=I.sL?c(I.sL,C,true,S):e(C);if(I.r>0){H+=U.r}if(I.subLanguageMode=="continuous"){S=U.top}return w(U.language,U.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(W,V){var U=W.cN?w(W.cN,"",true):"";if(W.rB){D+=U;C=""}else{if(W.eB){D+=j(V)+U;C=""}else{D+=U;C=V}}I=Object.create(W,{parent:{value:I}})}function G(U,Y){C+=U;if(Y===undefined){D+=Q();return 0}var W=v(Y,I);if(W){D+=Q();P(W,Y);return W.rB?0:Y.length}var X=z(I,Y);if(X){var V=I;if(!(V.rE||V.eE)){C+=Y}D+=Q();do{if(I.cN){D+=""}H+=I.r;I=I.parent}while(I!=X.parent);if(V.eE){D+=j(Y)}C="";if(X.starts){P(X.starts,"")}return V.rE?0:Y.length}if(A(Y,I)){throw new Error('Illegal lexeme "'+Y+'" for mode "'+(I.cN||"")+'"')}C+=Y;return Y.length||1}var M=i(T);if(!M){throw new Error('Unknown language: "'+T+'"')}m(M);var I=R||M;var S;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,"",true)+D}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+=""}}return{r:H,value:D,language:T,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:j(L)}}else{throw O}}}function e(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:j(y)};var w=v;x.forEach(function(z){if(!i(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function g(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"
")}return v}function p(A){var B=r(A);if(/no(-?)highlight/.test(B)){return}var y;if(b.useBR){y=document.createElementNS("http://www.w3.org/1999/xhtml","div");y.innerHTML=A.innerHTML.replace(/\n/g,"").replace(//g,"\n")}else{y=A}var z=y.textContent;var v=B?c(B,z,true):e(z);var x=u(y);if(x.length){var w=document.createElementNS("http://www.w3.org/1999/xhtml","div");w.innerHTML=v.value;v.value=q(x,u(w),z)}v.value=g(v.value);A.innerHTML=v.value;A.className+=" hljs "+(!B&&v.language||"");A.result={language:v.language,re:v.r};if(v.second_best){A.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function d(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function k(){return Object.keys(f)}function i(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=e;this.fixMarkup=g;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=d;this.listLanguages=k;this.getLanguage=i;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/};this.CLCM={cN:"comment",b:"//",e:"$",c:[this.PWM]};this.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[this.PWM]};this.HCM={cN:"comment",b:"#",e:"$",c:[this.PWM]};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.CSSNM={cN:"number",b:this.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0};this.RM={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("scala",function(d){var b={cN:"annotation",b:"@[A-Za-z]+"};var c={cN:"string",b:'u?r?"""',e:'"""',r:10};var a={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"};var e={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0};var h={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0};var i={cN:"class",bK:"class object trait type",e:/[:={\[(\n;]/,c:[{cN:"keyword",bK:"extends with",r:10},h]};var g={cN:"function",bK:"def val",e:/[:={\[(\n;]/,c:[h]};var f={cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[d.CLCM,d.CBCM,c,d.QSM,a,e,g,i,d.CNM,b]}}); \ No newline at end of file diff --git a/spec/public/scripts/main.js b/spec/public/scripts/main.js new file mode 100644 index 0000000000..f0509aba41 --- /dev/null +++ b/spec/public/scripts/main.js @@ -0,0 +1,57 @@ +function currentChapter() { + var path = document.location.pathname; + var idx = path.lastIndexOf("/") + 1; + var chap = path.substring(idx, idx + 2); + return parseInt(chap, 10); +} + +function heading(i, heading, $heading) { + var currentLevel = parseInt(heading.tagName.substring(1)); + var result = ""; + if (currentLevel === this.headerLevel) { + this.headerCounts[this.headerLevel] += 1; + return "" + this.headerCounts[this.headerLevel] + " " + $heading.text(); + } else if (currentLevel < this.headerLevel) { + while(currentLevel < this.headerLevel) { + this.headerCounts[this.headerLevel] = 1; + this.headerLevel -= 1; + } + this.headerCounts[this.headerLevel] += 1; + return "" + this.headerCounts[this.headerLevel]+ " " + $heading.text(); + } else { + while(currentLevel > this.headerLevel) { + this.headerLevel += 1; + this.headerCounts[this.headerLevel] = 1; + } + return "" + this.headerCounts[this.headerLevel]+ " " + $heading.text(); + } +} + +$('#toc').toc( + { + 'selectors': 'h1,h2,h3', + 'smoothScrolling': false, + 'chapter': currentChapter(), + 'headerLevel': 1, + 'headerCounts': [-1, currentChapter() - 1, 1, 1], + 'headerText': heading + } +); + +// no language auto-detect so that EBNF isn't detected as scala +hljs.configure({ + languages: [] +}); + +// syntax highlighting after mathjax is loaded so that mathjax can be used in code blocks +MathJax.Hub.Queue(function () { + hljs.initHighlighting(); + $("pre nobr").addClass("fixws"); +}) + +$("#chapters a").each(function (index) { + if (document.location.pathname.endsWith($(this).attr("href"))) + $(this).addClass("chapter-active"); + else + $(this).removeClass("chapter-active"); +}); diff --git a/spec/public/scripts/navigation.js b/spec/public/scripts/navigation.js deleted file mode 100644 index c046bf4d54..0000000000 --- a/spec/public/scripts/navigation.js +++ /dev/null @@ -1,70 +0,0 @@ -(function($){ $.fn.navigation = function() { - - // the TOC already contains H1 so we start at H2 - var headers = $('h2, h3, h4, h5').filter(function() { - // exclude examples - if (this.id.substr(0, 7) == 'example') { - return false; - } - - // get all headers with an id - return this.id; - }); - - var output = $(this); - - var get_level = function(n) { return parseInt(n.nodeName.replace('H', ''), 10); } - - var back_to_top = ''; - - if (headers.length && output.length) { - var level = get_level(headers[0]); - var current_level; - var html = '
    '; - - headers.each(function(_, header) { - current_level = get_level(header); - - if (current_level === level) { - // same level as before - html += '
  1. ' + header.innerHTML + ''; - } else if (current_level <= level) { - // higher level, we go back up and chose intermediary lists - for(i = current_level; i < level; i++) { - html += '
'; - } - html += '
  • ' + header.innerHTML + ''; - } else if (current_level > level) { - // lower level, we open new nested lists - for(i = current_level; i > level; i--) { - html += '
    1. '; - } - html += '' + header.innerHTML + ''; - } - - var header_link = ''; - $(header).prepend(header_link); - - if (!$(header).prev().is('h1')) { - $(header).after(back_to_top); - } - - level = current_level; - }); - - html += '
    '; - - output.html(html); - } - - // back to top links - $(document).on('click', '.to_top', function() { - $(window).scrollTop(0); - window.location.hash = ''; - }); - - // we add one more at the end of the document - $('#content-container').append(back_to_top); - -};})(jQuery); - diff --git a/spec/public/scripts/toc.js b/spec/public/scripts/toc.js new file mode 100644 index 0000000000..070d7b7a93 --- /dev/null +++ b/spec/public/scripts/toc.js @@ -0,0 +1,128 @@ +/*! + * toc - jQuery Table of Contents Plugin + * v0.3.2 + * http://projects.jga.me/toc/ + * copyright Greg Allen 2014 + * MIT License +*/ +(function($) { +var verboseIdCache = {}; +$.fn.toc = function(options) { + var self = this; + var opts = $.extend({}, jQuery.fn.toc.defaults, options); + + var container = $(opts.container); + var headings = $(opts.selectors, container); + var headingOffsets = []; + var activeClassName = opts.activeClass; + + var scrollTo = function(e, callback) { + $('li', self).removeClass(activeClassName); + $(e.target).parent().addClass(activeClassName); + }; + + //highlight on scroll + var timeout; + var highlightOnScroll = function(e) { + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(function() { + var top = $(window).scrollTop(), + highlighted, closest = Number.MAX_VALUE, index = 0; + + for (var i = 0, c = headingOffsets.length; i < c; i++) { + var currentClosest = Math.abs(headingOffsets[i] - top); + if (currentClosest < closest) { + index = i; + closest = currentClosest; + } + } + + $('li', self).removeClass(activeClassName); + highlighted = $('li:eq('+ index +')', self).addClass(activeClassName); + opts.onHighlight(highlighted); + }, 50); + }; + if (opts.highlightOnScroll) { + $(window).bind('scroll', highlightOnScroll); + highlightOnScroll(); + } + + return this.each(function() { + //build TOC + var el = $(this); + var ul = $(opts.listType); + + headings.each(function(i, heading) { + var $h = $(heading); + headingOffsets.push($h.offset().top - opts.highlightOffset); + + var anchorName = opts.anchorName(i, heading, opts.prefix); + + //add anchor + if(heading.id !== anchorName) { + var anchor = $('').attr('id', anchorName).insertBefore($h); + } + + //build TOC item + var a = $('') + .text(opts.headerText(i, heading, $h)) + .attr('href', '#' + anchorName) + .bind('click', function(e) { + $(window).unbind('scroll', highlightOnScroll); + scrollTo(e, function() { + $(window).bind('scroll', highlightOnScroll); + }); + el.trigger('selected', $(this).attr('href')); + }); + + var li = $('
  • ') + .addClass(opts.itemClass(i, heading, $h, opts.prefix)) + .append(a); + + ul.append(li); + }); + el.html(ul); + }); +}; + + +jQuery.fn.toc.defaults = { + container: 'body', + listType: '
      ', + selectors: 'h1,h2,h3', + prefix: 'toc', + activeClass: 'toc-active', + onHighlight: function() {}, + highlightOnScroll: true, + highlightOffset: 100, + anchorName: function(i, heading, prefix) { + if(heading.id.length) { + return heading.id; + } + + var candidateId = $(heading).text().replace(/[^a-z0-9]/ig, ' ').replace(/\s+/g, '-').toLowerCase(); + if (verboseIdCache[candidateId]) { + var j = 2; + + while(verboseIdCache[candidateId + j]) { + j++; + } + candidateId = candidateId + '-' + j; + + } + verboseIdCache[candidateId] = true; + + return prefix + '-' + candidateId; + }, + headerText: function(i, heading, $heading) { + return $heading.text(); + }, + itemClass: function(i, heading, $heading, prefix) { + return prefix + '-' + $heading[0].tagName.toLowerCase(); + } + +}; + +})(jQuery); diff --git a/spec/public/stylesheets/fonts.css b/spec/public/stylesheets/fonts.css new file mode 100644 index 0000000000..36efb2bbd5 --- /dev/null +++ b/spec/public/stylesheets/fonts.css @@ -0,0 +1,73 @@ +@font-face { + font-family: 'Luxi Sans'; + src: local('Luxi Sans Regular'), + url('../fonts/LuxiSans-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'Luxi Sans'; + src: local('Luxi Sans Bold'), + url('../fonts/LuxiSans-Bold.woff') format('woff'); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'Luxi Mono'; + src: local('Luxi Mono Regular'), + url('../fonts/LuxiMono-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: 'Luxi Mono'; + src: local('Luxi Mono Oblique'), + url('../fonts/LuxiMono-BoldOblique.woff') format('woff'); + font-weight: normal; + font-style: oblique; +} +@font-face { + font-family: 'Luxi Mono'; + src: local('Luxi Mono Bold'), + url('../fonts/LuxiMono-Bold.woff') format('woff'); + font-weight: bold; + font-style: normal; +} +@font-face { + font-family: 'Luxi Mono'; + src: local('Luxi Mono Bold Oblique'), + url('../fonts/LuxiMono-BoldOblique.woff') format('woff'); + font-weight: bold; + font-style: oblique; +} + +@font-face { + font-family: 'Heuristica'; + src: local('Heuristica Regular'), + url('../fonts/Heuristica-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: 'Heuristica'; + src: local('Heuristica Italic'), + url('../fonts/Heuristica-RegularItalic.woff') format('woff'); + font-weight: normal; + font-style: italic; +} +@font-face { + font-family: 'Heuristica'; + src: local('Heuristica Bold'), + url('../fonts/Heuristica-Bold.woff') format('woff'); + font-weight: bold; + font-style: normal; +} +@font-face { + font-family: 'Heuristica'; + src: local('Heuristica Bold Italic'), + url('../fonts/Heuristica-BoldItalic.woff') format('woff'); + font-weight: bold; + font-style: italic; +} diff --git a/spec/public/stylesheets/screen-small.css b/spec/public/stylesheets/screen-small.css new file mode 100644 index 0000000000..674db7c490 --- /dev/null +++ b/spec/public/stylesheets/screen-small.css @@ -0,0 +1,57 @@ +body { + padding: 0px; + margin: 0px; +} +aside.left { + position: relative; + margin: 0px auto; + overflow: visible; + height: inherit; + margin-bottom: 40px; + background-color: #073642; +} +header { + position: relative; + height: inherit; + min-height: 32px; +} +main { + max-width: 1000px; + min-width: 600px; + margin: 0 auto; +} + +#chapters a { + font-size: 14px; + max-height: 32px; + padding: 4px 8px; + white-space: nowrap; + display: inline-block; +} +#chapters > #github { + padding: 14px; +} + +#toc { + overflow: visible; +} +#toc .toc-active { + background: inherit; +} +#toc .toc-h1 { + display: inherit; +} +#toc .toc-h1 a { + padding-left: 10px; + color: #FFFFFF; + background: #72D0EB; +} +#toc .toc-h2 a { + padding-left: 30px; +} +#toc .toc-h3 a { + padding-left: 50px; +} +#toc a { + font-size: 14px; +} diff --git a/spec/public/stylesheets/screen-toc.css b/spec/public/stylesheets/screen-toc.css new file mode 100644 index 0000000000..7a04bd00f9 --- /dev/null +++ b/spec/public/stylesheets/screen-toc.css @@ -0,0 +1,37 @@ +body { + padding: 0px; + margin: 0px; +} +header { + height: 96px; + padding: 0px; + width: 100%; + position: relative; + color: #FFFFFF; +} +#header-main { + height: 68px; + line-height: 1.2; + font-size: 32px; +} +#header-sub { + padding-left: 64px; + height: 28px; + background-color:#72D0EB; + vertical-align: middle; +} +#scala-logo { + padding: 10px; +} +#title { + vertical-align: middle; +} +#github { + height: 40px; + padding: 14px; + float: right; + font-size: 0px; +} +li { + margin: 5px; +} diff --git a/spec/public/stylesheets/screen.css b/spec/public/stylesheets/screen.css index dbb3ebe1b3..fdddba0b45 100644 --- a/spec/public/stylesheets/screen.css +++ b/spec/public/stylesheets/screen.css @@ -1,8 +1,8 @@ /* from https://gist.github.com/andyferra/2554919 */ body { - font-family: Helvetica, arial, sans-serif; - font-size: 14px; + font-family:Heuristica,Georgia,serif; + color: #222222; line-height: 1.6; padding-bottom: 10px; @@ -18,7 +18,11 @@ body { } a { - color: #4183C4; + color: #08C; + text-decoration: none; +} +a:hover, a:focus { + } a.absent { color: #cc0000; @@ -41,13 +45,21 @@ a.anchor span { } h1, h2, h3, h4, h5, h6 { - margin: 20px 0 10px; + margin: 30px 0 0px; + padding: 0; + /* Fix anchor position due to header */ + padding-top: 32px; + margin-top: -32px; font-weight: bold; -webkit-font-smoothing: antialiased; cursor: text; position: relative; } +h1, h2 { + font-weight: normal; +} + h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } @@ -95,7 +107,6 @@ h1 { h2 { font-size: 24px; - border-bottom: 1px solid #cccccc; color: black; } @@ -117,7 +128,7 @@ h6 { } p, blockquote, ul, ol, dl, li, table, pre { - margin: 15px 0; + margin: 5px 0 15px; -moz-font-feature-settings: "onum"; -ms-font-feature-settings: "onum"; -webkit-font-feature-settings: "onum"; @@ -125,7 +136,7 @@ p, blockquote, ul, ol, dl, li, table, pre { } hr { - background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0; + background: transparent repeat-x 0 0; border: 0 none; color: #cccccc; height: 4px; @@ -207,7 +218,7 @@ dl dd > :last-child { blockquote { border-left: 4px solid #dddddd; padding: 0 15px; - color: #777777; + color: #222222; } blockquote > :first-child { margin-top: 0; @@ -215,31 +226,34 @@ blockquote > :first-child { blockquote > :last-child { margin-bottom: 0; } +blockquote:before { + content: "Example"; + color: #777777; + font-size: 14px; + font-weight: bold; +} table { padding: 0; + margin: 0; + border: none; + border-collapse: collapse; } table tr { - border-top: 1px solid #cccccc; background-color: white; - margin: 0; - padding: 0; } table tr:nth-child(2n) { background-color: #f8f8f8; } table tr th { + background-color: #EAEAEA; font-weight: bold; - border: 1px solid #cccccc; text-align: left; - margin: 0; - padding: 6px 13px; + padding: 5px 13px; } table tr td { - border: 1px solid #cccccc; text-align: left; - margin: 0; - padding: 6px 13px; + padding: 5px 13px; } table tr th :first-child, table tr td :first-child { margin-top: 0; @@ -327,11 +341,14 @@ span.float-right > span { text-align: right; } +pre, code, tt { + font:14px "Luxi Mono", 'andale mono', 'lucida console', monospace; + line-height:1.5; +} + .highlight pre { - border: 1px solid #eaeaea; - background-color: #f8f8f8; + background-color: #F8F8F8; border-radius: 3px; - line-height: 19px; overflow: auto; padding: 6px 10px; white-space: nowrap; @@ -343,86 +360,144 @@ code { margin: 0; padding: 0; white-space: pre; - font-size: 16px; } -#navigation { - margin-right: 10px; - float: right; - width: 26%; - display: inline; - color: #8B8B8B; - font-size: 15px; - font-weight: bold; - background-color: #F3F4F4; +aside.left { + height: 100%; + position: fixed; + direction: rtl; + overflow: auto; + left: 0px; + width: 320px; + bottom: -32px; + font-family: "Luxi Sans", serif; + background-color: #073642; } -#content-container { - float: left; - width: 70%; - display: inline; +aside.left > nav { + direction: ltr; + top: 32px; + padding-bottom: 32px; } -#container { - padding-top: 10px; - width: 100%; +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block; } -#navigation a { - text-decoration: none; - color: #8B8B8B; +audio, canvas, img, svg, video { + vertical-align: middle; } -#navigation a:hover { - text-decoration: underline; +audio, canvas, progress, video { + display: inline-block; + vertical-align: baseline; } -.active-page { - color: #171717; +main { + position: relative; + top: 32px; + margin: 0 0 0 320px; + padding: 0px 32px; + max-width: 800px; + min-width: 800px; + min-height: 580px; + background-color: #FFF; } -.active-page a { - color: #171717 !important; +header { + position: fixed; + top: 0px; + left: 0px; + height: 32px; + width: 100%; + background-color: #002B36; + margin: 0px 0px; + padding: 0px 0px; + font-family: "Luxi Sans", serif; + font-weight: bold; + z-index: 10; + overflow: hidden; + text-shadow: 1px 1px 0px rgba(0, 43, 54, 0.15); } -.to_top { - position: absolute; - margin-top: -35px; - right: 27%; - color: gray; - cursor: pointer; - width: 16px; height: 16px; - display: block; +#chapters a { + color: #FFFFFF; + text-decoration: none; + font-size: 0.63vw; + padding: 100% 8px; } -.to_top:hover { - color: black; +#chapters a:hover, #chapters a:focus, #github:hover, #github:focus { + background: #DC322F; + -webkit-transition: background .2s ease-in; + -moz-transition: background .2s ease-in; + -ms-transition: background .2s ease-in; + -o-transition: background .2s ease-in; + transition: background .2s ease-in; } -#scala-logo { - float: left; - width: 168px; - height: 48px; - margin-right: 25px; +#chapters a.chapter-active { + background: #72D0EB; } -#header { - padding-top: 16px; - padding-bottom: 10px; - margin-bottom: 10px; - height: 64px; - border-bottom: 1px solid #cccccc; + +#toc ul { + margin: 0; + padding: 0; + list-style: none; } -#header a { - height: 100%; - display: block; +#toc li { + margin: 0; + padding: 0; +} + +#toc a { + color: #FFFFFF; /*#073642;*/ + font-weight: bold; + font-size: 12px; + display: block; + text-shadow: 1px 1px 0px rgba(0, 43, 54, 0.15); +} + +#toc a:hover, #toc a:focus { + background: #DC322F; text-decoration: none; + -webkit-transition: background .2s ease-in; + -moz-transition: background .2s ease-in; + -ms-transition: background .2s ease-in; + -o-transition: background .2s ease-in; + transition: background .2s ease-in; } -#header h1 { - cursor: pointer; - padding-top: 6px; - margin-bottom: 0px; - font-size: 30px; +#toc .toc-h1 { + display: none; +} + +#toc .toc-h2 a { + padding-left: 10px; +} + +#toc .toc-h3 a { + padding-left: 30px; +} + +#toc .toc-active { + background: #72D0EB; +} + +#toc .toc-active a { + color: #FFFFFF; +} + +#chapters > #github { + padding: 0px; + float: right; +} + +.hljs{ + background: #f8f8f8; } +/* proper rendering of MathJax into highlighted code blocks */ +.fixws { white-space: pre; } +.fixws .math { white-space: nowrap; } -- cgit v1.2.3