From 87f1e82d414e3a16fdc4f8623e25c31fa363e531 Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Wed, 12 Oct 2022 09:46:55 +0200 Subject: [PATCH 01/11] Copy Scala 2's Spec Scala 2 Spec taken from https://github.com/scala/scala/commit/f15171599298d57618a53e6f4a9a8c26e2d139a3 --- docs/_spec/01-lexical-syntax.md | 652 ++++++ docs/_spec/02-identifiers-names-and-scopes.md | 183 ++ docs/_spec/03-types.md | 1078 ++++++++++ .../04-basic-declarations-and-definitions.md | 945 +++++++++ docs/_spec/05-classes-and-objects.md | 1160 +++++++++++ docs/_spec/06-expressions.md | 1828 +++++++++++++++++ docs/_spec/07-implicits.md | 525 +++++ docs/_spec/08-pattern-matching.md | 817 ++++++++ docs/_spec/09-top-level-definitions.md | 210 ++ docs/_spec/10-xml-expressions-and-patterns.md | 145 ++ docs/_spec/11-annotations.md | 176 ++ docs/_spec/12-the-scala-standard-library.md | 816 ++++++++ docs/_spec/13-syntax-summary.md | 330 +++ docs/_spec/14-references.md | 207 ++ docs/_spec/15-changelog.md | 847 ++++++++ docs/_spec/README.md | 45 + docs/_spec/_config.yml | 11 + docs/_spec/_includes/numbering.css | 60 + docs/_spec/_includes/table-of-contents.yml | 23 + docs/_spec/_includes/version-notice.yml | 3 + docs/_spec/_layouts/default.yml | 51 + docs/_spec/_layouts/toc.yml | 34 + docs/_spec/id_dsa_travis.enc | 68 + docs/_spec/index.md | 55 + docs/_spec/public/favicon.ico | Bin 0 -> 6518 bytes docs/_spec/public/fonts/Heuristica-Bold.woff | Bin 0 -> 106188 bytes .../public/fonts/Heuristica-BoldItalic.woff | Bin 0 -> 104316 bytes .../public/fonts/Heuristica-Regular.woff | Bin 0 -> 141416 bytes .../fonts/Heuristica-RegularItalic.woff | Bin 0 -> 104700 bytes docs/_spec/public/fonts/LuxiMono-Bold.woff | Bin 0 -> 26560 bytes .../public/fonts/LuxiMono-BoldOblique.woff | Bin 0 -> 29480 bytes docs/_spec/public/fonts/LuxiMono-Regular.woff | Bin 0 -> 26432 bytes .../public/fonts/LuxiMono-RegularOblique.woff | Bin 0 -> 29300 bytes docs/_spec/public/fonts/LuxiSans-Bold.woff | Bin 0 -> 13592 bytes docs/_spec/public/fonts/LuxiSans-Regular.woff | Bin 0 -> 13568 bytes docs/_spec/public/images/classhierarchy.pdf | Bin 0 -> 84078 bytes docs/_spec/public/images/classhierarchy.png | Bin 0 -> 117555 bytes docs/_spec/public/images/github-logo@2x.png | Bin 0 -> 1753 bytes .../public/images/scala-spiral-white.png | Bin 0 -> 1442 bytes docs/_spec/public/octicons/LICENSE.txt | 9 + docs/_spec/public/octicons/octicons.css | 235 +++ docs/_spec/public/octicons/octicons.eot | Bin 0 -> 31440 bytes docs/_spec/public/octicons/octicons.svg | 198 ++ docs/_spec/public/octicons/octicons.ttf | Bin 0 -> 31272 bytes docs/_spec/public/octicons/octicons.woff | Bin 0 -> 17492 bytes docs/_spec/public/scripts/LICENSE-highlight | 24 + docs/_spec/public/scripts/LICENSE-toc | 18 + docs/_spec/public/scripts/highlight.pack.js | 1 + docs/_spec/public/scripts/main.js | 71 + docs/_spec/public/scripts/toc.js | 128 ++ docs/_spec/public/stylesheets/fonts.css | 73 + docs/_spec/public/stylesheets/print.css | 42 + .../_spec/public/stylesheets/screen-small.css | 57 + docs/_spec/public/stylesheets/screen-toc.css | 37 + docs/_spec/public/stylesheets/screen.css | 521 +++++ docs/_spec/spec-toc.xslt | 64 + 56 files changed, 11747 insertions(+) create mode 100644 docs/_spec/01-lexical-syntax.md create mode 100644 docs/_spec/02-identifiers-names-and-scopes.md create mode 100644 docs/_spec/03-types.md create mode 100644 docs/_spec/04-basic-declarations-and-definitions.md create mode 100644 docs/_spec/05-classes-and-objects.md create mode 100644 docs/_spec/06-expressions.md create mode 100644 docs/_spec/07-implicits.md create mode 100644 docs/_spec/08-pattern-matching.md create mode 100644 docs/_spec/09-top-level-definitions.md create mode 100644 docs/_spec/10-xml-expressions-and-patterns.md create mode 100644 docs/_spec/11-annotations.md create mode 100644 docs/_spec/12-the-scala-standard-library.md create mode 100644 docs/_spec/13-syntax-summary.md create mode 100644 docs/_spec/14-references.md create mode 100644 docs/_spec/15-changelog.md create mode 100644 docs/_spec/README.md create mode 100644 docs/_spec/_config.yml create mode 100644 docs/_spec/_includes/numbering.css create mode 100644 docs/_spec/_includes/table-of-contents.yml create mode 100644 docs/_spec/_includes/version-notice.yml create mode 100644 docs/_spec/_layouts/default.yml create mode 100644 docs/_spec/_layouts/toc.yml create mode 100644 docs/_spec/id_dsa_travis.enc create mode 100644 docs/_spec/index.md create mode 100644 docs/_spec/public/favicon.ico create mode 100644 docs/_spec/public/fonts/Heuristica-Bold.woff create mode 100644 docs/_spec/public/fonts/Heuristica-BoldItalic.woff create mode 100644 docs/_spec/public/fonts/Heuristica-Regular.woff create mode 100644 docs/_spec/public/fonts/Heuristica-RegularItalic.woff create mode 100644 docs/_spec/public/fonts/LuxiMono-Bold.woff create mode 100644 docs/_spec/public/fonts/LuxiMono-BoldOblique.woff create mode 100644 docs/_spec/public/fonts/LuxiMono-Regular.woff create mode 100644 docs/_spec/public/fonts/LuxiMono-RegularOblique.woff create mode 100644 docs/_spec/public/fonts/LuxiSans-Bold.woff create mode 100644 docs/_spec/public/fonts/LuxiSans-Regular.woff create mode 100644 docs/_spec/public/images/classhierarchy.pdf create mode 100644 docs/_spec/public/images/classhierarchy.png create mode 100644 docs/_spec/public/images/github-logo@2x.png create mode 100644 docs/_spec/public/images/scala-spiral-white.png create mode 100644 docs/_spec/public/octicons/LICENSE.txt create mode 100644 docs/_spec/public/octicons/octicons.css create mode 100644 docs/_spec/public/octicons/octicons.eot create mode 100644 docs/_spec/public/octicons/octicons.svg create mode 100644 docs/_spec/public/octicons/octicons.ttf create mode 100644 docs/_spec/public/octicons/octicons.woff create mode 100644 docs/_spec/public/scripts/LICENSE-highlight create mode 100644 docs/_spec/public/scripts/LICENSE-toc create mode 100644 docs/_spec/public/scripts/highlight.pack.js create mode 100644 docs/_spec/public/scripts/main.js create mode 100644 docs/_spec/public/scripts/toc.js create mode 100644 docs/_spec/public/stylesheets/fonts.css create mode 100644 docs/_spec/public/stylesheets/print.css create mode 100644 docs/_spec/public/stylesheets/screen-small.css create mode 100644 docs/_spec/public/stylesheets/screen-toc.css create mode 100644 docs/_spec/public/stylesheets/screen.css create mode 100644 docs/_spec/spec-toc.xslt diff --git a/docs/_spec/01-lexical-syntax.md b/docs/_spec/01-lexical-syntax.md new file mode 100644 index 000000000000..921384b40e20 --- /dev/null +++ b/docs/_spec/01-lexical-syntax.md @@ -0,0 +1,652 @@ +--- +title: Lexical Syntax +layout: default +chapter: 1 +--- + +# Lexical Syntax + +Scala source code consists of Unicode text. + +The program text is tokenized as described in this chapter. +See the last section for special support for XML literals, +which are parsed in _XML mode_. + +To construct tokens, characters are distinguished according to the following +classes (Unicode general category given in parentheses): + +1. Whitespace characters. `\u0020 | \u0009 | \u000D | \u000A`. +1. Letters, which include lower case letters (`Ll`), upper case letters (`Lu`), + title case letters (`Lt`), other letters (`Lo`), modifier letters (`Lm`), + letter numerals (`Nl`) and the two characters `\u0024 ‘$’` and `\u005F ‘_’`. +1. Digits `‘0’ | … | ‘9’`. +1. Parentheses `‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ `. +1. Delimiter characters ``‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ ``. +1. Operator characters. These consist of all printable ASCII characters + (`\u0020` - `\u007E`) that are in none of the sets above, mathematical + symbols (`Sm`) and other symbols (`So`). + +## Identifiers + +```ebnf +op ::= opchar {opchar} +varid ::= lower idrest +boundvarid ::= varid + | ‘`’ varid ‘`’ +plainid ::= upper idrest + | varid + | op +id ::= plainid + | ‘`’ { charNoBackQuoteOrNewline | escapeSeq } ‘`’ +idrest ::= {letter | digit} [‘_’ op] +escapeSeq ::= UnicodeEscape | charEscapeSeq +UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit +hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ +``` + +There are three ways to form an identifier. First, an identifier can +start with a letter, followed by an arbitrary sequence of +letters and digits. This may be followed by underscore `‘_‘` +characters and another string composed of either letters and digits or +of operator characters. Second, an identifier can start with an operator +character followed by an arbitrary sequence of operator characters. +The preceding two forms are called _plain_ identifiers. Finally, +an identifier may also be formed by an arbitrary string between +backquotes (host systems may impose some restrictions on which +strings are legal for identifiers). The identifier then is composed +of all characters excluding the backquotes themselves. + +As usual, the longest match rule applies. For instance, the string + +```scala +big_bob++=`def` +``` + +decomposes into the three identifiers `big_bob`, `++=`, and +`def`. + +The rules for pattern matching further distinguish between +_variable identifiers_, which start with a lower case letter +or `_`, and _constant identifiers_, which do not. + +For this purpose, lower case letters include not only a-z, +but also all characters in Unicode category Ll (lowercase letter), +as well as all letters that have contributory property +Other_Lowercase, except characters in category Nl (letter numerals), +which are never taken as lower case. + +The following are examples of variable identifiers: + +> ```scala +> x maxIndex p2p empty_? +> `yield` αρετη _y dot_product_* +> __system _MAX_LEN_ +> ªpple ʰelper +> ``` + +Some examples of constant identifiers are + +> ```scala +> + Object $reserved Džul ǂnûm +> ⅰ_ⅲ Ⅰ_Ⅲ ↁelerious ǃqhàà ʹthatsaletter +> ``` + +The ‘$’ character is reserved for compiler-synthesized identifiers. +User programs should not define identifiers that contain ‘$’ characters. + +The following names are reserved words instead of being members of the +syntactic class `id` of lexical identifiers. + +```scala +abstract case catch class def +do else extends false final +finally for forSome if implicit +import lazy macro match new +null object override package private +protected return sealed super this +throw trait try true type +val var while with yield +_ : = => <- <: <% >: # @ +``` + +The Unicode operators `\u21D2` ‘´\Rightarrow´’ and `\u2190` ‘´\leftarrow´’, which have the ASCII +equivalents `=>` and `<-`, are also reserved. + +> Here are examples of identifiers: +> ```scala +> x Object maxIndex p2p empty_? +> + `yield` αρετη _y dot_product_* +> __system _MAX_LEN_ +> ``` + + + +> 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 + +```ebnf +semi ::= ‘;’ | nl {nl} +``` + +Scala is a line-oriented language where statements may be terminated by +semi-colons or newlines. A newline in a Scala source text is treated +as the special token “nl” if the three following criteria are satisfied: + +1. The token immediately preceding the newline can terminate a statement. +1. The token immediately following the newline can begin a statement. +1. The token appears in a region where newlines are enabled. + +The tokens that can terminate a statement are: literals, identifiers +and the following delimiters and reserved words: + +```scala +this null true false return type +_ ) ] } +``` + +The tokens that can begin a statement are all Scala tokens _except_ +the following delimiters and reserved words: + +```scala +catch else extends finally forSome match +with yield , . ; : = => <- <: <% +>: # [ ) ] } +``` + +A `case` token can begin a statement only if followed by a +`class` or `object` token. + +Newlines are enabled in: + +1. all of a Scala source file, except for nested regions where newlines + are disabled, and +1. the interval between matching `{` and `}` brace tokens, + except for nested regions where newlines are disabled. + +Newlines are disabled in: + +1. the interval between matching `(` and `)` parenthesis tokens, except for + nested regions where newlines are enabled, and +1. the interval between matching `[` and `]` bracket tokens, except for nested + regions where newlines are enabled. +1. The interval between a `case` token and its matching + `=>` token, except for nested regions where newlines are + enabled. +1. Any regions analyzed in [XML mode](#xml-mode). + +Note that the brace characters of `{...}` escapes in XML and +string literals are not tokens, +and therefore do not enclose a region where newlines +are enabled. + +Normally, only a single `nl` token is inserted between two +consecutive non-newline tokens which are on different lines, even if there are multiple lines +between the two tokens. However, if two tokens are separated by at +least one completely blank line (i.e a line which contains no +printable characters), then two `nl` tokens are inserted. + +The Scala grammar (given in full [here](13-syntax-summary.html)) +contains productions where optional `nl` tokens, but not +semicolons, are accepted. This has the effect that a new line in one of these +positions does not terminate an expression or statement. These positions can +be summarized as follows: + +Multiple newline tokens are accepted in the following places (note +that a semicolon in place of the newline would be illegal in every one +of these cases): + +- between the condition of a + [conditional expression](06-expressions.html#conditional-expressions) + or [while loop](06-expressions.html#while-loop-expressions) and the next + following expression, +- between the enumerators of a + [for-comprehension](06-expressions.html#for-comprehensions-and-for-loops) + and the next following expression, and +- after the initial `type` keyword in a + [type definition or declaration](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases). + +A single new line token is accepted + +- in front of an opening brace ‘{’, if that brace is a legal + continuation of the current statement or expression, +- 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-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 + +There are literals for integer numbers, floating point numbers, +characters, booleans, symbols, strings. The syntax of these literals is in +each case as in Java. + + + +```ebnf +Literal ::= [‘-’] integerLiteral + | [‘-’] floatingPointLiteral + | booleanLiteral + | characterLiteral + | stringLiteral + | interpolatedString + | symbolLiteral + | ‘null’ +``` + +### Integer Literals + +```ebnf +integerLiteral ::= (decimalNumeral | hexNumeral) + [‘L’ | ‘l’] +decimalNumeral ::= digit {digit} +hexNumeral ::= ‘0’ (‘x’ | ‘X’) hexDigit {hexDigit} +``` + +Values of type `Int` are all integer +numbers between $-2\^{31}$ and $2\^{31}-1$, inclusive. Values of +type `Long` are all integer numbers between $-2\^{63}$ and +$2\^{63}-1$, inclusive. A compile-time error occurs if an integer literal +denotes a number outside these ranges. + +Integer literals are usually of type `Int`, or of type +`Long` when followed by a `L` or `l` suffix. +(Lowercase `l` is deprecated for reasons of legibility.) + +However, if the expected type [_pt_](06-expressions.html#expression-typing) of a literal +in an expression is either `Byte`, `Short`, or `Char` +and the integer number fits in the numeric range defined by the type, +then the number is converted to type _pt_ and the literal's type +is _pt_. The numeric ranges given by these types are: + +| | | +|----------------|--------------------------| +|`Byte` | ´-2\^7´ to ´2\^7-1´ | +|`Short` | ´-2\^{15}´ to ´2\^{15}-1´| +|`Char` | ´0´ to ´2\^{16}-1´ | + +The digits of a numeric literal may be separated by +arbitrarily many underscores for purposes of legibility. + +> ```scala +> 0 21_000 0x7F -42L 0xFFFF_FFFF +> ``` + +### Floating Point Literals + +```ebnf +floatingPointLiteral ::= digit {digit} ‘.’ digit {digit} [exponentPart] [floatType] + | ‘.’ digit {digit} [exponentPart] [floatType] + | digit {digit} exponentPart [floatType] + | digit {digit} [exponentPart] floatType +exponentPart ::= (‘E’ | ‘e’) [‘+’ | ‘-’] digit {digit} +floatType ::= ‘F’ | ‘f’ | ‘D’ | ‘d’ +``` + +Floating point literals are of type `Float` when followed by +a floating point type suffix `F` or `f`, and are +of type `Double` otherwise. The type `Float` +consists of all IEEE 754 32-bit single-precision binary floating point +values, whereas the type `Double` consists of all IEEE 754 +64-bit double-precision binary floating point values. + +If a floating point literal in a program is followed by a token +starting with a letter, there must be at least one intervening +whitespace character between the two tokens. + +> ```scala +> 0.0 1e30f 3.14159f 1.0e-100 .1 +> ``` + + + +> The phrase `1.toString` parses as three different tokens: +> the integer literal `1`, a `.`, and the identifier `toString`. + + + +> `1.` is not a valid floating point literal because the mandatory digit after the `.` is missing. + +### Boolean Literals + +```ebnf +booleanLiteral ::= ‘true’ | ‘false’ +``` + +The boolean literals `true` and `false` are +members of type `Boolean`. + +### Character Literals + +```ebnf +characterLiteral ::= ‘'’ (charNoQuoteOrNewline | escapeSeq) ‘'’ +``` + +A character literal is a single character enclosed in quotes. +The character can be any Unicode character except the single quote +delimiter or `\u000A` (LF) or `\u000D` (CR); +or any Unicode character represented by an +[escape sequence](#escape-sequences). + +> ```scala +> 'a' '\u0041' '\n' '\t' +> ``` + +### String Literals + +```ebnf +stringLiteral ::= ‘"’ {stringElement} ‘"’ +stringElement ::= charNoDoubleQuoteOrNewline | escapeSeq +``` + +A string literal is a sequence of characters in double quotes. +The characters can be any Unicode character except the double quote +delimiter or `\u000A` (LF) or `\u000D` (CR); +or any Unicode character represented by an [escape sequence](#escape-sequences). + +If the string literal contains a double quote character, it must be escaped using +`"\""`. + +The value of a string literal is an instance of class `String`. + +> ```scala +> "Hello, world!\n" +> "\"Hello,\" replied the world." +> ``` + +#### Multi-Line String Literals + +```ebnf +stringLiteral ::= ‘"""’ multiLineChars ‘"""’ +multiLineChars ::= {[‘"’] [‘"’] charNoDoubleQuote} {‘"’} +``` + +A multi-line string literal is a sequence of characters enclosed in +triple quotes `""" ... """`. The sequence of characters is +arbitrary, except that it may contain three or more consecutive quote characters +only at the very end. Characters +must not necessarily be printable; newlines or other +control characters are also permitted. [Escape sequences](#escape-sequences) are +not processed, except for Unicode escapes (this is deprecated since 2.13.2). + +> ```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.StringOps](https://www.scala-lang.org/api/current/scala/collection/StringOps.html#stripMargin:String). + +#### Interpolated string + +```ebnf +interpolatedString ::= alphaid ‘"’ {[‘\’] interpolatedStringPart | ‘\\’ | ‘\"’} ‘"’ + | alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘$’) | escape} {‘"’} ‘"""’ +interpolatedStringPart ::= printableChar \ (‘"’ | ‘$’ | ‘\’) | escape +escape ::= ‘$$’ + | ‘$"’ + | ‘$’ alphaid + | ‘$’ BlockExpr +alphaid ::= upper idrest + | varid + +``` + +An interpolated string consists of an identifier starting with a letter immediately +followed by a string literal. There may be no whitespace characters or comments +between the leading identifier and the opening quote `"` of the string. +The string literal in an interpolated string can be standard (single quote) +or multi-line (triple quote). + +Inside an interpolated string none of the usual escape characters are interpreted +no matter whether the string literal is normal (enclosed in single quotes) or +multi-line (enclosed in triple quotes). Note that the sequence `\"` does not +close a normal string literal (enclosed in single quotes). + +There are three forms of dollar sign escape. +The most general form encloses an expression in `${` and `}`, i.e. `${expr}`. +The expression enclosed in the braces that follow the leading `$` character is of +syntactical category BlockExpr. Hence, it can contain multiple statements, +and newlines are significant. Single ‘$’-signs are not permitted in isolation +in an interpolated string. A single ‘$’-sign can still be obtained by doubling the ‘$’ +character: ‘$$’. A single ‘"’-sign can be obtained by the sequence ‘\$"’. + +The simpler form consists of a ‘$’-sign followed by an identifier starting with +a letter and followed only by letters, digits, and underscore characters, e.g., `$id`. +The simpler form is expanded by putting braces around the identifier, +e.g., `$id` is equivalent to `${id}`. In the following, unless we explicitly state otherwise, +we assume that this expansion has already been performed. + +The expanded expression is type checked normally. Usually, `StringContext` will resolve to +the default implementation in the scala package, +but it could also be user-defined. Note that new interpolators can also be added through +implicit conversion of the built-in `scala.StringContext`. + +One could write an extension +```scala +implicit class StringInterpolation(s: StringContext) { + def id(args: Any*) = ??? +} +``` + +### Escape Sequences + +The following character escape sequences are recognized in character and string literals. + +| charEscapeSeq | unicode | name | char | +|---------------|----------|-----------------|--------| +| `‘\‘ ‘b‘` | `\u0008` | backspace | `BS` | +| `‘\‘ ‘t‘` | `\u0009` | horizontal tab | `HT` | +| `‘\‘ ‘n‘` | `\u000a` | linefeed | `LF` | +| `‘\‘ ‘f‘` | `\u000c` | form feed | `FF` | +| `‘\‘ ‘r‘` | `\u000d` | carriage return | `CR` | +| `‘\‘ ‘"‘` | `\u0022` | double quote | `"` | +| `‘\‘ ‘'‘` | `\u0027` | single quote | `'` | +| `‘\‘ ‘\‘` | `\u005c` | backslash | `\` | + +In addition, Unicode escape sequences of the form `\uxxxx`, where each `x` is a hex digit are +recognized in character and string literals. + +It is a compile time error if a backslash character in a character or +string literal does not start a valid escape sequence. + +### Symbol literals + +```ebnf +symbolLiteral ::= ‘'’ plainid +``` + +A symbol literal `'x` is deprecated shorthand for the expression `scala.Symbol("x")`. + +The `apply` method of `Symbol`'s companion object +caches weak references to `Symbol`s, thus ensuring that +identical symbol literals are equivalent with respect to reference +equality. + +## Whitespace and Comments + +Tokens may be separated by whitespace characters +and/or comments. Comments come in two forms: + +A single-line comment is a sequence of characters which starts with +`//` and extends to the end of the line. + +A multi-line comment is a sequence of characters between +`/*` and `*/`. Multi-line comments may be nested, +but are required to be properly nested. Therefore, a comment like +`/* /* */` will be rejected as having an unterminated +comment. + +## Trailing Commas in Multi-line Expressions + +If a comma (`,`) is followed immediately, ignoring whitespace, by a newline and +a closing parenthesis (`)`), bracket (`]`), or brace (`}`), then the comma is +treated as a "trailing comma" and is ignored. For example: + +```scala +foo( + 23, + "bar", + true, +) +``` + +## XML mode + +In order to allow literal inclusion of XML fragments, lexical analysis +switches from Scala mode to XML mode when encountering an opening +angle bracket ‘<’ in the following circumstance: The ‘<’ must be +preceded either by whitespace, an opening parenthesis or an opening +brace and immediately followed by a character starting an XML name. + +```ebnf + ( whitespace | ‘(’ | ‘{’ ) ‘<’ (XNameStart | ‘!’ | ‘?’) + + XNameStart ::= ‘_’ | BaseChar | Ideographic // as in W3C XML, but without ‘:’ +``` + +The scanner switches from XML mode to Scala mode if either + +- the XML expression or the XML pattern started by the initial ‘<’ has been + successfully parsed, or if +- the parser encounters an embedded Scala expression or pattern and + forces the Scanner + back to normal mode, until the Scala expression or pattern is + successfully parsed. In this case, since code and XML fragments can be + nested, the parser has to maintain a stack that reflects the nesting + of XML and Scala expressions adequately. + +Note that no Scala tokens are constructed in XML mode, and that comments are interpreted +as text. + +> The following value definition uses an XML literal with two embedded +> Scala expressions: +> +> ```scala +> val b = +> The Scala Language Specification +> {scalaBook.version} +> {scalaBook.authors.mkList("", ", ", "")} +> +> ``` diff --git a/docs/_spec/02-identifiers-names-and-scopes.md b/docs/_spec/02-identifiers-names-and-scopes.md new file mode 100644 index 000000000000..b8bde8cfd1a9 --- /dev/null +++ b/docs/_spec/02-identifiers-names-and-scopes.md @@ -0,0 +1,183 @@ +--- +title: Identifiers, Names & Scopes +layout: default +chapter: 2 +--- + +# Identifiers, Names and Scopes + +Names in Scala identify types, values, methods, and classes which are +collectively called _entities_. Names are introduced by local +[definitions and declarations](04-basic-declarations-and-definitions.html#basic-declarations-and-definitions), +[inheritance](05-classes-and-objects.html#class-members), +[import clauses](04-basic-declarations-and-definitions.html#import-clauses), or +[package clauses](09-top-level-definitions.html#packagings) +which are collectively called _bindings_. + +Bindings of different kinds have precedence defined on them: + +1. Definitions and declarations that are local, inherited, or made + available by a package clause and also defined in the same compilation unit + as the reference to them, have the highest precedence. +1. Explicit imports have the next highest precedence. +1. Wildcard imports have the next highest precedence. +1. Definitions made available by a package clause, but not also defined in the + same compilation unit as the reference to them, as well as imports which + are supplied by the compiler but not explicitly written in source code, + have the lowest precedence. + +There are two different name spaces, one for [types](03-types.html#types) +and one for [terms](06-expressions.html#expressions). The same name may designate a +type and a term, depending on the context where the name is used. + +A binding has a _scope_ in which the entity defined by a single +name can be accessed using a simple name. Scopes are nested. A binding +in some inner scope _shadows_ bindings of lower precedence in the +same scope as well as bindings of the same or lower precedence in outer +scopes. + +Note that shadowing is only a partial order. In the following example, +neither binding of `x` shadows the other. Consequently, the +reference to `x` in the last line of the block is ambiguous. + +```scala +val x = 1 +locally { + import p.X.x + x +} +``` + +A reference to an unqualified (type- or term-) identifier ´x´ is bound +by the unique binding, which + +- defines an entity with name ´x´ in the same namespace as the identifier, and +- shadows all other bindings that define entities with name ´x´ in that + namespace. + +It is an error if no such binding exists. If ´x´ is bound by an +import clause, then the simple name ´x´ is taken to be equivalent to +the qualified name to which ´x´ is mapped by the import clause. If ´x´ +is bound by a definition or declaration, then ´x´ refers to the entity +introduced by that binding. In that case, the type of ´x´ is the type +of the referenced entity. + +A reference to a qualified (type- or term-) identifier ´e.x´ refers to +the member of the type ´T´ of ´e´ which has the name ´x´ in the same +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´. + +Binding precedence implies that the way source is bundled in files affects name resolution. +In particular, imported names have higher precedence than names, defined in other files, +that might otherwise be visible because they are defined in +either the current package or an enclosing package. + +Note that a package definition is taken as lowest precedence, since packages +are open and can be defined across arbitrary compilation units. + +```scala +package util { + import scala.util + class Random + object Test extends App { + println(new util.Random) // scala.util.Random + } +} +``` + +The compiler supplies imports in a preamble to every source file. This preamble +conceptually has the following form, where braces indicate nested scopes: + +```scala +import java.lang._ +{ + import scala._ + { + import Predef._ + { /* source */ } + } +} +``` + +These imports are taken as lowest precedence, so that they are always shadowed +by user code, which may contain competing imports and definitions. +They also increase the nesting depth as shown, so that later imports +shadow earlier ones. + +As a convenience, multiple bindings of a type identifier to the same +underlying type is permitted. This is possible when import clauses introduce +a binding of a member type alias with the same binding precedence, typically +through wildcard imports. This allows redundant type aliases to be imported +without introducing an ambiguity. + +```scala +object X { type T = annotation.tailrec } +object Y { type T = annotation.tailrec } +object Z { + import X._, Y._, annotation.{tailrec => T} // OK, all T mean tailrec + @T def f: Int = { f ; 42 } // error, f is not tail recursive +} +``` + +Similarly, imported aliases of names introduced by package statements are +allowed, even though the names are strictly ambiguous: + +```scala +// c.scala +package p { class C } + +// xy.scala +import p._ +package p { class X extends C } +package q { class Y extends C } +``` + +The reference to `C` in the definition of `X` is strictly ambiguous +because `C` is available by virtue of the package clause in +a different file, and can't shadow the imported name. But because +the references are the same, the definition is taken as though it +did shadow the import. + +###### Example + +Assume the following two definitions of objects named `X` in packages `p` and `q` +in separate compilation units. + +```scala +package p { + object X { val x = 1; val y = 2 } +} + +package q { + object X { val x = true; val y = false } +} +``` + +The following program illustrates different kinds of bindings and +precedences between them. + +```scala +package p { // `X' bound by package clause +import Console._ // `println' bound by wildcard import +object Y { + println(s"L4: $X") // `X' refers to `p.X' here + locally { + import q._ // `X' bound by wildcard import + println(s"L7: $X") // `X' refers to `q.X' here + import X._ // `x' and `y' bound by wildcard import + println(s"L9: $x") // `x' refers to `q.X.x' here + locally { + val x = 3 // `x' bound by local definition + println(s"L12: $x") // `x' refers to constant `3' here + locally { + import q.X._ // `x' and `y' bound by wildcard import +// println(s"L15: $x") // reference to `x' is ambiguous here + import X.y // `y' bound by explicit import + println(s"L17: $y") // `y' refers to `q.X.y' here + locally { + val x = "abc" // `x' bound by local definition + import p.X._ // `x' and `y' bound by wildcard import +// println(s"L21: $y") // reference to `y' is ambiguous here + println(s"L22: $x") // `x' refers to string "abc" here +}}}}}} +``` diff --git a/docs/_spec/03-types.md b/docs/_spec/03-types.md new file mode 100644 index 000000000000..3c78b33e571c --- /dev/null +++ b/docs/_spec/03-types.md @@ -0,0 +1,1078 @@ +--- +title: Types +layout: default +chapter: 3 +--- + +# Types + +```ebnf + Type ::= FunctionArgTypes ‘=>’ Type + | InfixType [ExistentialClause] + FunctionArgTypes ::= InfixType + | ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’ + ExistentialClause ::= ‘forSome’ ‘{’ ExistentialDcl + {semi ExistentialDcl} ‘}’ + ExistentialDcl ::= ‘type’ TypeDcl + | ‘val’ ValDcl + InfixType ::= CompoundType {id [nl] CompoundType} + CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement] + | Refinement + AnnotType ::= SimpleType {Annotation} + SimpleType ::= SimpleType TypeArgs + | SimpleType ‘#’ id + | StableId + | Path ‘.’ ‘type’ + | Literal + | ‘(’ Types ‘)’ + TypeArgs ::= ‘[’ Types ‘]’ + Types ::= Type {‘,’ Type} +``` + +We distinguish between proper types and type constructors, which +take type parameters and yield types. A subset of proper types +called _value types_ represents sets of (first-class) values. +Value types are either _concrete_ or _abstract_. + +Every concrete value type can be represented as a _class type_, i.e. a +[type designator](#type-designators) that refers to a +[class or a trait](05-classes-and-objects.html#class-definitions) [^1], or as a +[compound type](#compound-types) representing an +intersection of types, possibly with a [refinement](#compound-types) +that further constrains the types of its members. + +Abstract value types are introduced by [type parameters](04-basic-declarations-and-definitions.html#type-parameters) +and [abstract type bindings](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases). +Parentheses in types can be used for grouping. + +[^1]: We assume that objects and packages also implicitly + define a class (of the same name as the object or package, but + inaccessible to user programs). + +Non-value types capture properties of identifiers that +[are not values](#non-value-types). For example, a +[type constructor](#type-constructors) does not directly specify a type of +values. However, when a type constructor is applied to the correct type +arguments, it yields a proper type, which may be a value type. + +Non-value types are expressed indirectly in Scala. E.g., a method type is +described by writing down a method signature, which in itself is not a real +type, although it gives rise to a corresponding [method type](#method-types). +Type constructors are another example, as one can write +`type Swap[m[_, _], a,b] = m[b, a]`, but there is no syntax to write +the corresponding anonymous type function directly. + +## Paths + +```ebnf +Path ::= StableId + | [id ‘.’] this +StableId ::= id + | Path ‘.’ id + | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id +ClassQualifier ::= ‘[’ id ‘]’ +``` + +Paths are not types themselves, but they can be a part of named types +and in that function form a central role in Scala's type system. + +A path is one of the following. + +- The empty path ε (which cannot be written explicitly in user programs). +- ´C.´`this`, where ´C´ references a class. + The path `this` is taken as a shorthand for ´C.´`this` where + ´C´ is the name of the class directly enclosing the reference. +- ´p.x´ where ´p´ is a path and ´x´ is a stable member of ´p´. + _Stable members_ are packages or members introduced by object definitions or + by value definitions of [non-volatile types](#volatile-types). +- ´C.´`super`´.x´ or ´C.´`super`´[M].x´ + where ´C´ references a class and ´x´ references a + stable member of the super class or designated parent class ´M´ of ´C´. + The prefix `super` is taken as a shorthand for ´C.´`super` where + ´C´ is the name of the class directly enclosing the reference. + +A _stable identifier_ is a path which ends in an identifier. + +## Value Types + +Every value in Scala has a type which is of one of the following +forms. + +### Singleton Types + +```ebnf +SimpleType ::= Path ‘.’ ‘type’ +``` + +A _singleton type_ is of the form ´p.´`type`. Where ´p´ is a path pointing to a +value which [conforms](06-expressions.html#expression-typing) to +`scala.AnyRef`, the type denotes the set of values consisting of `null` and the +value denoted by ´p´ (i.e., the value ´v´ for which `v eq p`). Where the path +does not conform to `scala.AnyRef` the type denotes the set consisting of only +the value denoted by ´p´. + + + +### Literal Types + +```ebnf +SimpleType ::= Literal +``` + +A literal type `lit` is a special kind of singleton type which denotes the +single literal value `lit`. Thus, the type ascription `1: 1` gives the most +precise type to the literal value `1`: the literal type `1`. + +At run time, an expression `e` is considered to have literal type `lit` if `e == lit`. +Concretely, the result of `e.isInstanceOf[lit]` and `e match { case _ : lit => }` is +determined by evaluating `e == lit`. + +Literal types are available for all types for which there is dedicated syntax +except `Unit`. This includes the numeric types (other than `Byte` and `Short` +which don't currently have syntax), `Boolean`, `Char` and `String`. + +### Stable Types +A _stable type_ is a singleton type, a literal type, +or a type that is declared to be a subtype of trait `scala.Singleton`. + +### Type Projection + +```ebnf +SimpleType ::= SimpleType ‘#’ id +``` + +A _type projection_ ´T´#´x´ references the type member named +´x´ of type ´T´. + + + +### Type Designators + +```ebnf +SimpleType ::= StableId +``` + +A _type designator_ refers to a named value type. It can be simple or +qualified. All such type designators are shorthands for type projections. + +Specifically, the unqualified type name ´t´ where ´t´ is bound in some +class, object, or package ´C´ is taken as a shorthand for +´C.´`this.type#`´t´. If ´t´ is +not bound in a class, object, or package, then ´t´ is taken as a +shorthand for ε`.type#`´t´. + +A qualified type designator has the form `p.t` where `p` is +a [path](#paths) and _t_ is a type name. Such a type designator is +equivalent to the type projection `p.type#t`. + +###### Example + +Some type designators and their expansions are listed below. We assume +a local type parameter ´t´, a value `maintable` +with a type member `Node` and the standard class `scala.Int`, + +| Designator | Expansion | +|-------------------- | --------------------------| +|t | ε.type#t | +|Int | scala.type#Int | +|scala.Int | scala.type#Int | +|data.maintable.Node | data.maintable.type#Node | + +### Parameterized Types + +```ebnf +SimpleType ::= SimpleType TypeArgs +TypeArgs ::= ‘[’ Types ‘]’ +``` + +A _parameterized type_ ´T[ T_1 , \ldots , T_n ]´ consists of a type +designator ´T´ and type parameters ´T_1 , \ldots , T_n´ where +´n \geq 1´. ´T´ must refer to a type constructor which takes ´n´ type +parameters ´a_1 , \ldots , a_n´. + +Say the type parameters have lower bounds ´L_1 , \ldots , L_n´ and +upper bounds ´U_1, \ldots, U_n´. The parameterized type is +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 + +Given the partial type definitions: + +```scala +class TreeMap[A <: Comparable[A], B] { … } +class List[A] { … } +class I extends Comparable[I] { … } + +class F[M[_], X] { … } +class S[K <: String] { … } +class G[M[ Z <: I ], I] { … } +``` + +the following parameterized types are well-formed: + +```scala +TreeMap[I, String] +List[I] +List[List[Boolean]] + +F[List, Int] +G[S, String] +``` + +###### Example + +Given the [above type definitions](#example-parameterized-types), +the following types are ill-formed: + +```scala +TreeMap[I] // illegal: wrong number of parameters +TreeMap[List[I], Int] // illegal: type parameter not within bound + +F[Int, Boolean] // illegal: Int is not a type constructor +F[TreeMap, Int] // illegal: TreeMap takes two parameters, + // F expects a constructor taking one +G[S, Int] // illegal: S constrains its parameter to + // conform to String, + // G expects type constructor with a parameter + // that conforms to Int +``` + +### Tuple Types + +```ebnf +SimpleType ::= ‘(’ Types ‘)’ +``` + +A _tuple type_ ´(T_1 , \ldots , T_n)´ is an alias for the +class `scala.Tuple´n´[´T_1´, … , ´T_n´]`, where ´n \geq 2´. + +Tuple classes are case classes whose fields can be accessed using +selectors `_1` , … , `_n`. Their functionality is +abstracted in a corresponding `Product` trait. The _n_-ary tuple +class and product trait are defined at least as follows in the +standard Scala library (they might also add other methods and +implement other traits). + +```scala +case class Tuple´_n´[+´T_1´, … , +´T_n´](_1: ´T_1´, … , _n: ´T_n´) +extends Product´_n´[´T_1´, … , ´T_n´] + +trait Product´_n´[+´T_1´, … , +´T_n´] { + override def productArity = ´n´ + def _1: ´T_1´ + … + def _n: ´T_n´ +} +``` + +### Annotated Types + +```ebnf +AnnotType ::= SimpleType {Annotation} +``` + +An _annotated type_ ´T´ ´a_1, \ldots, a_n´ +attaches [annotations](11-annotations.html#user-defined-annotations) +´a_1 , \ldots , a_n´ to the type ´T´. + +###### Example + +The following type adds the `@suspendable` annotation to the type `String`: + +```scala +String @suspendable +``` + +### Compound Types + +```ebnf +CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement] + | Refinement +Refinement ::= [nl] ‘{’ RefineStat {semi RefineStat} ‘}’ +RefineStat ::= Dcl + | ‘type’ TypeDef + | +``` + +A _compound type_ ´T_1´ `with` … `with` ´T_n \\{ R \\}´ +represents objects with members as given in the component types +´T_1 , \ldots , T_n´ and the refinement ´\\{ R \\}´. A refinement +´\\{ R \\}´ contains declarations and type definitions. +If a declaration or definition overrides a declaration or definition in +one of the component types ´T_1 , \ldots , T_n´, the usual rules for +[overriding](05-classes-and-objects.html#overriding) apply; otherwise the declaration +or definition is said to be “structural” [^2]. + +[^2]: A reference to a structurally defined member (method call or access + to a value or variable) may generate binary code that is significantly + slower than an equivalent code to a non-structural member. + +Within a method declaration in a structural refinement, the type of +any value parameter may only refer to type parameters or abstract +types that are contained inside the refinement. That is, it must refer +either to a type parameter of the method itself, or to a type +definition within the refinement. This restriction does not apply to +the method's result type. + +If no refinement is given, the empty refinement is implicitly added, +i.e. ´T_1´ `with` … `with` ´T_n´ is a shorthand for ´T_1´ `with` … `with` ´T_n \\{\\}´. + +A compound type may also consist of just a refinement +´\\{ R \\}´ with no preceding component types. Such a type is +equivalent to `AnyRef` ´\\{ R \\}´. + +###### Example + +The following example shows how to declare and use a method which has +a parameter type that contains a refinement with structural declarations. + +```scala +case class Bird (val name: String) extends Object { + def fly(height: Int) = … +… +} +case class Plane (val callsign: String) extends Object { + def fly(height: Int) = … +… +} +def takeoff( + runway: Int, + r: { val callsign: String; def fly(height: Int) }) = { + tower.print(r.callsign + " requests take-off on runway " + runway) + tower.read(r.callsign + " is clear for take-off") + r.fly(1000) +} +val bird = new Bird("Polly the parrot"){ val callsign = name } +val a380 = new Plane("TZ-987") +takeoff(42, bird) +takeoff(89, a380) +``` + +Although `Bird` and `Plane` do not share any parent class other than +`Object`, the parameter _r_ of method `takeoff` is defined using a +refinement with structural declarations to accept any object that declares +a value `callsign` and a `fly` method. + +### Infix Types + +```ebnf +InfixType ::= CompoundType {id [nl] CompoundType} +``` + +An _infix type_ ´T_1´ `op` ´T_2´ consists of an infix +operator `op` which gets applied to two type operands ´T_1´ and +´T_2´. The type is equivalent to the type application +`op`´[T_1, T_2]´. The infix operator `op` may be an +arbitrary identifier. + +All type infix operators have the same precedence; parentheses have to +be used for grouping. The [associativity](06-expressions.html#prefix,-infix,-and-postfix-operations) +of a type operator is determined as for term operators: type operators +ending in a colon ‘:’ are right-associative; all other +operators are left-associative. + +In a sequence of consecutive type infix operations +´t_0 \, \mathit{op} \, t_1 \, \mathit{op_2} \, \ldots \, \mathit{op_n} \, t_n´, +all operators ´\mathit{op}\_1 , \ldots , \mathit{op}\_n´ must have the same +associativity. If they are all left-associative, the sequence is +interpreted as +´(\ldots (t_0 \mathit{op_1} t_1) \mathit{op_2} \ldots) \mathit{op_n} t_n´, +otherwise it is interpreted as +´t_0 \mathit{op_1} (t_1 \mathit{op_2} ( \ldots \mathit{op_n} t_n) \ldots)´. + +### Function Types + +```ebnf +Type ::= FunctionArgs ‘=>’ Type +FunctionArgs ::= InfixType + | ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’ +``` + +The type ´(T_1 , \ldots , T_n) \Rightarrow U´ represents the set of function +values that take arguments of types ´T_1 , \ldots , Tn´ and yield +results of type ´U´. In the case of exactly one argument type +´T \Rightarrow U´ is a shorthand for ´(T) \Rightarrow U´. +An argument type of the form ´\Rightarrow T´ +represents a [call-by-name parameter](04-basic-declarations-and-definitions.html#by-name-parameters) of type ´T´. + +Function types associate to the right, e.g. +´S \Rightarrow T \Rightarrow U´ is the same as +´S \Rightarrow (T \Rightarrow U)´. + +Function types are shorthands for class types that define `apply` +functions. Specifically, the ´n´-ary function type +´(T_1 , \ldots , T_n) \Rightarrow U´ is a shorthand for the class type +`Function´_n´[´T_1´ , … , ´T_n´, ´U´]`. Such class +types are defined in the Scala library for ´n´ between 0 and 22 as follows. + +```scala +package scala +trait Function´_n´[-´T_1´ , … , -´T_n´, +´U´] { + def apply(´x_1´: ´T_1´ , … , ´x_n´: ´T_n´): ´U´ + override def toString = "" +} +``` + +Hence, function types are [covariant](04-basic-declarations-and-definitions.html#variance-annotations) in their +result type and contravariant in their argument types. + +### Existential Types + +```ebnf +Type ::= InfixType ExistentialClauses +ExistentialClauses ::= ‘forSome’ ‘{’ ExistentialDcl + {semi ExistentialDcl} ‘}’ +ExistentialDcl ::= ‘type’ TypeDcl + | ‘val’ ValDcl +``` + +An _existential type_ has the form `´T´ forSome { ´Q´ }` +where ´Q´ is a sequence of +[type declarations](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases). + +Let +´t_1[\mathit{tps}\_1] >: L_1 <: U_1 , \ldots , t_n[\mathit{tps}\_n] >: L_n <: U_n´ +be the types declared in ´Q´ (any of the +type parameter sections `[ ´\mathit{tps}_i´ ]` might be missing). +The scope of each type ´t_i´ includes the type ´T´ and the existential clause +´Q´. +The type variables ´t_i´ are said to be _bound_ in the type +`´T´ forSome { ´Q´ }`. +Type variables which occur in a type ´T´ but which are not bound in ´T´ are said +to be _free_ in ´T´. + +A _type instance_ of `´T´ forSome { ´Q´ }` +is a type ´\sigma T´ where ´\sigma´ is a substitution over ´t_1 , \ldots , t_n´ +such that, for each ´i´, ´\sigma L_i <: \sigma t_i <: \sigma U_i´. +The set of values denoted by the existential type `´T´ forSome {´\,Q\,´}` +is the union of the set of values of all its type instances. + +A _skolemization_ of `´T´ forSome { ´Q´ }` is +a type instance ´\sigma T´, where ´\sigma´ is the substitution +´[t_1'/t_1 , \ldots , t_n'/t_n]´ and each ´t_i'´ is a fresh abstract type +with lower bound ´\sigma L_i´ and upper bound ´\sigma U_i´. + +#### Simplification Rules + +Existential types obey the following four equivalences: + +1. Multiple for-clauses in an existential type can be merged. E.g., +`´T´ forSome { ´Q´ } forSome { ´Q'´ }` +is equivalent to +`´T´ forSome { ´Q´ ; ´Q'´}`. +1. Unused quantifications can be dropped. E.g., +`´T´ forSome { ´Q´ ; ´Q'´}` +where none of the types defined in ´Q'´ are referred to by ´T´ or ´Q´, +is equivalent to +`´T´ forSome {´ Q ´}`. +1. An empty quantification can be dropped. E.g., +`´T´ forSome { }` is equivalent to ´T´. +1. An existential type `´T´ forSome { ´Q´ }` where ´Q´ contains +a clause `type ´t[\mathit{tps}] >: L <: U´` is equivalent +to the type `´T'´ forSome { ´Q´ }` where ´T'´ results from ´T´ by replacing +every [covariant occurrence](04-basic-declarations-and-definitions.html#variance-annotations) of ´t´ in ´T´ by ´U´ and by +replacing every contravariant occurrence of ´t´ in ´T´ by ´L´. + +#### Existential Quantification over Values + +As a syntactic convenience, the bindings clause +in an existential type may also contain +value declarations `val ´x´: ´T´`. +An existential type `´T´ forSome { ´Q´; val ´x´: ´S\,´;´\,Q'´ }` +is treated as a shorthand for the type +`´T'´ forSome { ´Q´; type ´t´ <: ´S´ with Singleton; ´Q'´ }`, where ´t´ is a +fresh type name and ´T'´ results from ´T´ by replacing every occurrence of +`´x´.type` with ´t´. + +#### Placeholder Syntax for Existential Types + +```ebnf +WildcardType ::= ‘_’ TypeBounds +``` + +Scala supports a placeholder syntax for existential types. +A _wildcard type_ is of the form `_´\;´>:´\,L\,´<:´\,U´`. Both bound +clauses may be omitted. If a lower bound clause `>:´\,L´` is missing, +`>:´\,´scala.Nothing` +is assumed. If an upper bound clause `<:´\,U´` is missing, +`<:´\,´scala.Any` is assumed. A wildcard type is a shorthand for an +existentially quantified type variable, where the existential quantification is +implicit. + +A wildcard type must appear as a type argument of a parameterized type. +Let ´T = p.c[\mathit{targs},T,\mathit{targs}']´ be a parameterized type where +´\mathit{targs}, \mathit{targs}'´ may be empty and +´T´ is a wildcard type `_´\;´>:´\,L\,´<:´\,U´`. Then ´T´ is equivalent to the +existential +type + +```scala +´p.c[\mathit{targs},t,\mathit{targs}']´ forSome { type ´t´ >: ´L´ <: ´U´ } +``` + +where ´t´ is some fresh type variable. +Wildcard types may also appear as parts of [infix types](#infix-types) +, [function types](#function-types), +or [tuple types](#tuple-types). +Their expansion is then the expansion in the equivalent parameterized +type. + +###### Example + +Assume the class definitions + +```scala +class Ref[T] +abstract class Outer { type T } +``` + +Here are some examples of existential types: + +```scala +Ref[T] forSome { type T <: java.lang.Number } +Ref[x.T] forSome { val x: Outer } +Ref[x_type # T] forSome { type x_type <: Outer with Singleton } +``` + +The last two types in this list are equivalent. +An alternative formulation of the first type above using wildcard syntax is: + +```scala +Ref[_ <: java.lang.Number] +``` + +###### Example + +The type `List[List[_]]` is equivalent to the existential type + +```scala +List[List[t] forSome { type t }] +``` + +###### Example + +Assume a covariant type + +```scala +class List[+T] +``` + +The type + +```scala +List[T] forSome { type T <: java.lang.Number } +``` + +is equivalent (by simplification rule 4 above) to + +```scala +List[java.lang.Number] forSome { type T <: java.lang.Number } +``` + +which is in turn equivalent (by simplification rules 2 and 3 above) to +`List[java.lang.Number]`. + +## Non-Value Types + +The types explained in the following do not denote sets of values, nor +do they appear explicitly in programs. They are introduced in this +report as the internal types of defined identifiers. + +### Method Types + +A _method type_ is denoted internally as ´(\mathit{Ps})U´, where ´(\mathit{Ps})´ +is a sequence of parameter names and types ´(p_1:T_1 , \ldots , p_n:T_n)´ +for some ´n \geq 0´ and ´U´ is a (value or method) type. This type +represents named methods that take arguments named ´p_1 , \ldots , p_n´ +of types ´T_1 , \ldots , T_n´ +and that return a result of type ´U´. + +Method types associate to the right: ´(\mathit{Ps}\_1)(\mathit{Ps}\_2)U´ is +treated as ´(\mathit{Ps}\_1)((\mathit{Ps}\_2)U)´. + +A special case are types of methods without any parameters. They are +written here `=> T`. Parameterless methods name expressions +that are re-evaluated each time the parameterless method name is +referenced. + +Method types do not exist as types of values. If a method name is used +as a value, its type is [implicitly converted](06-expressions.html#implicit-conversions) to a +corresponding function type. + +###### Example + +The declarations + +```scala +def a: Int +def b (x: Int): Boolean +def c (x: Int) (y: String, z: String): String +``` + +produce the typings + +```scala +a: => Int +b: (Int) Boolean +c: (Int) (String, String) String +``` + +### Polymorphic Method Types + +A polymorphic method type is denoted internally as `[´\mathit{tps}\,´]´T´` where +`[´\mathit{tps}\,´]` is a type parameter section +`[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]` +for some ´n \geq 0´ and ´T´ is a +(value or method) type. This type represents named methods that +take type arguments `´S_1 , \ldots , S_n´` which +[conform](#parameterized-types) to the lower bounds +`´L_1 , \ldots , L_n´` and the upper bounds +`´U_1 , \ldots , U_n´` and that yield results of type ´T´. + +###### Example + +The declarations + +```scala +def empty[A]: List[A] +def union[A <: Comparable[A]] (x: Set[A], xs: Set[A]): Set[A] +``` + +produce the typings + +```scala +empty : [A >: Nothing <: Any] List[A] +union : [A >: Nothing <: Comparable[A]] (x: Set[A], xs: Set[A]) Set[A] +``` + +### Type Constructors + +A _type constructor_ is represented internally much like a polymorphic method type. +`[´\pm´ ´a_1´ >: ´L_1´ <: ´U_1 , \ldots , \pm a_n´ >: ´L_n´ <: ´U_n´] ´T´` +represents a type that is expected by a +[type constructor parameter](04-basic-declarations-and-definitions.html#type-parameters) or an +[abstract type constructor binding](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases) with +the corresponding type parameter clause. + +###### Example + +Consider this fragment of the `Iterable[+X]` class: + +```scala +trait Iterable[+X] { + def flatMap[newType[+X] <: Iterable[X], S](f: X => newType[S]): newType[S] +} +``` + +Conceptually, the type constructor `Iterable` is a name for the +anonymous type `[+X] Iterable[X]`, which may be passed to the +`newType` type constructor parameter in `flatMap`. + + + +## Base Types and Member Definitions + +Types of class members depend on the way the members are referenced. +Central here are three notions, namely: +1. the notion of the set of base types of a type ´T´, +1. the notion of a type ´T´ in some class ´C´ seen from some + prefix type ´S´, +1. the notion of the set of member bindings of some type ´T´. + +These notions are defined mutually recursively as follows. + +1. The set of _base types_ of a type is a set of class types, + given as follows. + - The base types of a class type ´C´ with parents ´T_1 , \ldots , T_n´ are + ´C´ itself, as well as the base types of the compound type + `´T_1´ with … with ´T_n´ { ´R´ }`. + - The base types of an aliased type are the base types of its alias. + - The base types of an abstract type are the base types of its upper bound. + - The base types of a parameterized type + `´C´[´T_1 , \ldots , T_n´]` are the base types + of type ´C´, where every occurrence of a type parameter ´a_i´ + of ´C´ has been replaced by the corresponding parameter type ´T_i´. + - The base types of a singleton type `´p´.type` are the base types of + the type of ´p´. + - The base types of a compound type + `´T_1´ with ´\ldots´ with ´T_n´ { ´R´ }` + are the _reduced union_ of the base + classes of all ´T_i´'s. This means: + Let the multi-set ´\mathscr{S}´ be the multi-set-union of the + base types of all ´T_i´'s. + If ´\mathscr{S}´ contains several type instances of the same class, say + `´S^i´#´C´[´T^i_1 , \ldots , T^i_n´]` ´(i \in I)´, then + all those instances + are replaced by one of them which conforms to all + others. It is an error if no such instance exists. It follows that the + reduced union, if it exists, + produces a set of class types, where different types are instances of + different classes. + - The base types of a type selection `´S´#´T´` are + determined as follows. If ´T´ is an alias or abstract type, the + previous clauses apply. Otherwise, ´T´ must be a (possibly + parameterized) class type, which is defined in some class ´B´. Then + the base types of `´S´#´T´` are the base types of ´T´ + in ´B´ seen from the prefix type ´S´. + - The base types of an existential type `´T´ forSome { ´Q´ }` are + all types `´S´ forSome { ´Q´ }` where ´S´ is a base type of ´T´. + +1. The notion of a type ´T´ _in class ´C´ seen from some prefix type ´S´_ + makes sense only if the prefix type ´S´ + has a type instance of class ´C´ as a base type, say + `´S'´#´C´[´T_1 , \ldots , T_n´]`. Then we define as follows. + - If `´S´ = ´\epsilon´.type`, then ´T´ in ´C´ seen from ´S´ is + ´T´ itself. + - Otherwise, if ´S´ is an existential type `´S'´ forSome { ´Q´ }`, and + ´T´ in ´C´ seen from ´S'´ is ´T'´, + then ´T´ in ´C´ seen from ´S´ is `´T'´ forSome {´\,Q\,´}`. + - Otherwise, if ´T´ is the ´i´'th type parameter of some class ´D´, then + - If ´S´ has a base type `´D´[´U_1 , \ldots , U_n´]`, for some type + parameters `[´U_1 , \ldots , U_n´]`, then ´T´ in ´C´ seen from ´S´ + is ´U_i´. + - Otherwise, if ´C´ is defined in a class ´C'´, then + ´T´ in ´C´ seen from ´S´ is the same as ´T´ in ´C'´ seen from ´S'´. + - Otherwise, if ´C´ is not defined in another class, then + ´T´ in ´C´ seen from ´S´ is ´T´ itself. + - Otherwise, if ´T´ is the singleton type `´D´.this.type` for some class ´D´ + then + - If ´D´ is a subclass of ´C´ and ´S´ has a type instance of class ´D´ + among its base types, then ´T´ in ´C´ seen from ´S´ is ´S´. + - Otherwise, if ´C´ is defined in a class ´C'´, then + ´T´ in ´C´ seen from ´S´ is the same as ´T´ in ´C'´ seen from ´S'´. + - Otherwise, if ´C´ is not defined in another class, then + ´T´ in ´C´ seen from ´S´ is ´T´ itself. + - If ´T´ is some other type, then the described mapping is performed + to all its type components. + + If ´T´ is a possibly parameterized class type, where ´T´'s class + is defined in some other class ´D´, and ´S´ is some prefix type, + then we use "´T´ seen from ´S´" as a shorthand for + "´T´ in ´D´ seen from ´S´". + +1. The _member bindings_ of a type ´T´ are + 1. all bindings ´d´ such that there exists a type instance of some class ´C´ among the base types of ´T´ + and there exists a definition or declaration ´d'´ in ´C´ + such that ´d´ results from ´d'´ by replacing every + type ´T'´ in ´d'´ by ´T'´ in ´C´ seen from ´T´, and + 2. all bindings of the type's [refinement](#compound-types), if it has one. + + The _definition_ of a type projection `S#T` is the member + binding ´d_T´ of the type `T` in `S`. In that case, we also say + that `S#T` _is defined by_ ´d_T´. + +## Relations between types + +We define the following relations between types. + +| Name | Symbolically | Interpretation | +|------------------|----------------|----------------------------------------------------| +| Equivalence | ´T \equiv U´ | ´T´ and ´U´ are interchangeable in all contexts. | +| Conformance | ´T <: U´ | Type ´T´ conforms to ("is a subtype of") type ´U´. | +| Weak Conformance | ´T <:_w U´ | Augments conformance for primitive numeric types. | +| Compatibility | | Type ´T´ conforms to type ´U´ after conversions. | + +### Equivalence + +Equivalence ´(\equiv)´ between types is the smallest congruence [^congruence] such that the following holds: + +- If ´t´ is defined by a type alias `type ´t´ = ´T´`, then ´t´ is equivalent to ´T´. +- If a path ´p´ has a singleton type `´q´.type`, then `´p´.type ´\equiv q´.type`. +- If ´O´ is defined by an object definition, and ´p´ is a path consisting only of package or object selectors and ending in ´O´, then `´O´.this.type ´\equiv p´.type`. +- Two [compound types](#compound-types) are equivalent if the sequences + of their component are pairwise equivalent, and occur in the same order, and + their refinements are equivalent. Two refinements are equivalent if they + bind the same names and the modifiers, types and bounds of every + declared entity are equivalent in both refinements. +- Two [method types](#method-types) are equivalent if: + - neither are implicit, or they both are [^implicit]; + - they have equivalent result types; + - they have the same number of parameters; and + - corresponding parameters have equivalent types. + Note that the names of parameters do not matter for method type equivalence. +- Two [polymorphic method types](#polymorphic-method-types) are equivalent if + they have the same number of type parameters, and, after renaming one set of + type parameters by another, the result types as well as lower and upper bounds + of corresponding type parameters are equivalent. +- Two [existential types](#existential-types) + are equivalent if they have the same number of + quantifiers, and, after renaming one list of type quantifiers by + another, the quantified types as well as lower and upper bounds of + corresponding quantifiers are equivalent. +- Two [type constructors](#type-constructors) are equivalent if they have the + same number of type parameters, and, after renaming one list of type + parameters by another, the result types as well as variances, lower and upper + bounds of corresponding type parameters are equivalent. + +[^congruence]: A congruence is an equivalence relation which is closed under formation of contexts. +[^implicit]: A method type is implicit if the parameter section that defines it starts with the `implicit` keyword. + +### Conformance + +The conformance relation ´(<:)´ is the smallest transitive relation that satisfies the following conditions. + + +- Conformance includes equivalence. If `T \equiv U` then `T <: U`. +- For every value type `T`, `scala.Nothing <: ´T´ <: scala.Any`. +- For every type constructor ´T´ (with any number of type parameters), `scala.Nothing <: ´T´ <: scala.Any`. +- For every value type ´T´, `scala.Null <: ´T´` unless `´T´ <: scala.AnyVal`. +- A type variable or abstract type ´t´ conforms to its upper bound and + its lower bound conforms to ´t´. +- A class type or parameterized type conforms to any of its base-types. +- A singleton type `´p´.type` conforms to the type of the path ´p´. +- A singleton type `´p´.type` conforms to the type `scala.Singleton`. +- A type projection `´T´#´t´` conforms to `´U´#´t´` if ´T´ conforms to ´U´. +- A parameterized type `´T´[´T_1´ , … , ´T_n´]` conforms to + `´T´[´U_1´ , … , ´U_n´]` if + the following three conditions hold for ´i \in \{ 1 , \ldots , n \}´: + 1. If the ´i´'th type parameter of ´T´ is declared covariant, then + ´T_i <: U_i´. + 1. If the ´i´'th type parameter of ´T´ is declared contravariant, then + ´U_i <: T_i´. + 1. If the ´i´'th type parameter of ´T´ is declared neither covariant + nor contravariant, then ´U_i \equiv T_i´. +- A compound type `´T_1´ with ´\ldots´ with ´T_n´ {´R\,´}` conforms to + each of its component types ´T_i´. +- If ´T <: U_i´ for ´i \in \{ 1 , \ldots , n \}´ and for every + binding ´d´ of a type or value ´x´ in ´R´ there exists a member + binding of ´x´ in ´T´ which subsumes ´d´, then ´T´ conforms to the + compound type `´U_1´ with ´\ldots´ with ´U_n´ {´R\,´}`. +- The existential type `´T´ forSome {´\,Q\,´}` conforms to + ´U´ if its [skolemization](#existential-types) + conforms to ´U´. +- The type ´T´ conforms to the existential type `´U´ forSome {´\,Q\,´}` + if ´T´ conforms to one of the [type instances](#existential-types) + of `´U´ forSome {´\,Q\,´}`. +- If + ´T_i \equiv T_i'´ for ´i \in \{ 1 , \ldots , n\}´ and ´U´ conforms to ´U'´ + then the method type ´(p_1:T_1 , \ldots , p_n:T_n) U´ conforms to + ´(p_1':T_1' , \ldots , p_n':T_n') U'´. +- The polymorphic type + ´[a_1 >: L_1 <: U_1 , \ldots , a_n >: L_n <: U_n] T´ conforms to the + polymorphic type + ´[a_1 >: L_1' <: U_1' , \ldots , a_n >: L_n' <: U_n'] T'´ if, assuming + ´L_1' <: a_1 <: U_1' , \ldots , L_n' <: a_n <: U_n'´ + one has ´T <: T'´ and ´L_i <: L_i'´ and ´U_i' <: U_i´ + for ´i \in \{ 1 , \ldots , n \}´. +- Type constructors ´T´ and ´T'´ follow a similar discipline. We characterize + ´T´ and ´T'´ by their type parameter clauses + ´[a_1 , \ldots , a_n]´ and + ´[a_1' , \ldots , a_n']´, where an ´a_i´ or ´a_i'´ may include a variance + annotation, a higher-order type parameter clause, and bounds. Then, ´T´ + conforms to ´T'´ if any list ´[t_1 , \ldots , t_n]´ -- with declared + variances, bounds and higher-order type parameter clauses -- of valid type + arguments for ´T'´ is also a valid list of type arguments for ´T´ and + ´T[t_1 , \ldots , t_n] <: T'[t_1 , \ldots , t_n]´. Note that this entails + that: + - The bounds on ´a_i´ must be weaker than the corresponding bounds declared + for ´a'_i´. + - The variance of ´a_i´ must match the variance of ´a'_i´, where covariance + matches covariance, contravariance matches contravariance and any variance + matches invariance. + - Recursively, these restrictions apply to the corresponding higher-order + type parameter clauses of ´a_i´ and ´a'_i´. + +A declaration or definition in some compound type of class type ´C´ +_subsumes_ another declaration of the same name in some compound type or class +type ´C'´, if one of the following holds. + +- A value declaration or definition that defines a name ´x´ with type ´T´ + subsumes a value or method declaration that defines ´x´ with type ´T'´, provided + ´T <: T'´. +- A method declaration or definition that defines a name ´x´ with type ´T´ + subsumes a method declaration that defines ´x´ with type ´T'´, provided + ´T <: T'´. +- A type alias + `type ´t´[´T_1´ , … , ´T_n´] = ´T´` subsumes a type alias + `type ´t´[´T_1´ , … , ´T_n´] = ´T'´` if ´T \equiv T'´. +- A type declaration `type ´t´[´T_1´ , … , ´T_n´] >: ´L´ <: ´U´` subsumes + a type declaration `type ´t´[´T_1´ , … , ´T_n´] >: ´L'´ <: ´U'´` if + ´L' <: L´ and ´U <: U'´. +- A type or class definition that binds a type name ´t´ subsumes an abstract + type declaration `type t[´T_1´ , … , ´T_n´] >: L <: U` if + ´L <: t <: U´. + + +#### Least upper bounds and greatest lower bounds +The ´(<:)´ relation forms pre-order between types, i.e. it is transitive and reflexive. +This allows us to define _least upper bounds_ and _greatest lower bounds_ of a set of types in terms of that order. +The least upper bound or greatest lower bound of a set of types does not always exist. +For instance, consider the class definitions: + +```scala +class A[+T] {} +class B extends A[B] +class C extends A[C] +``` + +Then the types `A[Any], A[A[Any]], A[A[A[Any]]], ...` form +a descending sequence of upper bounds for `B` and `C`. The +least upper bound would be the infinite limit of that sequence, which +does not exist as a Scala type. Since cases like this are in general +impossible to detect, a Scala compiler is free to reject a term +which has a type specified as a least upper or greatest lower bound, +and that bound would be more complex than some compiler-set +limit [^4]. + +The least upper bound or greatest lower bound might also not be +unique. For instance `A with B` and `B with A` are both +greatest lower bounds of `A` and `B`. If there are several +least upper bounds or greatest lower bounds, the Scala compiler is +free to pick any one of them. + +[^4]: The current Scala compiler limits the nesting level + of parameterization in such bounds to be at most two deeper than the + maximum nesting level of the operand types + +### Weak Conformance + +In some situations Scala uses a more general conformance relation. +A type ´S´ _weakly conforms_ to a type ´T´, written ´S <:_w T´, +if ´S <: T´ or both ´S´ and ´T´ are primitive number types and ´S´ precedes ´T´ in the following ordering. + +```scala +Byte ´<:_w´ Short +Short ´<:_w´ Int +Char ´<:_w´ Int +Int ´<:_w´ Long +Long ´<:_w´ Float +Float ´<:_w´ Double +``` + +A _weak least upper bound_ is a least upper bound with respect to weak conformance. + +### Compatibility +A type ´T´ is _compatible_ to a type ´U´ if ´T´ (or its corresponding function type) [weakly conforms](#weak-conformance) to ´U´ +after applying [eta-expansion](06-expressions.html#eta-expansion). If ´T´ is a method type, it's converted to the corresponding function type. If the types do not weakly conform, the following alternatives are checked in order: + - [view application](07-implicits.html#views): there's an implicit view from ´T´ to ´U´; + - dropping by-name modifiers: if ´U´ is of the shape `´=> U'´` (and ´T´ is not), `´T <:_w U'´`; + - SAM conversion: if ´T´ corresponds to a function type, and ´U´ declares a single abstract method whose type [corresponds](06-expressions.html#sam-conversion) to the function type ´U'´, `´T <:_w U'´`. + + + +#### Examples + +##### Function compatibility via SAM conversion + +Given the definitions + +```scala +def foo(x: Int => String): Unit +def foo(x: ToString): Unit + +trait ToString { def convert(x: Int): String } +``` + +The application `foo((x: Int) => x.toString)` [resolves](06-expressions.html#overloading-resolution) to the first overload, +as it's more specific: + - `Int => String` is compatible to `ToString` -- when expecting a value of type `ToString`, you may pass a function literal from `Int` to `String`, as it will be SAM-converted to said function; + - `ToString` is not compatible to `Int => String` -- when expecting a function from `Int` to `String`, you may not pass a `ToString`. + +## Volatile Types + +Type volatility approximates the possibility that a type parameter or +abstract type instance of a type does not have any non-null values. +A value member of a volatile type cannot appear in a [path](#paths). + +A type is _volatile_ if it falls into one of four categories: + +A compound type `´T_1´ with … with ´T_n´ {´R\,´}` +is volatile if one of the following three conditions hold. + +1. One of ´T_2 , \ldots , T_n´ is a type parameter or abstract type, or +1. ´T_1´ is an abstract type and either the refinement ´R´ + or a type ´T_j´ for ´j > 1´ contributes an abstract member + to the compound type, or +1. one of ´T_1 , \ldots , T_n´ is a singleton type. + +Here, a type ´S´ _contributes an abstract member_ to a type ´T´ if +´S´ contains an abstract member that is also a member of ´T´. +A refinement ´R´ contributes an abstract member to a type ´T´ if ´R´ +contains an abstract declaration which is also a member of ´T´. + +A type designator is volatile if it is an alias of a volatile type, or +if it designates a type parameter or abstract type that has a volatile type as +its upper bound. + +A singleton type `´p´.type` is volatile, if the underlying +type of path ´p´ is volatile. + +An existential type `´T´ forSome {´\,Q\,´}` is volatile if +´T´ is volatile. + +## Type Erasure + +A type is called _generic_ if it contains type arguments or type variables. +_Type erasure_ is a mapping from (possibly generic) types to +non-generic types. We write ´|T|´ for the erasure of type ´T´. +The erasure mapping is defined as follows. + +- The erasure of an alias type is the erasure of its right-hand side. +- The erasure of an abstract type is the erasure of its upper bound. +- The erasure of the parameterized type `scala.Array´[T_1]´` is + `scala.Array´[|T_1|]´`. +- The erasure of every other parameterized type ´T[T_1 , \ldots , T_n]´ is ´|T|´. +- The erasure of a singleton type `´p´.type` is the + erasure of the type of ´p´. +- The erasure of a type projection `´T´#´x´` is `|´T´|#´x´`. +- The erasure of a compound type + `´T_1´ with ´\ldots´ with ´T_n´ {´R\,´}` is the erasure of the intersection + dominator of ´T_1 , \ldots , T_n´. +- The erasure of an existential type `´T´ forSome {´\,Q\,´}` is ´|T|´. + +The _intersection dominator_ of a list of types ´T_1 , \ldots , T_n´ is computed +as follows. +Let ´T_{i_1} , \ldots , T_{i_m}´ be the subsequence of types ´T_i´ +which are not supertypes of some other type ´T_j´. +If this subsequence contains a type designator ´T_c´ that refers to a class +which is not a trait, +the intersection dominator is ´T_c´. Otherwise, the intersection +dominator is the first element of the subsequence, ´T_{i_1}´. diff --git a/docs/_spec/04-basic-declarations-and-definitions.md b/docs/_spec/04-basic-declarations-and-definitions.md new file mode 100644 index 000000000000..acaf2491d99b --- /dev/null +++ b/docs/_spec/04-basic-declarations-and-definitions.md @@ -0,0 +1,945 @@ +--- +title: Basic Declarations & Definitions +layout: default +chapter: 4 +--- + +# Basic Declarations and Definitions + +```ebnf +Dcl ::= ‘val’ ValDcl + | ‘var’ VarDcl + | ‘def’ FunDcl + | ‘type’ {nl} TypeDcl +PatVarDef ::= ‘val’ PatDef + | ‘var’ VarDef +Def ::= PatVarDef + | ‘def’ FunDef + | ‘type’ {nl} TypeDef + | TmplDef +``` + +A _declaration_ introduces names and assigns them types. It can +form part of a [class definition](05-classes-and-objects.html#templates) or of a +refinement in a [compound type](03-types.html#compound-types). + +A _definition_ introduces names that denote terms or types. It can +form part of an object or class definition or it can be local to a +block. Both declarations and definitions produce _bindings_ that +associate type names with type definitions or bounds, and that +associate term names with types. + +The scope of a name introduced by a declaration or definition is the +whole statement sequence containing the binding. However, there is a +restriction on forward references in blocks: In a statement sequence +´s_1 \ldots s_n´ making up a block, if a simple name in ´s_i´ refers +to an entity defined by ´s_j´ where ´j \geq i´, then for all ´s_k´ +between and including ´s_i´ and ´s_j´, + +- ´s_k´ cannot be a variable definition. +- If ´s_k´ is a value definition, it must be lazy. + + + +## Value Declarations and Definitions + +```ebnf +Dcl ::= ‘val’ ValDcl +ValDcl ::= ids ‘:’ Type +PatVarDef ::= ‘val’ PatDef +PatDef ::= Pattern2 {‘,’ Pattern2} [‘:’ Type] ‘=’ Expr +ids ::= id {‘,’ id} +``` + +A value declaration `val ´x´: ´T´` introduces ´x´ as a name of a value of +type ´T´. + +A value definition `val ´x´: ´T´ = ´e´` defines ´x´ as a +name of the value that results from the evaluation of ´e´. +If the value definition is not recursive, the type +´T´ may be omitted, in which case the [packed type](06-expressions.html#expression-typing) of +expression ´e´ is assumed. If a type ´T´ is given, then ´e´ is expected to +conform to it. + +Evaluation of the value definition implies evaluation of its +right-hand side ´e´, unless it has the modifier `lazy`. The +effect of the value definition is to bind ´x´ to the value of ´e´ +converted to type ´T´. A `lazy` value definition evaluates +its right hand side ´e´ the first time the value is accessed. + +A _constant value definition_ is of the form + +```scala +final val x = e +``` + +where `e` is a [constant expression](06-expressions.html#constant-expressions). +The `final` modifier must be +present and no type annotation may be given. References to the +constant value `x` are themselves treated as constant expressions; in the +generated code they are replaced by the definition's right-hand side `e`. + +Value definitions can alternatively have a [pattern](08-pattern-matching.html#patterns) +as left-hand side. If ´p´ is some pattern other +than a simple name or a name followed by a colon and a type, then the +value definition `val ´p´ = ´e´` is expanded as follows: + +1. If the pattern ´p´ has bound variables ´x_1 , \ldots , x_n´, where ´n > 1´: + +```scala +val ´\$x´ = ´e´ match {case ´p´ => (´x_1 , \ldots , x_n´)} +val ´x_1´ = ´\$x´._1 +´\ldots´ +val ´x_n´ = ´\$x´._n +``` + +Here, ´\$x´ is a fresh name. + +2. If ´p´ has a unique bound variable ´x´: + +```scala +val ´x´ = ´e´ match { case ´p´ => ´x´ } +``` + +3. If ´p´ has no bound variables: + +```scala +´e´ match { case ´p´ => ()} +``` + +###### Example + +The following are examples of value definitions + +```scala +val pi = 3.1415 +val pi: Double = 3.1415 // equivalent to first definition +val Some(x) = f() // a pattern definition +val x :: xs = mylist // an infix pattern definition +``` + +The last two definitions have the following expansions. + +```scala +val x = f() match { case Some(x) => x } + +val x´\$´ = mylist match { case x :: xs => (x, xs) } +val x = x´\$´._1 +val xs = x´\$´._2 +``` + +The name of any declared or defined value may not end in `_=`. + +A value declaration `val ´x_1 , \ldots , x_n´: ´T´` is a shorthand for the +sequence of value declarations `val ´x_1´: ´T´; ...; val ´x_n´: ´T´`. +A value definition `val ´p_1 , \ldots , p_n´ = ´e´` is a shorthand for the +sequence of value definitions `val ´p_1´ = ´e´; ...; val ´p_n´ = ´e´`. +A value definition `val ´p_1 , \ldots , p_n: T´ = ´e´` is a shorthand for the +sequence of value definitions `val ´p_1: T´ = ´e´; ...; val ´p_n: T´ = ´e´`. + +## Variable Declarations and Definitions + +```ebnf +Dcl ::= ‘var’ VarDcl +PatVarDef ::= ‘var’ VarDef +VarDcl ::= ids ‘:’ Type +VarDef ::= PatDef + | ids ‘:’ Type ‘=’ ‘_’ +``` + +A variable declaration `var ´x´: ´T´` is equivalent to the declarations +of both a _getter function_ ´x´ *and* a _setter function_ `´x´_=`: + +```scala +def ´x´: ´T´ +def ´x´_= (´y´: ´T´): Unit +``` + +An implementation of a class may _define_ a declared variable +using a variable definition, or by defining the corresponding setter and getter methods. + +A variable definition `var ´x´: ´T´ = ´e´` introduces a +mutable variable with type ´T´ and initial value as given by the +expression ´e´. The type ´T´ can be omitted, in which case the type of +´e´ is assumed. If ´T´ is given, then ´e´ is expected to +[conform to it](06-expressions.html#expression-typing). + +Variable definitions can alternatively have a [pattern](08-pattern-matching.html#patterns) +as left-hand side. A variable definition + `var ´p´ = ´e´` where ´p´ is a pattern other +than a simple name or a name followed by a colon and a type is expanded in the same way +as a [value definition](#value-declarations-and-definitions) +`val ´p´ = ´e´`, except that +the free names in ´p´ are introduced as mutable variables, not values. + +The name of any declared or defined variable may not end in `_=`. + +A variable definition `var ´x´: ´T´ = _` can appear only as a member of a template. +It introduces a mutable field with type ´T´ and a default initial value. +The default value depends on the type ´T´ as follows: + +| default | type ´T´ | +|----------|------------------------------------| +|`0` | `Int` or one of its subrange types | +|`0L` | `Long` | +|`0.0f` | `Float` | +|`0.0d` | `Double` | +|`false` | `Boolean` | +|`()` | `Unit` | +|`null` | all other types | + +When they occur as members of a template, both forms of variable +definition also introduce a getter function ´x´ which returns the +value currently assigned to the variable, as well as a setter function +`´x´_=` which changes the value currently assigned to the variable. +The functions have the same signatures as for a variable declaration. +The template then has these getter and setter functions as +members, whereas the original variable cannot be accessed directly as +a template member. + +###### Example + +The following example shows how _properties_ can be +simulated in Scala. It defines a class `TimeOfDayVar` of time +values with updatable integer fields representing hours, minutes, and +seconds. Its implementation contains tests that allow only legal +values to be assigned to these fields. The user code, on the other +hand, accesses these fields just like normal variables. + +```scala +class TimeOfDayVar { + private var h: Int = 0 + private var m: Int = 0 + private var s: Int = 0 + + def hours = h + def hours_= (h: Int) = if (0 <= h && h < 24) this.h = h + else throw new DateError() + + def minutes = m + def minutes_= (m: Int) = if (0 <= m && m < 60) this.m = m + else throw new DateError() + + def seconds = s + def seconds_= (s: Int) = if (0 <= s && s < 60) this.s = s + else throw new DateError() +} +val d = new TimeOfDayVar +d.hours = 8; d.minutes = 30; d.seconds = 0 +d.hours = 25 // throws a DateError exception +``` + +A variable declaration `var ´x_1 , \ldots , x_n´: ´T´` is a shorthand for the +sequence of variable declarations `var ´x_1´: ´T´; ...; var ´x_n´: ´T´`. +A variable definition `var ´x_1 , \ldots , x_n´ = ´e´` is a shorthand for the +sequence of variable definitions `var ´x_1´ = ´e´; ...; var ´x_n´ = ´e´`. +A variable definition `var ´x_1 , \ldots , x_n: T´ = ´e´` is a shorthand for +the sequence of variable definitions +`var ´x_1: T´ = ´e´; ...; var ´x_n: T´ = ´e´`. + +## Type Declarations and Type Aliases + + + +```ebnf +Dcl ::= ‘type’ {nl} TypeDcl +TypeDcl ::= id [TypeParamClause] [‘>:’ Type] [‘<:’ Type] +Def ::= ‘type’ {nl} TypeDef +TypeDef ::= id [TypeParamClause] ‘=’ Type +``` + +A _type declaration_ `type ´t´[´\mathit{tps}\,´] >: ´L´ <: ´U´` declares +´t´ to be an abstract type with lower bound type ´L´ and upper bound +type ´U´. If the type parameter clause `[´\mathit{tps}\,´]` is omitted, ´t´ abstracts over a proper type, otherwise ´t´ stands for a type constructor that accepts type arguments as described by the type parameter clause. + +If a type declaration appears as a member declaration of a +type, implementations of the type may implement ´t´ with any type ´T´ +for which ´L <: T <: U´. It is a compile-time error if +´L´ does not conform to ´U´. Either or both bounds may be omitted. +If the lower bound ´L´ is absent, the bottom type +`scala.Nothing` is assumed. If the upper bound ´U´ is absent, +the top type `scala.Any` is assumed. + +A type constructor declaration imposes additional restrictions on the +concrete types for which ´t´ may stand. Besides the bounds ´L´ and +´U´, the type parameter clause may impose higher-order bounds and +variances, as governed by the [conformance of type constructors](03-types.html#conformance). + +The scope of a type parameter extends over the bounds `>: ´L´ <: ´U´` and the type parameter clause ´\mathit{tps}´ itself. A +higher-order type parameter clause (of an abstract type constructor +´tc´) has the same kind of scope, restricted to the declaration of the +type parameter ´tc´. + +To illustrate nested scoping, these declarations are all equivalent: `type t[m[x] <: Bound[x], Bound[x]]`, `type t[m[x] <: Bound[x], Bound[y]]` and `type t[m[x] <: Bound[x], Bound[_]]`, as the scope of, e.g., the type parameter of ´m´ is limited to the declaration of ´m´. In all of them, ´t´ is an abstract type member that abstracts over two type constructors: ´m´ stands for a type constructor that takes one type parameter and that must be a subtype of ´Bound´, ´t´'s second type constructor parameter. `t[MutableList, Iterable]` is a valid use of ´t´. + +A _type alias_ `type ´t´ = ´T´` defines ´t´ to be an alias +name for the type ´T´. The left hand side of a type alias may +have a type parameter clause, e.g. `type ´t´[´\mathit{tps}\,´] = ´T´`. The scope +of a type parameter extends over the right hand side ´T´ and the +type parameter clause ´\mathit{tps}´ itself. + +The scope rules for [definitions](#basic-declarations-and-definitions) +and [type parameters](#function-declarations-and-definitions) +make it possible that a type name appears in its +own bound or in its right-hand side. However, it is a static error if +a type alias refers recursively to the defined type constructor itself. +That is, the type ´T´ in a type alias `type ´t´[´\mathit{tps}\,´] = ´T´` may not +refer directly or indirectly to the name ´t´. It is also an error if +an abstract type is directly or indirectly its own upper or lower bound. + +###### Example + +The following are legal type declarations and definitions: + +```scala +type IntList = List[Integer] +type T <: Comparable[T] +type Two[A] = Tuple2[A, A] +type MyCollection[+X] <: Iterable[X] +``` + +The following are illegal: + +```scala +type Abs = Comparable[Abs] // recursive type alias + +type S <: T // S, T are bounded by themselves. +type T <: S + +type T >: Comparable[T.That] // Cannot select from T. + // T is a type, not a value +type MyCollection <: Iterable // Type constructor members must explicitly + // state their type parameters. +``` + +If a type alias `type ´t´[´\mathit{tps}\,´] = ´S´` refers to a class type +´S´, the name ´t´ can also be used as a constructor for +objects of type ´S´. + +###### Example + +Suppose we make `Pair` an alias of the parameterized class `Tuple2`, +as follows: + +```scala +type Pair[+A, +B] = Tuple2[A, B] +object Pair { + def apply[A, B](x: A, y: B) = Tuple2(x, y) + def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x) +} +``` + +As a consequence, for any two types ´S´ and ´T´, the type +`Pair[´S´, ´T\,´]` is equivalent to the type `Tuple2[´S´, ´T\,´]`. +`Pair` can also be used as a constructor instead of `Tuple2`, as in: + +```scala +val x: Pair[Int, String] = new Pair(1, "abc") +``` + +## Type Parameters + +```ebnf +TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’ +VariantTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeParam +TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] [‘:’ Type] +``` + +Type parameters appear in type definitions, class definitions, and +function definitions. In this section we consider only type parameter +definitions with lower bounds `>: ´L´` and upper bounds +`<: ´U´` whereas a discussion of context bounds +`: ´U´` and view bounds `<% ´U´` +is deferred to [here](07-implicits.html#context-bounds-and-view-bounds). + +The most general form of a proper type parameter is +`´@a_1 \ldots @a_n´ ´\pm´ ´t´ >: ´L´ <: ´U´`. +Here, ´L´, and ´U´ are lower and upper bounds that +constrain possible type arguments for the parameter. It is a +compile-time error if ´L´ does not conform to ´U´. ´\pm´ is a _variance_, i.e. an optional prefix of either `+`, or +`-`. One or more annotations may precede the type parameter. + + + + + +The names of all type parameters must be pairwise different in their enclosing type parameter clause. The scope of a type parameter includes in each case the whole type parameter clause. Therefore it is possible that a type parameter appears as part of its own bounds or the bounds of other type parameters in the same clause. However, a type parameter may not be bounded directly or indirectly by itself. + +A type constructor parameter adds a nested type parameter clause to the type parameter. The most general form of a type constructor parameter is `´@a_1 \ldots @a_n \pm t[\mathit{tps}\,]´ >: ´L´ <: ´U´`. + +The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. Higher-order type parameters (the type parameters of a type parameter ´t´) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of ´t´. Therefore, their names must only be pairwise different from the names of other visible parameters. Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a `‘_’`, which is nowhere visible. + +###### Example +Here are some well-formed type parameter clauses: + +```scala +[S, T] +[@specialized T, U] +[Ex <: Throwable] +[A <: Comparable[B], B <: A] +[A, B >: A, C >: A <: B] +[M[X], N[X]] +[M[_], N[_]] // equivalent to previous clause +[M[X <: Bound[X]], Bound[_]] +[M[+X] <: Iterable[X]] +``` + +The following type parameter clauses are illegal: + +```scala +[A >: A] // illegal, `A' has itself as bound +[A <: B, B <: C, C <: A] // illegal, `A' has itself as bound +[A, B, C >: A <: B] // illegal lower bound `A' of `C' does + // not conform to upper bound `B'. +``` + +## Variance Annotations + +Variance annotations indicate how instances of parameterized types +vary with respect to [subtyping](03-types.html#conformance). A +‘+’ variance indicates a covariant dependency, a +‘-’ variance indicates a contravariant dependency, and a +missing variance indication indicates an invariant dependency. + +A variance annotation constrains the way the annotated type variable +may appear in the type or class which binds the type parameter. In a +type definition `type ´T´[´\mathit{tps}\,´] = ´S´`, or a type +declaration `type ´T´[´\mathit{tps}\,´] >: ´L´ <: ´U´` type parameters labeled +‘+’ must only appear in covariant position whereas +type parameters labeled ‘-’ must only appear in contravariant +position. Analogously, for a class definition +`class ´C´[´\mathit{tps}\,´](´\mathit{ps}\,´) extends ´T´ { ´x´: ´S´ => ...}`, +type parameters labeled +‘+’ must only appear in covariant position in the +self type ´S´ and the template ´T´, whereas type +parameters labeled ‘-’ must only appear in contravariant +position. + +The variance position of a type parameter in a type or template is +defined as follows. Let the opposite of covariance be contravariance, +and the opposite of invariance be itself. The top-level of the type +or template is always in covariant position. The variance position +changes at the following constructs. + +- The variance position of a method parameter is the opposite of the + variance position of the enclosing parameter clause. +- The variance position of a type parameter is the opposite of the + variance position of the enclosing type parameter clause. +- The variance position of the lower bound of a type declaration or type parameter + is the opposite of the variance position of the type declaration or parameter. +- The type of a mutable variable is always in invariant position. +- The right-hand side of a type alias is always in invariant position. +- The prefix ´S´ of a type selection `´S´#´T´` is always in invariant position. +- For a type argument ´T´ of a type `´S´[´\ldots T \ldots´ ]`: If the + corresponding type parameter is invariant, then ´T´ is in + invariant position. If the corresponding type parameter is + contravariant, the variance position of ´T´ is the opposite of + the variance position of the enclosing type `´S´[´\ldots T \ldots´ ]`. + + + +References to the type parameters in +[object-private or object-protected values, types, variables, or methods](05-classes-and-objects.html#modifiers) of the class are not +checked for their variance position. In these members the type parameter may +appear anywhere without restricting its legal variance annotations. + +###### Example +The following variance annotation is legal. + +```scala +abstract class P[+A, +B] { + def fst: A; def snd: B +} +``` + +With this variance annotation, type instances +of ´P´ subtype covariantly with respect to their arguments. +For instance, + +```scala +P[IOException, String] <: P[Throwable, AnyRef] +``` + +If the members of ´P´ are mutable variables, +the same variance annotation becomes illegal. + +```scala +abstract class Q[+A, +B](x: A, y: B) { + var fst: A = x // **** error: illegal variance: + var snd: B = y // `A', `B' occur in invariant position. +} +``` + +If the mutable variables are object-private, the class definition +becomes legal again: + +```scala +abstract class R[+A, +B](x: A, y: B) { + private[this] var fst: A = x // OK + private[this] var snd: B = y // OK +} +``` + +###### Example + +The following variance annotation is illegal, since ´a´ appears +in contravariant position in the parameter of `append`: + +```scala +abstract class Sequence[+A] { + def append(x: Sequence[A]): Sequence[A] + // **** error: illegal variance: + // `A' occurs in contravariant position. +} +``` + +The problem can be avoided by generalizing the type of `append` +by means of a lower bound: + +```scala +abstract class Sequence[+A] { + def append[B >: A](x: Sequence[B]): Sequence[B] +} +``` + +###### Example + +```scala +abstract class OutputChannel[-A] { + def write(x: A): Unit +} +``` + +With that annotation, we have that +`OutputChannel[AnyRef]` conforms to `OutputChannel[String]`. +That is, a +channel on which one can write any object can substitute for a channel +on which one can write only strings. + +## Function Declarations and Definitions + +```ebnf +Dcl ::= ‘def’ FunDcl +FunDcl ::= FunSig ‘:’ Type +Def ::= ‘def’ FunDef +FunDef ::= FunSig [‘:’ Type] ‘=’ Expr +FunSig ::= id [FunTypeParamClause] ParamClauses +FunTypeParamClause ::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’ +ParamClauses ::= {ParamClause} [[nl] ‘(’ ‘implicit’ Params ‘)’] +ParamClause ::= [nl] ‘(’ [Params] ‘)’ +Params ::= Param {‘,’ Param} +Param ::= {Annotation} id [‘:’ ParamType] [‘=’ Expr] +ParamType ::= Type + | ‘=>’ Type + | Type ‘*’ +``` + +A _function declaration_ has the form `def ´f\,\mathit{psig}´: ´T´`, where +´f´ is the function's name, ´\mathit{psig}´ is its parameter +signature and ´T´ is its result type. A _function definition_ +`def ´f\,\mathit{psig}´: ´T´ = ´e´` also includes a _function body_ ´e´, +i.e. an expression which defines the function's result. A parameter +signature consists of an optional type parameter clause `[´\mathit{tps}\,´]`, +followed by zero or more value parameter clauses +`(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_n´)`. Such a declaration or definition +introduces a value with a (possibly polymorphic) method type whose +parameter types and result type are as given. + +The type of the function body is expected to [conform](06-expressions.html#expression-typing) +to the function's declared +result type, if one is given. If the function definition is not +recursive, the result type may be omitted, in which case it is +determined from the packed type of the function body. + +A _type parameter clause_ ´\mathit{tps}´ consists of one or more +[type declarations](#type-declarations-and-type-aliases), which introduce type +parameters, possibly with bounds. The scope of a type parameter includes +the whole signature, including any of the type parameter bounds as +well as the function body, if it is present. + +A _value parameter clause_ ´\mathit{ps}´ consists of zero or more formal +parameter bindings such as `´x´: ´T´` or `´x: T = e´`, which bind value +parameters and associate them with their types. + +### Default Arguments + +Each value parameter +declaration may optionally define a default argument. The default argument +expression ´e´ is type-checked with an expected type ´T'´ obtained +by replacing all occurrences of the function's type parameters in ´T´ by +the undefined type. + +For every parameter ´p_{i,j}´ with a default argument a method named +`´f\$´default´\$´n` is generated which computes the default argument +expression. Here, ´n´ denotes the parameter's position in the method +declaration. These methods are parametrized by the type parameter clause +`[´\mathit{tps}\,´]` and all value parameter clauses +`(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_{i-1}´)` preceding ´p_{i,j}´. +The `´f\$´default´\$´n` methods are inaccessible for user programs. + +###### Example +In the method + +```scala +def compare[T](a: T = 0)(b: T = a) = (a == b) +``` + +the default expression `0` is type-checked with an undefined expected +type. When applying `compare()`, the default value `0` is inserted +and `T` is instantiated to `Int`. The methods computing the default +arguments have the form: + +```scala +def compare´\$´default´\$´1[T]: Int = 0 +def compare´\$´default´\$´2[T](a: T): T = a +``` + +The scope of a formal value parameter name ´x´ comprises all subsequent +parameter clauses, as well as the method return type and the function body, if +they are given. Both type parameter names and value parameter names must +be pairwise distinct. + +A default value which depends on earlier parameters uses the actual arguments +if they are provided, not the default arguments. + +```scala +def f(a: Int = 0)(b: Int = a + 1) = b // OK +// def f(a: Int = 0, b: Int = a + 1) // "error: not found: value a" +f(10)() // returns 11 (not 1) +``` + +If an [implicit argument](07-implicits.html#implicit-parameters) +is not found by implicit search, it may be supplied using a default argument. + +```scala +implicit val i: Int = 2 +def f(implicit x: Int, s: String = "hi") = s * x +f // "hihi" +``` + +### By-Name Parameters + +```ebnf +ParamType ::= ‘=>’ Type +``` + +The type of a value parameter may be prefixed by `=>`, e.g. +`´x´: => ´T´`. The type of such a parameter is then the +parameterless method type `=> ´T´`. This indicates that the +corresponding argument is not evaluated at the point of function +application, but instead is evaluated at each use within the +function. That is, the argument is evaluated using _call-by-name_. + +The by-name modifier is disallowed for parameters of classes that +carry a `val` or `var` prefix, including parameters of case +classes for which a `val` prefix is implicitly generated. + +###### Example +The declaration + +```scala +def whileLoop (cond: => Boolean) (stat: => Unit): Unit +``` + +indicates that both parameters of `whileLoop` are evaluated using +call-by-name. + +### Repeated Parameters + +```ebnf +ParamType ::= Type ‘*’ +``` + +The last value parameter of a parameter section may be suffixed by +`'*'`, e.g. `(..., ´x´:´T´*)`. The type of such a +_repeated_ parameter inside the method is then the sequence type +`scala.Seq[´T´]`. Methods with repeated parameters +`´T´*` take a variable number of arguments of type ´T´. +That is, if a method ´m´ with type +`(´p_1:T_1 , \ldots , p_n:T_n, p_s:S´*)´U´` is applied to arguments +´(e_1 , \ldots , e_k)´ where ´k \geq n´, then ´m´ is taken in that application +to have type ´(p_1:T_1 , \ldots , p_n:T_n, p_s:S , \ldots , p_{s'}:S)U´, with +´k - n´ occurrences of type +´S´ where any parameter names beyond ´p_s´ are fresh. The only exception to +this rule is if the last argument is +marked to be a _sequence argument_ via a `_*` type +annotation. If ´m´ above is applied to arguments +`(´e_1 , \ldots , e_n, e'´: _*)`, then the type of ´m´ in +that application is taken to be +`(´p_1:T_1, \ldots , p_n:T_n,p_{s}:´scala.Seq[´S´])`. + +It is not allowed to define any default arguments in a parameter section +with a repeated parameter. + +###### Example +The following method definition computes the sum of the squares of a +variable number of integer arguments. + +```scala +def sum(args: Int*) = { + var result = 0 + for (arg <- args) result += arg + result +} +``` + +The following applications of this method yield `0`, `1`, +`6`, in that order. + +```scala +sum() +sum(1) +sum(1, 2, 3) +``` + +Furthermore, assume the definition: + +```scala +val xs = List(1, 2, 3) +``` + +The following application of method `sum` is ill-formed: + +```scala +sum(xs) // ***** error: expected: Int, found: List[Int] +``` + +By contrast, the following application is well formed and yields again +the result `6`: + +```scala +sum(xs: _*) +``` + +### Procedures + +```ebnf +FunDcl ::= FunSig +FunDef ::= FunSig [nl] ‘{’ Block ‘}’ +``` + +Special syntax exists for procedures, i.e. functions that return the +`Unit` value `()`. +A _procedure declaration_ is a function declaration where the result type +is omitted. The result type is then implicitly completed to the +`Unit` type. E.g., `def ´f´(´\mathit{ps}´)` is equivalent to +`def ´f´(´\mathit{ps}´): Unit`. + +A _procedure definition_ is a function definition where the result type +and the equals sign are omitted; its defining expression must be a block. +E.g., `def ´f´(´\mathit{ps}´) {´\mathit{stats}´}` is equivalent to +`def ´f´(´\mathit{ps}´): Unit = {´\mathit{stats}´}`. + +###### Example +Here is a declaration and a definition of a procedure named `write`: + +```scala +trait Writer { + def write(str: String) +} +object Terminal extends Writer { + def write(str: String) { System.out.println(str) } +} +``` + +The code above is implicitly completed to the following code: + +```scala +trait Writer { + def write(str: String): Unit +} +object Terminal extends Writer { + def write(str: String): Unit = { System.out.println(str) } +} +``` + +### Method Return Type Inference + +A class member definition ´m´ that overrides some other function ´m'´ +in a base class of ´C´ may leave out the return type, even if it is +recursive. In this case, the return type ´R'´ of the overridden +function ´m'´, seen as a member of ´C´, is taken as the return type of +´m´ for each recursive invocation of ´m´. That way, a type ´R´ for the +right-hand side of ´m´ can be determined, which is then taken as the +return type of ´m´. Note that ´R´ may be different from ´R'´, as long +as ´R´ conforms to ´R'´. + +###### Example +Assume the following definitions: + +```scala +trait I { + def factorial(x: Int): Int +} +class C extends I { + def factorial(x: Int) = if (x == 0) 1 else x * factorial(x - 1) +} +``` + +Here, it is OK to leave out the result type of `factorial` +in `C`, even though the method is recursive. + + + +## Import Clauses + +```ebnf +Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} +ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors) +ImportSelectors ::= ‘{’ {ImportSelector ‘,’} + (ImportSelector | ‘_’) ‘}’ +ImportSelector ::= id [‘=>’ id | ‘=>’ ‘_’] +``` + +An import clause has the form `import ´p´.´I´` where ´p´ is a +[stable identifier](03-types.html#paths) and ´I´ is an import expression. +The import expression determines a set of names of importable members of ´p´ +which are made available without qualification. A member ´m´ of ´p´ is +_importable_ if it is [accessible](05-classes-and-objects.html#modifiers). +The most general form of an import expression is a list of _import selectors_ + +```scala +{ ´x_1´ => ´y_1 , \ldots , x_n´ => ´y_n´, _ } +``` + +for ´n \geq 0´, where the final wildcard `‘_’` may be absent. It +makes available each importable member `´p´.´x_i´` under the unqualified name +´y_i´. I.e. every import selector `´x_i´ => ´y_i´` renames +`´p´.´x_i´` to +´y_i´. If a final wildcard is present, all importable members ´z´ of +´p´ other than `´x_1 , \ldots , x_n,y_1 , \ldots , y_n´` are also made available +under their own unqualified names. + +Import selectors work in the same way for type and term members. For +instance, an import clause `import ´p´.{´x´ => ´y\,´}` renames the term +name `´p´.´x´` to the term name ´y´ and the type name `´p´.´x´` +to the type name ´y´. At least one of these two names must +reference an importable member of ´p´. + +If the target in an import selector is a wildcard, the import selector +hides access to the source member. For instance, the import selector +`´x´ => _` “renames” ´x´ to the wildcard symbol (which is +unaccessible as a name in user programs), and thereby effectively +prevents unqualified access to ´x´. This is useful if there is a +final wildcard in the same import selector list, which imports all +members not mentioned in previous import selectors. + +The scope of a binding introduced by an import-clause starts +immediately after the import clause and extends to the end of the +enclosing block, template, package clause, or compilation unit, +whichever comes first. + +Several shorthands exist. An import selector may be just a simple name +´x´. In this case, ´x´ is imported without renaming, so the +import selector is equivalent to `´x´ => ´x´`. Furthermore, it is +possible to replace the whole import selector list by a single +identifier or wildcard. The import clause `import ´p´.´x´` is +equivalent to `import ´p´.{´x\,´}`, i.e. it makes available without +qualification the member ´x´ of ´p´. The import clause +`import ´p´._` is equivalent to +`import ´p´.{_}`, +i.e. it makes available without qualification all members of ´p´ +(this is analogous to `import ´p´.*` in Java). + +An import clause with multiple import expressions +`import ´p_1´.´I_1 , \ldots , p_n´.´I_n´` is interpreted as a +sequence of import clauses +`import ´p_1´.´I_1´; ´\ldots´; import ´p_n´.´I_n´`. + +###### Example +Consider the object definition: + +```scala +object M { + def z = 0, one = 1 + def add(x: Int, y: Int): Int = x + y +} +``` + +Then the block + +```scala +{ import M.{one, z => zero, _}; add(zero, one) } +``` + +is equivalent to the block + +```scala +{ M.add(M.z, M.one) } +``` diff --git a/docs/_spec/05-classes-and-objects.md b/docs/_spec/05-classes-and-objects.md new file mode 100644 index 000000000000..5c3a74e608a2 --- /dev/null +++ b/docs/_spec/05-classes-and-objects.md @@ -0,0 +1,1160 @@ +--- +title: Classes & Objects +layout: default +chapter: 5 +--- + +# Classes and Objects + +```ebnf +TmplDef ::= [‘case’] ‘class’ ClassDef + | [‘case’] ‘object’ ObjectDef + | ‘trait’ TraitDef +``` + +[Classes](#class-definitions) and [objects](#object-definitions) +are both defined in terms of _templates_. + +## Templates + +```ebnf +ClassTemplate ::= [EarlyDefs] ClassParents [TemplateBody] +TraitTemplate ::= [EarlyDefs] TraitParents [TemplateBody] +ClassParents ::= Constr {‘with’ AnnotType} +TraitParents ::= AnnotType {‘with’ AnnotType} +TemplateBody ::= [nl] ‘{’ [SelfType] TemplateStat {semi TemplateStat} ‘}’ +SelfType ::= id [‘:’ Type] ‘=>’ + | this ‘:’ Type ‘=>’ +``` + +A _template_ defines the type signature, behavior and initial state of a +trait or class of objects or of a single object. Templates form part of +instance creation expressions, class definitions, and object +definitions. A template +`´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´ { ´\mathit{stats}´ }` +consists of a constructor invocation ´sc´ +which defines the template's _superclass_, trait references +`´mt_1 , \ldots , mt_n´` ´(n \geq 0)´, which define the +template's _traits_, and a statement sequence ´\mathit{stats}´ which +contains initialization code and additional member definitions for the +template. + +Each trait reference ´mt_i´ must denote a [trait](#traits). +By contrast, the superclass constructor ´sc´ normally refers to a +class which is not a trait. It is possible to write a list of +parents that starts with a trait reference, e.g. +`´mt_1´ with ´\ldots´ with ´mt_n´`. In that case the list +of parents is implicitly extended to include the supertype of ´mt_1´ +as the first parent type. The new supertype must have at least one +constructor that does not take parameters. In the following, we will +always assume that this implicit extension has been performed, so that +the first parent class of a template is a regular superclass +constructor, not a trait reference. + +The list of parents of a template must be well-formed. This means that +the class denoted by the superclass constructor ´sc´ must be a +subclass of the superclasses of all the traits ´mt_1 , \ldots , mt_n´. +In other words, the non-trait classes inherited by a template form a +chain in the inheritance hierarchy which starts with the template's +superclass. + +The _least proper supertype_ of a template is the class type or +[compound type](03-types.html#compound-types) consisting of all its parent +class types. + +The statement sequence ´\mathit{stats}´ contains member definitions that +define new members or overwrite members in the parent classes. If the +template forms part of an abstract class or trait definition, the +statement part ´\mathit{stats}´ may also contain declarations of abstract +members. If the template forms part of a concrete class definition, +´\mathit{stats}´ may still contain declarations of abstract type members, but +not of abstract term members. Furthermore, ´\mathit{stats}´ may in any case +also contain expressions; these are executed in the order they are +given as part of the initialization of a template. + +The sequence of template statements may be prefixed with a formal +parameter definition and an arrow, e.g. `´x´ =>`, or +`´x´:´T´ =>`. If a formal parameter is given, it can be +used as an alias for the reference `this` throughout the +body of the template. +If the formal parameter comes with a type ´T´, this definition affects +the _self type_ ´S´ of the underlying class or object as follows: Let ´C´ be the type +of the class or trait or object defining the template. +If a type ´T´ is given for the formal self parameter, ´S´ +is the greatest lower bound of ´T´ and ´C´. +If no type ´T´ is given, ´S´ is just ´C´. +Inside the template, the type of `this` is assumed to be ´S´. + +The self type of a class or object must conform to the self types of +all classes which are inherited by the template ´t´. + +A second form of self type annotation reads just +`this: ´S´ =>`. It prescribes the type ´S´ for `this` +without introducing an alias name for it. + +###### Example +Consider the following class definitions: + +```scala +class Base extends Object {} +trait Mixin extends Base {} +object O extends Mixin {} +``` + +In this case, the definition of `O` is expanded to: + +```scala +object O extends Base with Mixin {} +``` + + + +**Inheriting from Java Types** + +A template may have a Java class as its superclass and Java interfaces as its mixins. + +**Template Evaluation** + +Consider a template `´sc´ with ´mt_1´ with ´mt_n´ { ´\mathit{stats}´ }`. + +If this is the template of a [trait](#traits) then its _mixin-evaluation_ +consists of an evaluation of the statement sequence ´\mathit{stats}´. + +If this is not a template of a trait, then its _evaluation_ +consists of the following steps. + +- First, the superclass constructor ´sc´ is + [evaluated](#constructor-invocations). +- Then, all base classes in the template's [linearization](#class-linearization) + up to the template's superclass denoted by ´sc´ are + mixin-evaluated. Mixin-evaluation happens in reverse order of + occurrence in the linearization. +- Finally, the statement sequence ´\mathit{stats}\,´ is evaluated. + +###### Delayed Initialization +This statement sequence constitutes the initialization code for an object +or class after the superclass constructor invocation and the mixin-evaluation +of the template's base classes as described above. +Normally, this code is passed to a special hook, inaccessible to user code, +which simply executes it. + +However, in objects and classes (but not traits) which extend `scala.DelayedInit`, +the initialization code is passed to a `delayedInit` method which can be +overridden to implement arbitrary semantics. + +```scala +def delayedInit(body: => Unit): Unit +``` + +### Constructor Invocations + +```ebnf +Constr ::= AnnotType {‘(’ [Exprs] ‘)’} +``` + +Constructor invocations define the type, members, and initial state of +objects created by an instance creation expression, or of parts of an +object's definition which are inherited by a class or object +definition. A constructor invocation is a function application +`´x´.´c´[´\mathit{targs}´](´\mathit{args}_1´)´\ldots´(´\mathit{args}_n´)`, where ´x´ is a +[stable identifier](03-types.html#paths), ´c´ is a type name which either designates a +class or defines an alias type for one, ´\mathit{targs}´ is a type argument +list, ´\mathit{args}_1 , \ldots , \mathit{args}_n´ are argument lists, and there is a +constructor of that class which is [applicable](06-expressions.html#function-applications) +to the given arguments. If the constructor invocation uses named or +default arguments, it is transformed into a block expression using the +same transformation as described [here](sec:named-default). + +The prefix `´x´.` can be omitted. A type argument list +can be given only if the class ´c´ takes type parameters. Even then +it can be omitted, in which case a type argument list is synthesized +using [local type inference](06-expressions.html#local-type-inference). If no explicit +arguments are given, an empty list `()` is implicitly supplied. + +An evaluation of a constructor invocation +`´x´.´c´[´\mathit{targs}´](´\mathit{args}_1´)´\ldots´(´\mathit{args}_n´)` +consists of the following steps: + +- First, the prefix ´x´ is evaluated. +- Then, the arguments ´\mathit{args}_1 , \ldots , \mathit{args}_n´ are evaluated from + left to right. +- Finally, the class being constructed is initialized by evaluating the + template of the class referred to by ´c´. + +### Class Linearization + +The classes reachable through transitive closure of the direct +inheritance relation from a class ´C´ are called the _base classes_ of ´C´. Because of mixins, the inheritance relationship +on base classes forms in general a directed acyclic graph. A +linearization of this graph is defined as follows. + +###### Definition: linearization +Let ´C´ be a class with template +´C_1´ with ... with ´C_n´ { ´\mathit{stats}´ }`. +The _linearization_ of ´C´, ´\mathcal{L}(C)´ is defined as follows: +$$ +\mathcal{L}(C) = C, \mathcal{L}(C_n) \; \vec{+} \; \ldots \; \vec{+} \; \mathcal{L}(C_1) +$$ + +Here ´\vec{+}´ denotes concatenation where elements of the right operand +replace identical elements of the left operand: + +$$ +\begin{array}{lcll} +\{a, A\} \;\vec{+}\; B &=& a, (A \;\vec{+}\; B) &{\bf if} \; a \not\in B \\\\ + &=& A \;\vec{+}\; B &{\bf if} \; a \in B +\end{array} +$$ + +###### Example +Consider the following class definitions. + +```scala +abstract class AbsIterator extends AnyRef { ... } +trait RichIterator extends AbsIterator { ... } +class StringIterator extends AbsIterator { ... } +class Iter extends StringIterator with RichIterator { ... } +``` + +Then the linearization of class `Iter` is + +```scala +{ Iter, RichIterator, StringIterator, AbsIterator, AnyRef, Any } +``` + +Note that the linearization of a class refines the inheritance +relation: if ´C´ is a subclass of ´D´, then ´C´ precedes ´D´ in any +linearization where both ´C´ and ´D´ occur. +[Linearization](#definition:-linearization) also satisfies the property that +a linearization of a class always contains the linearization of its direct superclass as a suffix. + +For instance, the linearization of `StringIterator` is + +```scala +{ StringIterator, AbsIterator, AnyRef, Any } +``` + +which is a suffix of the linearization of its subclass `Iter`. +The same is not true for the linearization of mixins. +For instance, the linearization of `RichIterator` is + +```scala +{ RichIterator, AbsIterator, AnyRef, Any } +``` + +which is not a suffix of the linearization of `Iter`. + +### Class Members + +A class ´C´ defined by a template `´C_1´ with ´\ldots´ with ´C_n´ { ´\mathit{stats}´ }` +can define members in its statement sequence +´\mathit{stats}´ and can inherit members from all parent classes. Scala +adopts Java and C\#'s conventions for static overloading of +methods. It is thus possible that a class defines and/or inherits +several methods with the same name. To decide whether a defined +member of a class ´C´ overrides a member of a parent class, or whether +the two co-exist as overloaded variants in ´C´, Scala uses the +following definition of _matching_ on members: + +###### Definition: matching +A member definition ´M´ _matches_ a member definition ´M'´, if ´M´ +and ´M'´ bind the same name, and one of following holds. + +1. Neither ´M´ nor ´M'´ is a method definition. +2. ´M´ and ´M'´ define both monomorphic methods with equivalent argument types. +3. ´M´ defines a parameterless method and ´M'´ defines a method + with an empty parameter list `()` or _vice versa_. +4. ´M´ and ´M'´ define both polymorphic methods with + equal number of argument types ´\overline T´, ´\overline T'´ + and equal numbers of type parameters + ´\overline t´, ´\overline t'´, say, and ´\overline T' = [\overline t'/\overline t]\overline T´. + + + +Member definitions fall into two categories: concrete and abstract. +Members of class ´C´ are either _directly defined_ (i.e. they appear in +´C´'s statement sequence ´\mathit{stats}´) or they are _inherited_. There are two rules +that determine the set of members of a class, one for each category: + +A _concrete member_ of a class ´C´ is any concrete definition ´M´ in +some class ´C_i \in \mathcal{L}(C)´, except if there is a preceding class +´C_j \in \mathcal{L}(C)´ where ´j < i´ which directly defines a concrete +member ´M'´ matching ´M´. + +An _abstract member_ of a class ´C´ is any abstract definition ´M´ +in some class ´C_i \in \mathcal{L}(C)´, except if ´C´ contains already a +concrete member ´M'´ matching ´M´, or if there is a preceding class +´C_j \in \mathcal{L}(C)´ where ´j < i´ which directly defines an abstract +member ´M'´ matching ´M´. + +This definition also determines the [overriding](#overriding) relationships +between matching members of a class ´C´ and its parents. +First, a concrete definition always overrides an abstract definition. +Second, for definitions ´M´ and ´M´' which are both concrete or both abstract, +´M´ overrides ´M'´ if ´M´ appears in a class that precedes (in the +linearization of ´C´) the class in which ´M'´ is defined. + +It is an error if a template directly defines two matching members. It +is also an error if a template contains two members (directly defined +or inherited) with the same name and the same [erased type](03-types.html#type-erasure). +Finally, a template is not allowed to contain two methods (directly +defined or inherited) with the same name which both define default arguments. + +###### Example +Consider the trait definitions: + +```scala +trait A { def f: Int } +trait B extends A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 } +trait C extends A { override def f: Int = 4 ; def g: Int } +trait D extends B with C { def h: Int } +``` + +Then trait `D` has a directly defined abstract member `h`. It +inherits member `f` from trait `C` and member `g` from +trait `B`. + +### Overriding + + + +A member ´M´ of class ´C´ that [matches](#class-members) +a non-private member ´M'´ of a +base class of ´C´ is said to _override_ that member. In this case +the binding of the overriding member ´M´ must [subsume](03-types.html#conformance) +the binding of the overridden member ´M'´. +Furthermore, the following restrictions on modifiers apply to ´M´ and +´M'´: + +- ´M'´ must not be labeled `final`. +- ´M´ must not be [`private`](#modifiers). +- If ´M´ is labeled `private[´C´]` for some enclosing class or package ´C´, + then ´M'´ must be labeled `private[´C'´]` for some class or package ´C'´ where + ´C'´ equals ´C´ or ´C'´ is contained in ´C´. + + +- If ´M´ is labeled `protected`, then ´M'´ must also be + labeled `protected`. +- If ´M'´ is not an abstract member, then ´M´ must be labeled `override`. + Furthermore, one of two possibilities must hold: + - either ´M´ is defined in a subclass of the class where is ´M'´ is defined, + - or both ´M´ and ´M'´ override a third member ´M''´ which is defined + in a base class of both the classes containing ´M´ and ´M'´ +- If ´M'´ is [incomplete](#modifiers) in ´C´ then ´M´ must be + labeled `abstract override`. +- If ´M´ and ´M'´ are both concrete value definitions, then either none + of them is marked `lazy` or both must be marked `lazy`. + +- A stable member can only be overridden by a stable member. + For example, this is not allowed: + +```scala +class X { val stable = 1} +class Y extends X { override var stable = 1 } // error +``` + +Another restriction applies to abstract type members: An abstract type +member with a [volatile type](03-types.html#volatile-types) as its upper +bound may not override an abstract type member which does not have a +volatile upper bound. + +A special rule concerns parameterless methods. If a parameterless +method defined as `def ´f´: ´T´ = ...` or `def ´f´ = ...` overrides a method of +type ´()T'´ which has an empty parameter list, then ´f´ is also +assumed to have an empty parameter list. + +An overriding method inherits all default arguments from the definition +in the superclass. By specifying default arguments in the overriding method +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 + +Consider the definitions: + +```scala +trait Root { type T <: Root } +trait A extends Root { type T <: A } +trait B extends Root { type T <: B } +trait C extends A with B +``` + +Then the class definition `C` is not well-formed because the +binding of `T` in `C` is +`type T <: B`, +which fails to subsume the binding `type T <: A` of `T` +in type `A`. The problem can be solved by adding an overriding +definition of type `T` in class `C`: + +```scala +class C extends A with B { type T <: C } +``` + +### Inheritance Closure + +Let ´C´ be a class type. The _inheritance closure_ of ´C´ is the +smallest set ´\mathscr{S}´ of types such that + +- ´C´ is in ´\mathscr{S}´. +- If ´T´ is in ´\mathscr{S}´, then every type ´T'´ which forms syntactically + a part of ´T´ is also in ´\mathscr{S}´. +- If ´T´ is a class type in ´\mathscr{S}´, then all [parents](#templates) + of ´T´ are also in ´\mathscr{S}´. + +It is a static error if the inheritance closure of a class type +consists of an infinite number of types. (This restriction is +necessary to make subtyping decidable[^kennedy]). + +[^kennedy]: Kennedy, Pierce. [On Decidability of Nominal Subtyping with Variance.]( https://research.microsoft.com/pubs/64041/fool2007.pdf) in FOOL 2007 + +### Early Definitions + +```ebnf +EarlyDefs ::= ‘{’ [EarlyDef {semi EarlyDef}] ‘}’ ‘with’ +EarlyDef ::= {Annotation} {Modifier} PatVarDef +``` + +A template may start with an _early field definition_ clause, +which serves to define certain field values before the supertype +constructor is called. In a template + +```scala +{ val ´p_1´: ´T_1´ = ´e_1´ + ... + val ´p_n´: ´T_n´ = ´e_n´ +} with ´sc´ with ´mt_1´ with ´mt_n´ { ´\mathit{stats}´ } +``` + +The initial pattern definitions of ´p_1 , \ldots , p_n´ are called +_early definitions_. They define fields +which form part of the template. Every early definition must define +at least one variable. + +An early definition is type-checked and evaluated in the scope which +is in effect just before the template being defined, augmented by any +type parameters of the enclosing class and by any early definitions +preceding the one being defined. In particular, any reference to +`this` in an early definition refers +to the identity of `this` just outside the template. Consequently, it +is impossible for an early definition to refer to the object being +constructed by the template, or to refer to one of its fields and +methods, except for any other preceding early definition in the same +section. Furthermore, references to preceding early definitions +always refer to the value that's defined there and do not take into account +overriding definitions. In other words, a block of early definitions +is evaluated exactly as if it were a local block containing a number of value +definitions. + +Early definitions are evaluated +before the superclass constructor of the template is called, +in the order they are defined. + +###### Example +Early definitions are particularly useful for +traits, which do not have normal constructor parameters. Example: + +```scala +trait Greeting { + val name: String + val msg = "How are you, "+name +} +class C extends { + val name = "Bob" +} with Greeting { + println(msg) +} +``` + +In the code above, the field `name` is initialized before the +constructor of `Greeting` is called. Therefore, field `msg` in +class `Greeting` is properly initialized to `"How are you, Bob"`. + +If `name` had been initialized instead in `C`'s normal class +body, it would be initialized after the constructor of +`Greeting`. In that case, `msg` would be initialized to +`"How are you, "`. + +## Modifiers + +```ebnf +Modifier ::= LocalModifier + | AccessModifier + | ‘override’ +LocalModifier ::= ‘abstract’ + | ‘final’ + | ‘sealed’ + | ‘implicit’ + | ‘lazy’ +AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier] +AccessQualifier ::= ‘[’ (id | ‘this’) ‘]’ +``` + +Member definitions may be preceded by modifiers which affect the +accessibility and usage of the identifiers bound by them. If several +modifiers are given, their order does not matter, but the same +modifier may not occur more than once. Modifiers preceding a repeated +definition apply to all constituent definitions. The rules governing +the validity and meaning of a modifier are as follows. + +### `private` +The `private` modifier can be used with any definition or declaration in a +template. Private members of a template can be accessed only from within the +directly enclosing template and its companion module or +[companion class](#object-definitions). + +The `private` modifier is also valid for +[top-level](09-top-level-definitions.html#packagings) templates. + +A `private` modifier can be _qualified_ with an identifier ´C´ (e.g. +`private[´C´]`) that must denote a class or package enclosing the definition. +Members labeled with such a modifier are accessible respectively only from code +inside the package ´C´ or only from code inside the class ´C´ and its +[companion module](#object-definitions). + +A different form of qualification is `private[this]`. A member +´M´ marked with this modifier is called _object-protected_; it can be accessed only from within +the object in which it is defined. That is, a selection ´p.M´ is only +legal if the prefix is `this` or `´O´.this`, for some +class ´O´ enclosing the reference. In addition, the restrictions for +unqualified `private` apply. + +Members marked private without a qualifier are called _class-private_, +whereas members labeled with `private[this]` +are called _object-private_. A member _is private_ if it is +either class-private or object-private, but not if it is marked +`private[´C´]` where ´C´ is an identifier; in the latter +case the member is called _qualified private_. + +Class-private or object-private members may not be abstract, and may +not have `protected` or `override` modifiers. They are not inherited +by subclasses and they may not override definitions in parent classes. + +### `protected` +The `protected` modifier applies to class member definitions. +Protected members of a class can be accessed from within + - the template of the defining class, + - all templates that have the defining class as a base class, + - the companion module of any of those classes. + +A `protected` modifier can be qualified with an identifier ´C´ (e.g. +`protected[´C´]`) that must denote a class or package enclosing the definition. +Members labeled with such a modifier are also accessible respectively from all +code inside the package ´C´ or from all code inside the class ´C´ and its +[companion module](#object-definitions). + +A protected identifier ´x´ may be used as a member name in a selection +`´r´.´x´` only if one of the following applies: + - The access is within the template defining the member, or, if + a qualification ´C´ is given, inside the package ´C´, + or the class ´C´, or its companion module, or + - ´r´ is one of the reserved words `this` and + `super`, or + - ´r´'s type conforms to a type-instance of the + class which contains the access. + +A different form of qualification is `protected[this]`. A member +´M´ marked with this modifier is called _object-protected_; it can be accessed only from within +the object in which it is defined. That is, a selection ´p.M´ is only +legal if the prefix is `this` or `´O´.this`, for some +class ´O´ enclosing the reference. In addition, the restrictions for +unqualified `protected` apply. + +### `override` +The `override` modifier applies to class member definitions or declarations. +It is mandatory for member definitions or declarations that override some +other concrete member definition in a parent class. If an `override` +modifier is given, there must be at least one overridden member +definition or declaration (either concrete or abstract). + +### `abstract override` +The `override` modifier has an additional significance when +combined with the `abstract` modifier. That modifier combination +is only allowed for value members of traits. + +We call a member ´M´ of a template _incomplete_ if it is either +abstract (i.e. defined by a declaration), or it is labeled +`abstract` and `override` and +every member overridden by ´M´ is again incomplete. + +Note that the `abstract override` modifier combination does not +influence the concept whether a member is concrete or abstract. A +member is _abstract_ if only a declaration is given for it; +it is _concrete_ if a full definition is given. + +### `abstract` +The `abstract` modifier is used in class definitions. It is +redundant for traits, and mandatory for all other classes which have +incomplete members. Abstract classes cannot be +[instantiated](06-expressions.html#instance-creation-expressions) with a constructor invocation +unless followed by mixins and/or a refinement which override all +incomplete members of the class. Only abstract classes and traits can have +abstract term members. + +The `abstract` modifier can also be used in conjunction with +`override` for class member definitions. In that case the +previous discussion applies. + +### `final` +The `final` modifier applies to class member definitions and to +class definitions. A `final` class member definition may not be +overridden in subclasses. A `final` class may not be inherited by +a template. `final` is redundant for object definitions. Members +of final classes or objects are implicitly also final, so the +`final` modifier is generally redundant for them, too. Note, however, that +[constant value definitions](04-basic-declarations-and-definitions.html#value-declarations-and-definitions) +do require an explicit `final` modifier, +even if they are defined in a final class or object. +`final` is permitted for abstract classes +but it may not be applied to traits or incomplete members, +and it may not be combined in one modifier list with `sealed`. + +### `sealed` +The `sealed` modifier applies to class definitions. A +`sealed` class may not be directly inherited, except if the inheriting +template is defined in the same source file as the inherited class. +However, subclasses of a sealed class can be inherited anywhere. + +### `lazy` +The `lazy` modifier applies to value definitions. A `lazy` +value is initialized the first time it is accessed (which might never +happen at all). Attempting to access a lazy value during its +initialization might lead to looping behavior. If an exception is +thrown during initialization, the value is considered uninitialized, +and a later access will retry to evaluate its right hand side. + +###### Example +The following code illustrates the use of qualified private: + +```scala +package outerpkg.innerpkg +class Outer { + class Inner { + private[Outer] def f() + private[innerpkg] def g() + private[outerpkg] def h() + } +} +``` + +Here, accesses to the method `f` can appear anywhere within +`Outer`, but not outside it. Accesses to method +`g` can appear anywhere within the package +`outerpkg.innerpkg`, as would be the case for +package-private methods in Java. Finally, accesses to method +`h` can appear anywhere within package `outerpkg`, +including packages contained in it. + +###### Example +A useful idiom to prevent clients of a class from +constructing new instances of that class is to declare the class +`abstract` and `sealed`: + +```scala +object m { + abstract sealed class C (x: Int) { + def nextC = new C(x + 1) {} + } + val empty = new C(0) {} +} +``` + +For instance, in the code above clients can create instances of class +`m.C` only by calling the `nextC` method of an existing `m.C` +object; it is not possible for clients to create objects of class +`m.C` directly. Indeed the following two lines are both in error: + +```scala +new m.C(0) // **** error: C is abstract, so it cannot be instantiated. +new m.C(0) {} // **** error: illegal inheritance from sealed class. +``` + +A similar access restriction can be achieved by marking the primary +constructor `private` ([example](#example-private-constructor)). + +## Class Definitions + +```ebnf +TmplDef ::= ‘class’ ClassDef +ClassDef ::= id [TypeParamClause] {Annotation} + [AccessModifier] ClassParamClauses ClassTemplateOpt +ClassParamClauses ::= {ClassParamClause} + [[nl] ‘(’ implicit ClassParams ‘)’] +ClassParamClause ::= [nl] ‘(’ [ClassParams] ‘)’ +ClassParams ::= ClassParam {‘,’ ClassParam} +ClassParam ::= {Annotation} {Modifier} [(‘val’ | ‘var’)] + id [‘:’ ParamType] [‘=’ Expr] +ClassTemplateOpt ::= ‘extends’ ClassTemplate | [[‘extends’] TemplateBody] +``` + +The most general form of class definition is + +```scala +class ´c´[´\mathit{tps}\,´] ´as´ ´m´(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_n´) extends ´t´ ´\quad(n \geq 0)´. +``` + +Here, + + - ´c´ is the name of the class to be defined. + - ´\mathit{tps}´ is a non-empty list of type parameters of the class + being defined. The scope of a type parameter is the whole class + definition including the type parameter section itself. It is + illegal to define two type parameters with the same name. The type + parameter section `[´\mathit{tps}\,´]` may be omitted. A class with a type + parameter section is called _polymorphic_, otherwise it is called + _monomorphic_. + - ´as´ is a possibly empty sequence of + [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 + `private` or `protected`, possibly with a qualification. + If such an access modifier is given it applies to the primary constructor of the class. + - ´(\mathit{ps}\_1)\ldots(\mathit{ps}\_n)´ are formal value parameter clauses for + the _primary constructor_ of the class. The scope of a formal value parameter includes + all subsequent parameter sections and the template ´t´. However, a formal + value parameter may not form part of the types of any of the parent classes or members of the class template ´t´. + It is illegal to define two formal value parameters with the same name. + + If a class has no formal parameter section that is not implicit, an empty parameter section `()` is assumed. + + If a formal parameter declaration ´x: T´ is preceded by a `val` + or `var` keyword, an accessor (getter) [definition](04-basic-declarations-and-definitions.html#variable-declarations-and-definitions) + for this parameter is implicitly added to the class. + + The getter introduces a value member ´x´ of class ´c´ that is defined as an alias of the parameter. + If the introducing keyword is `var`, a setter accessor [`´x´_=`](04-basic-declarations-and-definitions.html#variable-declarations-and-definitions) is also implicitly added to the class. + In invocation of that setter `´x´_=(´e´)` changes the value of the parameter to the result of evaluating ´e´. + + The formal parameter declaration may contain modifiers, which then carry over to the accessor definition(s). + When access modifiers are given for a parameter, but no `val` or `var` keyword, `val` is assumed. + A formal parameter prefixed by `val` or `var` may not at the same time be a [call-by-name parameter](04-basic-declarations-and-definitions.html#by-name-parameters). + + - ´t´ is a [template](#templates) of the form + + ```scala + ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_m´ { ´\mathit{stats}´ } // ´m \geq 0´ + ``` + + which defines the base classes, behavior and initial state of objects of + the class. The extends clause + `extends ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_m´` + can be omitted, in which case + `extends scala.AnyRef` is assumed. The class body + `{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body + `{}` is assumed. + +This class definition defines a type `´c´[´\mathit{tps}\,´]` and a constructor +which when applied to parameters conforming to types ´\mathit{ps}´ +initializes instances of type `´c´[´\mathit{tps}\,´]` by evaluating the template +´t´. + +###### Example – `val` and `var` parameters +The following example illustrates `val` and `var` parameters of a class `C`: + +```scala +class C(x: Int, val y: String, var z: List[String]) +val c = new C(1, "abc", List()) +c.z = c.y :: c.z +``` + +###### Example – Private Constructor +The following class can be created only from its companion module. + +```scala +object Sensitive { + def makeSensitive(credentials: Certificate): Sensitive = + if (credentials == Admin) new Sensitive() + else throw new SecurityViolationException +} +class Sensitive private () { + ... +} +``` + +### Constructor Definitions + +```ebnf +FunDef ::= ‘this’ ParamClause ParamClauses + (‘=’ ConstrExpr | [nl] ConstrBlock) +ConstrExpr ::= SelfInvocation + | ConstrBlock +ConstrBlock ::= ‘{’ SelfInvocation {semi BlockStat} ‘}’ +SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} +``` + +A class may have additional constructors besides the primary +constructor. These are defined by constructor definitions of the form +`def this(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_n´) = ´e´`. Such a +definition introduces an additional constructor for the enclosing +class, with parameters as given in the formal parameter lists ´\mathit{ps}_1 +, \ldots , \mathit{ps}_n´, and whose evaluation is defined by the constructor +expression ´e´. The scope of each formal parameter is the subsequent +parameter sections and the constructor +expression ´e´. A constructor expression is either a self constructor +invocation `this(´\mathit{args}_1´)´\ldots´(´\mathit{args}_n´)` or a block +which begins with a self constructor invocation. The self constructor +invocation must construct a generic instance of the class. I.e. if the +class in question has name ´C´ and type parameters +`[´\mathit{tps}\,´]`, then a self constructor invocation must +generate an instance of `´C´[´\mathit{tps}\,´]`; it is not permitted +to instantiate formal type parameters. + +The signature and the self constructor invocation of a constructor +definition are type-checked and evaluated in the scope which is in +effect at the point of the enclosing class definition, augmented by +any type parameters of the enclosing class and by any +[early definitions](#early-definitions) of the enclosing template. +The rest of the +constructor expression is type-checked and evaluated as a function +body in the current class. + +If there are auxiliary constructors of a class ´C´, they form together +with ´C´'s primary [constructor](#class-definitions) +an overloaded constructor +definition. The usual rules for +[overloading resolution](06-expressions.html#overloading-resolution) +apply for constructor invocations of ´C´, +including for the self constructor invocations in the constructor +expressions themselves. However, unlike other methods, constructors +are never inherited. To prevent infinite cycles of constructor +invocations, there is the restriction that every self constructor +invocation must refer to a constructor definition which precedes it +(i.e. it must refer to either a preceding auxiliary constructor or the +primary constructor of the class). + +###### Example +Consider the class definition + +```scala +class LinkedList[A]() { + var head: A = _ + var tail: LinkedList[A] = null + def this(head: A) = { this(); this.head = head } + def this(head: A, tail: LinkedList[A]) = { this(head); this.tail = tail } +} +``` + +This defines a class `LinkedList` with three constructors. The +second constructor constructs a singleton list, while the +third one constructs a list with a given head and tail. + +### Case Classes + +```ebnf +TmplDef ::= ‘case’ ‘class’ ClassDef +``` + +If a class definition is prefixed with `case`, the class is said +to be a _case class_. + +A case class is required to have a parameter section that is not implicit. +The formal parameters in the first parameter section +are called _elements_ and are treated specially. +First, the value of such a parameter can be extracted as a +field of a constructor pattern. Second, a `val` prefix is +implicitly added to such a parameter, unless the parameter already carries +a `val` or `var` modifier. Hence, an accessor +definition for the parameter is [generated](#class-definitions). + +A case class definition of `´c´[´\mathit{tps}\,´](´\mathit{ps}_1\,´)´\ldots´(´\mathit{ps}_n´)` with type +parameters ´\mathit{tps}´ and value parameters ´\mathit{ps}´ implies +the definition of a companion object, which serves as an [extractor object](08-pattern-matching.html#extractor-patterns). It has the following shape: + +```scala +object ´c´ { + def apply[´\mathit{tps}\,´](´\mathit{ps}_1\,´)´\ldots´(´\mathit{ps}_n´): ´c´[´\mathit{tps}\,´] = new ´c´[´\mathit{Ts}\,´](´\mathit{xs}_1\,´)´\ldots´(´\mathit{xs}_n´) + def unapply[´\mathit{tps}\,´](´x´: ´c´[´\mathit{tps}\,´]) = + if (x eq null) scala.None + else scala.Some(´x.\mathit{xs}_{11}, \ldots , x.\mathit{xs}_{1k}´) +} +``` + +Here, ´\mathit{Ts}´ stands for the vector of types defined in the type +parameter section ´\mathit{tps}´, +each ´\mathit{xs}\_i´ denotes the parameter names of the parameter +section ´\mathit{ps}\_i´, and +´\mathit{xs}\_{11}, \ldots , \mathit{xs}\_{1k}´ denote the names of all parameters +in the first parameter section ´\mathit{xs}\_1´. +If a type parameter section is missing in the class, it is also missing in the `apply` and `unapply` methods. + +If the companion object ´c´ is already defined, +the `apply` and `unapply` methods are added to the existing object. +If the object ´c´ already has a [matching](#definition-matching) +`apply` (or `unapply`) member, no new definition is added. +The definition of `apply` is omitted if class ´c´ is `abstract`. + +If the case class definition contains an empty value parameter list, the +`unapply` method returns a `Boolean` instead of an `Option` type and +is defined as follows: + +```scala +def unapply[´\mathit{tps}\,´](´x´: ´c´[´\mathit{tps}\,´]) = x ne null +``` + +The name of the `unapply` method is changed to `unapplySeq` if the first +parameter section ´\mathit{ps}_1´ of ´c´ ends in a +[repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters). + +A method named `copy` is implicitly added to every case class unless the +class already has a member (directly defined or inherited) with that name, or the +class has a repeated parameter. The method is defined as follows: + +```scala +def copy[´\mathit{tps}\,´](´\mathit{ps}'_1\,´)´\ldots´(´\mathit{ps}'_n´): ´c´[´\mathit{tps}\,´] = new ´c´[´\mathit{Ts}\,´](´\mathit{xs}_1\,´)´\ldots´(´\mathit{xs}_n´) +``` + +Again, `´\mathit{Ts}´` stands for the vector of types defined in the type parameter section `´\mathit{tps}´` +and each `´xs_i´` denotes the parameter names of the parameter section `´ps'_i´`. The value +parameters `´ps'_{1,j}´` of first parameter list have the form `´x_{1,j}´:´T_{1,j}´=this.´x_{1,j}´`, +the other parameters `´ps'_{i,j}´` of the `copy` method are defined as `´x_{i,j}´:´T_{i,j}´`. +In all cases `´x_{i,j}´` and `´T_{i,j}´` refer to the name and type of the corresponding class parameter +`´\mathit{ps}_{i,j}´`. + +Every case class implicitly overrides some method definitions of class +[`scala.AnyRef`](12-the-scala-standard-library.html#root-classes) unless a definition of the same +method is already given in the case class itself or a concrete +definition of the same method is given in some base class of the case +class different from `AnyRef`. In particular: + +- Method `equals: (Any)Boolean` is structural equality, where two + instances are equal if they both belong to the case class in question and they + have equal (with respect to `equals`) constructor arguments (restricted to the class's _elements_, i.e., the first parameter section). +- Method `hashCode: Int` computes a hash-code. If the hashCode methods + of the data structure members map equal (with respect to equals) + values to equal hash-codes, then the case class hashCode method does + too. +- Method `toString: String` returns a string representation which + contains the name of the class and its elements. + +###### Example +Here is the definition of abstract syntax for lambda calculus: + +```scala +class Expr +case class Var (x: String) extends Expr +case class Apply (f: Expr, e: Expr) extends Expr +case class Lambda(x: String, e: Expr) extends Expr +``` + +This defines a class `Expr` with case classes +`Var`, `Apply` and `Lambda`. A call-by-value evaluator +for lambda expressions could then be written as follows. + +```scala +type Env = String => Value +case class Value(e: Expr, env: Env) + +def eval(e: Expr, env: Env): Value = e match { + case Var (x) => + env(x) + case Apply(f, g) => + val Value(Lambda (x, e1), env1) = eval(f, env) + val v = eval(g, env) + eval (e1, (y => if (y == x) v else env1(y))) + case Lambda(_, _) => + Value(e, env) +} +``` + +It is possible to define further case classes that extend type +`Expr` in other parts of the program, for instance + +```scala +case class Number(x: Int) extends Expr +``` + +This form of extensibility can be excluded by declaring the base class +`Expr` `sealed`; in this case, all classes that +directly extend `Expr` must be in the same source file as +`Expr`. + +## Traits + +```ebnf +TmplDef ::= ‘trait’ TraitDef +TraitDef ::= id [TypeParamClause] TraitTemplateOpt +TraitTemplateOpt ::= ‘extends’ TraitTemplate | [[‘extends’] TemplateBody] +``` + +A _trait_ is a class that is meant to be added to some other class +as a mixin. Unlike normal classes, traits cannot have +constructor parameters. Furthermore, no constructor arguments are +passed to the superclass of the trait. This is not necessary as traits are +initialized after the superclass is initialized. + +Assume a trait ´D´ defines some aspect of an instance ´x´ of type ´C´ (i.e. ´D´ is a base class of ´C´). +Then the _actual supertype_ of ´D´ in ´x´ is the compound type consisting of all the +base classes in ´\mathcal{L}(C)´ that succeed ´D´. The actual supertype gives +the context for resolving a [`super` reference](06-expressions.html#this-and-super) in a trait. +Note that the actual supertype depends on the type to which the trait is added in a mixin composition; +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 +The following trait defines the property +of being comparable to objects of some type. It contains an abstract +method `<` and default implementations of the other +comparison operators `<=`, `>`, and +`>=`. + +```scala +trait Comparable[T <: Comparable[T]] { self: T => + def < (that: T): Boolean + def <=(that: T): Boolean = this < that || this == that + def > (that: T): Boolean = that < this + def >=(that: T): Boolean = that <= this +} +``` + +###### Example +Consider an abstract class `Table` that implements maps +from a type of keys `A` to a type of values `B`. The class +has a method `set` to enter a new key / value pair into the table, +and a method `get` that returns an optional value matching a +given key. Finally, there is a method `apply` which is like +`get`, except that it returns a given default value if the table +is undefined for the given key. This class is implemented as follows. + +```scala +abstract class Table[A, B](defaultValue: B) { + def get(key: A): Option[B] + def set(key: A, value: B): Unit + def apply(key: A) = get(key) match { + case Some(value) => value + case None => defaultValue + } +} +``` + +Here is a concrete implementation of the `Table` class. + +```scala +class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) { + private var elems: List[(A, B)] = Nil + def get(key: A) = elems.find(_._1 == key).map(_._2) + def set(key: A, value: B) = { elems = (key, value) :: elems } +} +``` + +Here is a trait that prevents concurrent access to the +`get` and `set` operations of its parent class: + +```scala +trait SynchronizedTable[A, B] extends Table[A, B] { + abstract override def get(key: A): B = + synchronized { super.get(key) } + abstract override def set(key: A, value: B) = + synchronized { super.set(key, value) } +} +``` + +Note that `SynchronizedTable` does not pass an argument to +its superclass, `Table`, even though `Table` is defined with a +formal parameter. Note also that the `super` calls +in `SynchronizedTable`'s `get` and `set` methods +statically refer to abstract methods in class `Table`. This is +legal, as long as the calling method is labeled +[`abstract override`](#modifiers). + +Finally, the following mixin composition creates a synchronized list +table with strings as keys and integers as values and with a default +value `0`: + +```scala +object MyTable extends ListTable[String, Int](0) with SynchronizedTable[String, Int] +``` + +The object `MyTable` inherits its `get` and `set` +method from `SynchronizedTable`. The `super` calls in these +methods are re-bound to refer to the corresponding implementations in +`ListTable`, which is the actual supertype of `SynchronizedTable` +in `MyTable`. + +## Object Definitions + +```ebnf +ObjectDef ::= id ClassTemplate +``` + +An _object definition_ defines a single object of a new class. Its +most general form is +`object ´m´ extends ´t´`. Here, +´m´ is the name of the object to be defined, and +´t´ is a [template](#templates) of the form + +```scala +´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´ { ´\mathit{stats}´ } +``` + +which defines the base classes, behavior and initial state of ´m´. +The extends clause `extends ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´` +can be omitted, in which case +`extends scala.AnyRef` is assumed. The class body +`{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body +`{}` is assumed. + +The object definition defines a single object (or: _module_) +conforming to the template ´t´. It is roughly equivalent to the +following definition of a lazy value: + +```scala +lazy val ´m´ = new ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´ { this: ´m.type´ => ´\mathit{stats}´ } +``` + +Note that the value defined by an object definition is instantiated +lazily. The `new ´m´$cls` constructor is evaluated +not at the point of the object definition, but is instead evaluated +the first time ´m´ is dereferenced during execution of the program +(which might be never at all). An attempt to dereference ´m´ again +during evaluation of the constructor will lead to an infinite loop +or run-time error. +Other threads trying to dereference ´m´ while the +constructor is being evaluated block until evaluation is complete. + +The expansion given above is not accurate for top-level objects. It +cannot be because variable and method definition cannot appear on the +top-level outside of a [package object](09-top-level-definitions.html#package-objects). Instead, +top-level objects are translated to static fields. + +###### Example +Classes in Scala do not have static members; however, an equivalent +effect can be achieved by an accompanying object definition +E.g. + +```scala +abstract class Point { + val x: Double + val y: Double + def isOrigin = (x == 0.0 && y == 0.0) +} +object Point { + val origin = new Point() { val x = 0.0; val y = 0.0 } +} +``` + +This defines a class `Point` and an object `Point` which +contains `origin` as a member. Note that the double use of the +name `Point` is legal, since the class definition defines the +name `Point` in the type name space, whereas the object +definition defines a name in the term namespace. + +This technique is applied by the Scala compiler when interpreting a +Java class with static members. Such a class ´C´ is conceptually seen +as a pair of a Scala class that contains all instance members of ´C´ +and a Scala object that contains all static members of ´C´. + +Generally, a _companion module_ of a class is an object which has +the same name as the class and is defined in the same scope and +compilation unit. Conversely, the class is called the _companion class_ +of the module. + +Very much like a concrete class definition, an object definition may +still contain declarations of abstract type members, but not of +abstract term members. diff --git a/docs/_spec/06-expressions.md b/docs/_spec/06-expressions.md new file mode 100644 index 000000000000..f574d7ad2469 --- /dev/null +++ b/docs/_spec/06-expressions.md @@ -0,0 +1,1828 @@ +--- +title: Expressions +layout: default +chapter: 6 +--- + +# Expressions + +```ebnf +Expr ::= (Bindings | id | ‘_’) ‘=>’ Expr + | Expr1 +Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] + | ‘while’ ‘(’ Expr ‘)’ {nl} Expr + | ‘try’ Expr [‘catch’ Expr] [‘finally’ Expr] + | ‘do’ Expr [semi] ‘while’ ‘(’ Expr ‘)’ + | ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) {nl} [‘yield’] Expr + | ‘throw’ Expr + | ‘return’ [Expr] + | [SimpleExpr ‘.’] id ‘=’ Expr + | SimpleExpr1 ArgumentExprs ‘=’ Expr + | PostfixExpr + | PostfixExpr Ascription + | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’ +PostfixExpr ::= InfixExpr [id [nl]] +InfixExpr ::= PrefixExpr + | InfixExpr id [nl] InfixExpr +PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr +SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody) + | BlockExpr + | SimpleExpr1 [‘_’] +SimpleExpr1 ::= Literal + | Path + | ‘_’ + | ‘(’ [Exprs] ‘)’ + | SimpleExpr ‘.’ id + | SimpleExpr TypeArgs + | SimpleExpr1 ArgumentExprs + | XmlExpr +Exprs ::= Expr {‘,’ Expr} +BlockExpr ::= ‘{’ CaseClauses ‘}’ + | ‘{’ Block ‘}’ +Block ::= BlockStat {semi BlockStat} [ResultExpr] +ResultExpr ::= Expr1 + | (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block +Ascription ::= ‘:’ InfixType + | ‘:’ Annotation {Annotation} + | ‘:’ ‘_’ ‘*’ +``` + +Expressions are composed of operators and operands. Expression forms are +discussed subsequently in decreasing order of precedence. + +## Expression Typing + +The typing of expressions is often relative to some _expected type_ (which might be undefined). When we write "expression ´e´ is expected to conform to type ´T´", we mean: + 1. the expected type of ´e´ is ´T´, and + 2. the type of expression ´e´ must conform to ´T´. + +The following skolemization rule is applied universally for every +expression: If the type of an expression would be an existential type +´T´, then the type of the expression is assumed instead to be a +[skolemization](03-types.html#existential-types) of ´T´. + +Skolemization is reversed by type packing. Assume an expression ´e´ of +type ´T´ and let ´t_1[\mathit{tps}\_1] >: L_1 <: U_1 , \ldots , t_n[\mathit{tps}\_n] >: L_n <: U_n´ be +all the type variables created by skolemization of some part of ´e´ which are free in ´T´. +Then the _packed type_ of ´e´ is + +```scala +´T´ forSome { type ´t_1[\mathit{tps}\_1] >: L_1 <: U_1´; ´\ldots´; type ´t_n[\mathit{tps}\_n] >: L_n <: U_n´ }. +``` + +## Literals + +```ebnf +SimpleExpr ::= Literal +``` + +Typing of literals is described along with their [lexical syntax](01-lexical-syntax.html#literals); +their evaluation is immediate. + +## The _Null_ Value + +The `null` value is of type `scala.Null`, and thus conforms to every reference type. +It denotes a reference value which refers to a special `null` object. +This object implements methods in class `scala.AnyRef` as follows: + +- `eq(´x\,´)` and `==(´x\,´)` return `true` iff the + argument ´x´ is also the "null" object. +- `ne(´x\,´)` and `!=(´x\,´)` return true iff the + argument x is not also the "null" object. +- `isInstanceOf[´T\,´]` always returns `false`. +- `asInstanceOf[´T\,´]` returns the [default value](04-basic-declarations-and-definitions.html#value-declarations-and-definitions) of type ´T´. +- `##` returns ``0``. + +A reference to any other member of the "null" object causes a +`NullPointerException` to be thrown. + +## Designators + +```ebnf +SimpleExpr ::= Path + | SimpleExpr ‘.’ id +``` + +A designator refers to a named term. It can be a _simple name_ or +a _selection_. + +A simple name ´x´ refers to a value as specified +[here](02-identifiers-names-and-scopes.html#identifiers,-names-and-scopes). +If ´x´ is bound by a definition or declaration in an enclosing class +or object ´C´, it is taken to be equivalent to the selection +`´C´.this.´x´` where ´C´ is taken to refer to the class containing ´x´ +even if the type name ´C´ is [shadowed](02-identifiers-names-and-scopes.html#identifiers,-names-and-scopes) at the +occurrence of ´x´. + +If ´r´ is a [stable identifier](03-types.html#paths) of type ´T´, the selection ´r.x´ refers +statically to a term member ´m´ of ´r´ that is identified in ´T´ by +the name ´x´. + + + +For other expressions ´e´, ´e.x´ is typed as +if it was `{ val ´y´ = ´e´; ´y´.´x´ }`, for some fresh name +´y´. + +The expected type of a designator's prefix is always undefined. The +type of a designator is the type ´T´ of the entity it refers to, with +the following exception: The type of a [path](03-types.html#paths) ´p´ +which occurs in a context where a [stable type](03-types.html#singleton-types) +is required is the singleton type `´p´.type`. + +The contexts where a stable type is required are those that satisfy +one of the following conditions: + +1. The path ´p´ occurs as the prefix of a selection and it does not +designate a constant, or +1. The expected type ´\mathit{pt}´ is a stable type, or +1. The expected type ´\mathit{pt}´ is an abstract type with a stable type as lower + bound, and the type ´T´ of the entity referred to by ´p´ does not + conform to ´\mathit{pt}´, or +1. The path ´p´ designates a module. + +The selection ´e.x´ is evaluated by first evaluating the qualifier +expression ´e´, which yields an object ´r´, say. The selection's +result is then the member of ´r´ that is either defined by ´m´ or defined +by a definition overriding ´m´. + +## This and Super + +```ebnf +SimpleExpr ::= [id ‘.’] ‘this’ + | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id +``` + +The expression `this` can appear in the statement part of a +template or compound type. It stands for the object being defined by +the innermost template or compound type enclosing the reference. If +this is a compound type, the type of `this` is that compound type. +If it is a template of a +class or object definition with simple name ´C´, the type of this +is the same as the type of `´C´.this`. + +The expression `´C´.this` is legal in the statement part of an +enclosing class or object definition with simple name ´C´. It +stands for the object being defined by the innermost such definition. +If the expression's expected type is a stable type, or +`´C´.this` occurs as the prefix of a selection, its type is +`´C´.this.type`, otherwise it is the self type of class ´C´. + +A reference `super.´m´` refers statically to a method or type ´m´ +in the least proper supertype of the innermost template containing the +reference. It evaluates to the member ´m'´ in the actual supertype of +that template which is equal to ´m´ or which overrides ´m´. The +statically referenced member ´m´ must be a type or a +method. + + + +If it is +a method, it must be concrete, or the template +containing the reference must have a member ´m'´ which overrides ´m´ +and which is labeled `abstract override`. + +A reference `´C´.super.´m´` refers statically to a method +or type ´m´ in the least proper supertype of the innermost enclosing class or +object definition named ´C´ which encloses the reference. It evaluates +to the member ´m'´ in the actual supertype of that class or object +which is equal to ´m´ or which overrides ´m´. The +statically referenced member ´m´ must be a type or a +method. If the statically +referenced member ´m´ is a method, it must be concrete, or the innermost enclosing +class or object definition named ´C´ must have a member ´m'´ which +overrides ´m´ and which is labeled `abstract override`. + +The `super` prefix may be followed by a trait qualifier +`[´T\,´]`, as in `´C´.super[´T\,´].´x´`. This is +called a _static super reference_. In this case, the reference is +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 +Consider the following class definitions + +```scala +class Root { def x = "Root" } +class A extends Root { override def x = "A" ; def superA = super.x } +trait B extends Root { override def x = "B" ; def superB = super.x } +class C extends Root with B { + override def x = "C" ; def superC = super.x +} +class D extends A with B { + override def x = "D" ; def superD = super.x +} +``` + +The linearization of class `C` is `{C, B, Root}` and +the linearization of class `D` is `{D, B, A, Root}`. +Then we have: + +```scala +(new A).superA == "Root" + +(new C).superB == "Root" +(new C).superC == "B" + +(new D).superA == "Root" +(new D).superB == "A" +(new D).superD == "B" +``` + +Note that the `superB` method returns different results +depending on whether `B` is mixed in with class `Root` or `A`. + +## Function Applications + +```ebnf +SimpleExpr ::= SimpleExpr1 ArgumentExprs +ArgumentExprs ::= ‘(’ [Exprs] ‘)’ + | ‘(’ ‘using’ Exprs ‘)’ + | ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’ + | [nl] BlockExpr +Exprs ::= Expr {‘,’ Expr} +``` + +An application `´f(e_1 , \ldots , e_m)´` applies the function `´f´` to the argument expressions `´e_1, \ldots , e_m´`. For this expression to be well-typed, the function must be *applicable* to its arguments, which is defined next by case analysis on ´f´'s type. + +If ´f´ has a method type `(´p_1´:´T_1 , \ldots , p_n´:´T_n´)´U´`, each argument expression ´e_i´ is typed with the corresponding parameter type ´T_i´ as expected type. Let ´S_i´ be the type of argument ´e_i´ ´(i = 1 , \ldots , m)´. The method ´f´ must be _applicable_ to its arguments ´e_1, \ldots , e_n´ of types ´S_1 , \ldots , S_n´. We say that an argument expression ´e_i´ is a _named_ argument if it has the form `´x_i=e'_i´` and `´x_i´` is one of the parameter names `´p_1, \ldots, p_n´`. + +Once the types ´S_i´ have been determined, the method ´f´ of the above method type is said to be applicable if all of the following conditions hold: + - for every named argument ´p_j=e_i'´ the type ´S_i´ is [compatible](03-types.html#compatibility) with the parameter type ´T_j´; + - for every positional argument ´e_i´ the type ´S_i´ is [compatible](03-types.html#compatibility) with ´T_i´; + - if the expected type is defined, the result type ´U´ is [compatible](03-types.html#compatibility) to it. + +If ´f´ is a polymorphic method, [local type inference](#local-type-inference) is used to instantiate ´f´'s type parameters. +The polymorphic method is applicable if type inference can determine type arguments so that the instantiated method is applicable. + +If ´f´ has some value type, the application is taken to be equivalent to `´f´.apply(´e_1 , \ldots , e_m´)`, +i.e. the application of an `apply` method defined by ´f´. The value `´f´` is applicable to the given arguments if `´f´.apply` is applicable. + + +The application `´f´(´e_1 , \ldots , e_n´)` evaluates ´f´ and then each argument +´e_1 , \ldots , e_n´ from left to right, except for arguments that correspond to +a by-name parameter (see below). Each argument expression is converted to the +type of its corresponding formal parameter. After that, the application is +rewritten to the function's right hand side, with actual arguments substituted +for formal parameters. The result of evaluating the rewritten right-hand side +is finally converted to the function's declared result type, if one is given. + +The case of a formal parameter with a parameterless +method type `=> ´T´` is treated specially. In this case, the +corresponding actual argument expression ´e´ is not evaluated before the +application. Instead, every use of the formal parameter on the +right-hand side of the rewrite rule entails a re-evaluation of ´e´. +In other words, the evaluation order for +`=>`-parameters is _call-by-name_ whereas the evaluation +order for normal parameters is _call-by-value_. +Furthermore, it is required that ´e´'s [packed type](#expression-typing) +conforms to the parameter type ´T´. +The behavior of by-name parameters is preserved if the application is +transformed into a block due to named or default arguments. In this case, +the local value for that parameter has the form `val ´y_i´ = () => ´e´` +and the argument passed to the function is `´y_i´()`. + +The last argument in an application may be marked as a sequence +argument, e.g. `´e´: _*`. Such an argument must correspond +to a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type +`´S´*` and it must be the only argument matching this +parameter (i.e. the number of formal parameters and actual arguments +must be the same). Furthermore, the type of ´e´ must conform to +`scala.Seq[´T´]`, for some type ´T´ which conforms to +´S´. In this case, the argument list is transformed by replacing the +sequence ´e´ with its elements. When the application uses named +arguments, the vararg parameter has to be specified exactly once. + +If only a single argument is supplied, it may be supplied as a block expression +and parentheses can be omitted, in the form `´f´ { block }`. This is valid when +`f` has a single formal parameter or when all other formal parameters have +default values. + +A function application usually allocates a new frame on the program's +run-time stack. However, if a local method or a final method calls +itself as its last action, the call is executed using the stack-frame +of the caller. + +###### Example +Assume the following method which computes the sum of a +variable number of arguments: + +```scala +def sum(xs: Int*) = xs.foldLeft(0)((x, y) => x + y) +``` + +Then + +```scala +sum(1, 2, 3, 4) +sum(List(1, 2, 3, 4): _*) +``` + +both yield `10` as result. On the other hand, + +```scala +sum(List(1, 2, 3, 4)) +``` + +would not typecheck. + +An argument list may begin with the soft keyword `using` to facilitate cross-compilation with Scala 3. +The keyword is ignored. + +### Named and Default Arguments + +If an application is to use named arguments ´p = e´ or default +arguments, the following conditions must hold. + +- For every named argument ´p_i = e_i´ which appears left of a positional argument + in the argument list ´e_1 \ldots e_m´, the argument position ´i´ coincides with + the position of parameter ´p_i´ in the parameter list of the applied method. +- The names ´x_i´ of all named arguments are pairwise distinct and no named + argument defines a parameter which is already specified by a + positional argument. +- Every formal parameter ´p_j:T_j´ which is not specified by either a positional + or named argument has a default argument. + +If the application uses named or default +arguments the following transformation is applied to convert it into +an application without named or default arguments. + +If the method ´f´ +has the form `´p.m´[´\mathit{targs}´]` it is transformed into the +block + +```scala +{ val q = ´p´ + q.´m´[´\mathit{targs}´] +} +``` + +If the method ´f´ is itself an application expression the transformation +is applied recursively on ´f´. The result of transforming ´f´ is a block of +the form + +```scala +{ val q = ´p´ + val ´x_1´ = expr´_1´ + ´\ldots´ + val ´x_k´ = expr´_k´ + q.´m´[´\mathit{targs}´](´\mathit{args}_1´)´, \ldots ,´(´\mathit{args}_l´) +} +``` + +where every argument in ´(\mathit{args}\_1) , \ldots , (\mathit{args}\_l)´ is a reference to +one of the values ´x_1 , \ldots , x_k´. To integrate the current application +into the block, first a value definition using a fresh name ´y_i´ is created +for every argument in ´e_1 , \ldots , e_m´, which is initialised to ´e_i´ for +positional arguments and to ´e'_i´ for named arguments of the form +`´x_i=e'_i´`. Then, for every parameter which is not specified +by the argument list, a value definition using a fresh name ´z_i´ is created, +which is initialized using the method computing the +[default argument](04-basic-declarations-and-definitions.html#function-declarations-and-definitions) of +this parameter. + +Let ´\mathit{args}´ be a permutation of the generated names ´y_i´ and ´z_i´ such such +that the position of each name matches the position of its corresponding +parameter in the method type `(´p_1:T_1 , \ldots , p_n:T_n´)´U´`. +The final result of the transformation is a block of the form + +```scala +{ val q = ´p´ + val ´x_1´ = expr´_1´ + ´\ldots´ + val ´x_l´ = expr´_k´ + val ´y_1´ = ´e_1´ + ´\ldots´ + val ´y_m´ = ´e_m´ + val ´z_1´ = ´q.m\$default\$i[\mathit{targs}](\mathit{args}_1), \ldots ,(\mathit{args}_l)´ + ´\ldots´ + val ´z_d´ = ´q.m\$default\$j[\mathit{targs}](\mathit{args}_1), \ldots ,(\mathit{args}_l)´ + q.´m´[´\mathit{targs}´](´\mathit{args}_1´)´, \ldots ,´(´\mathit{args}_l´)(´\mathit{args}´) +} +``` + +### Signature Polymorphic Methods + +For invocations of signature polymorphic methods of the target platform `´f´(´e_1 , \ldots , e_m´)`, +the invoked method has a different method type `(´p_1´:´T_1 , \ldots , p_n´:´T_n´)´U´` at each call +site. The parameter types `´T_ , \ldots , T_n´` are the types of the argument expressions +`´e_1 , \ldots , e_m´`. If the declared return type `´R´` of the signature polymorphic method is +any type other than `scala.AnyRef`, then the return type `´U´` is `´R´`. +Otherwise, `´U´` is the expected type at the call site. If the expected type is undefined then +`´U´` is `scala.AnyRef`. The parameter names `´p_1 , \ldots , p_n´` are fresh. + +###### Note + +On the Java platform version 11 and later, signature polymorphic methods are native, +members of `java.lang.invoke.MethodHandle` or `java.lang.invoke.VarHandle`, and have a single +repeated parameter of type `java.lang.Object*`. + + +## Method Values + +```ebnf +SimpleExpr ::= SimpleExpr1 ‘_’ +``` + +The expression `´e´ _` is well-formed if ´e´ is of method +type or if ´e´ is a call-by-name parameter. If ´e´ is a method with +parameters, `´e´ _` represents ´e´ converted to a function +type by [eta expansion](#eta-expansion-section). If ´e´ is a +parameterless method or call-by-name parameter of type +`=> ´T´`, `´e´ _` represents the function of type +`() => ´T´`, which evaluates ´e´ when it is applied to the empty +parameter list `()`. + +###### Example +The method values in the left column are each equivalent to the [eta-expanded expressions](#eta-expansion-section) on the right. + +| placeholder syntax | eta-expansion | +|------------------------------ | ----------------------------------------------------------------------------| +|`math.sin _` | `x => math.sin(x)` | +|`math.pow _` | `(x1, x2) => math.pow(x1, x2)` | +|`val vs = 1 to 9; vs.fold _` | `(z) => (op) => vs.fold(z)(op)` | +|`(1 to 9).fold(z)_` | `{ val eta1 = 1 to 9; val eta2 = z; op => eta1.fold(eta2)(op) }` | +|`Some(1).fold(??? : Int)_` | `{ val eta1 = Some(1); val eta2 = () => ???; op => eta1.fold(eta2())(op) }` | + +Note that a space is necessary between a method name and the trailing underscore +because otherwise the underscore would be considered part of the name. + +## Type Applications + +```ebnf +SimpleExpr ::= SimpleExpr TypeArgs +``` + +A _type application_ `´e´[´T_1 , \ldots , T_n´]` instantiates +a polymorphic value ´e´ of type +`[´a_1´ >: ´L_1´ <: ´U_1, \ldots , a_n´ >: ´L_n´ <: ´U_n´]´S´` +with argument types +`´T_1 , \ldots , T_n´`. Every argument type ´T_i´ must obey +the corresponding bounds ´L_i´ and ´U_i´. That is, for each ´i = 1 +, \ldots , n´, we must have ´\sigma L_i <: T_i <: \sigma +U_i´, where ´\sigma´ is the substitution ´[a_1 := T_1 , \ldots , a_n +:= T_n]´. The type of the application is ´\sigma S´. + +If the function part ´e´ is of some value type, the type application +is taken to be equivalent to +`´e´.apply[´T_1 , \ldots ,´ T´_n´]`, i.e. the application of an `apply` method defined by +´e´. + +Type applications can be omitted if +[local type inference](#local-type-inference) can infer best type parameters +for a polymorphic method from the types of the actual method arguments +and the expected result type. + +## Tuples + +```ebnf +SimpleExpr ::= ‘(’ [Exprs] ‘)’ +``` + +A _tuple expression_ `(´e_1 , \ldots , e_n´)` is an alias +for the class instance creation +`scala.Tuple´n´(´e_1 , \ldots , e_n´)`, where ´n \geq 2´. +The empty tuple +`()` is the unique value of type `scala.Unit`. + +## Instance Creation Expressions + +```ebnf +SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody) +``` + +A _simple instance creation expression_ is of the form +`new ´c´` +where ´c´ is a [constructor invocation](05-classes-and-objects.html#constructor-invocations). Let ´T´ be +the type of ´c´. Then ´T´ must +denote a (a type instance of) a non-abstract subclass of +`scala.AnyRef`. Furthermore, the _concrete self type_ of the +expression must conform to the [self type](05-classes-and-objects.html#templates) of the class denoted by +´T´. The concrete self type is normally +´T´, except if the expression `new ´c´` appears as the +right hand side of a value definition + +```scala +val ´x´: ´S´ = new ´c´ +``` + +(where the type annotation `: ´S´` may be missing). +In the latter case, the concrete self type of the expression is the +compound type `´T´ with ´x´.type`. + +The expression is evaluated by creating a fresh +object of type ´T´ which is initialized by evaluating ´c´. The +type of the expression is ´T´. + +A _general instance creation expression_ is of the form +`new ´t´` for some [class template](05-classes-and-objects.html#templates) ´t´. +Such an expression is equivalent to the block + +```scala +{ class ´a´ extends ´t´; new ´a´ } +``` + +where ´a´ is a fresh name of an _anonymous class_ which is +inaccessible to user programs. + +There is also a shorthand form for creating values of structural +types: If `{´D´}` is a class body, then +`new {´D´}` is equivalent to the general instance creation expression +`new AnyRef{´D´}`. + +###### Example +Consider the following structural instance creation expression: + +```scala +new { def getName() = "aaron" } +``` + +This is a shorthand for the general instance creation expression + +```scala +new AnyRef{ def getName() = "aaron" } +``` + +The latter is in turn a shorthand for the block + +```scala +{ class anon$X extends AnyRef{ def getName() = "aaron" }; new anon$X } +``` + +where `anon$X` is some freshly created name. + +## Blocks + +```ebnf +BlockExpr ::= ‘{’ CaseClauses ‘}’ + | ‘{’ Block ‘}’ +Block ::= BlockStat {semi BlockStat} [ResultExpr] +``` + +A _block expression_ `{´s_1´; ´\ldots´; ´s_n´; ´e\,´}` is +constructed from a sequence of block statements ´s_1 , \ldots , s_n´ +and a final expression ´e´. The statement sequence may not contain +two definitions or declarations that bind the same name in the same +namespace. The final expression can be omitted, in which +case the unit value `()` is assumed. + +The expected type of the final expression ´e´ is the expected +type of the block. The expected type of all preceding statements is +undefined. + +The type of a block `´s_1´; ´\ldots´; ´s_n´; ´e´` is +`´T´ forSome {´\,Q\,´}`, where ´T´ is the type of ´e´ and ´Q´ +contains [existential clauses](03-types.html#existential-types) +for every value or type name which is free in ´T´ +and which is defined locally in one of the statements ´s_1 , \ldots , s_n´. +We say the existential clause _binds_ the occurrence of the value or type name. +Specifically, + +- A locally defined type definition `type´\;t = T´` + is bound by the existential clause `type´\;t >: T <: T´`. + It is an error if ´t´ carries type parameters. +- A locally defined value definition `val´\;x: T = e´` is + bound by the existential clause `val´\;x: T´`. +- A locally defined class definition `class´\;c´ extends´\;t´` + is bound by the existential clause `type´\;c <: T´` where + ´T´ is the least class type or refinement type which is a proper + supertype of the type ´c´. It is an error if ´c´ carries type parameters. +- A locally defined object definition `object´\;x\;´extends´\;t´` + is bound by the existential clause `val´\;x: T´` where + ´T´ is the least class type or refinement type which is a proper supertype of the type + `´x´.type`. + +Evaluation of the block entails evaluation of its +statement sequence, followed by an evaluation of the final expression +´e´, which defines the result of the block. + +A block expression `{´c_1´; ´\ldots´; ´c_n´}` where ´s_1 , \ldots , s_n´ are +case clauses forms a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions). + +###### Example +Assuming a class `Ref[T](x: T)`, the block + +```scala +{ class C extends B {´\ldots´} ; new Ref(new C) } +``` + +has the type `Ref[_1] forSome { type _1 <: B }`. +The block + +```scala +{ class C extends B {´\ldots´} ; new C } +``` + +simply has type `B`, because with the rules [here](03-types.html#simplification-rules) +the existentially quantified type +`_1 forSome { type _1 <: B }` can be simplified to `B`. + +## Prefix, Infix, and Postfix Operations + +```ebnf +PostfixExpr ::= InfixExpr [id [nl]] +InfixExpr ::= PrefixExpr + | InfixExpr id [nl] InfixExpr +PrefixExpr ::= [‘-’ | ‘+’ | ‘!’ | ‘~’] SimpleExpr +``` + +Expressions can be constructed from operands and operators. + +### Prefix Operations + +A prefix operation ´\mathit{op};e´ consists of a prefix operator ´\mathit{op}´, which +must be one of the identifiers ‘`+`’, ‘`-`’, ‘`!`’ or ‘`~`’, +which must not be enclosed in backquotes. +The expression ´\mathit{op};e´ is +equivalent to the postfix method application +`e.unary_´\mathit{op}´`. + + + +Prefix operators are different from normal method applications in +that their operand expression need not be atomic. For instance, the +input sequence `-sin(x)` is read as `-(sin(x))`, whereas the +method application `negate sin(x)` would be parsed as the +application of the infix operator `sin` to the operands +`negate` and `(x)`. + +### Postfix Operations + +A postfix operator can be an arbitrary identifier. The postfix +operation ´e;\mathit{op}´ is interpreted as ´e.\mathit{op}´. + +### Infix Operations + +An infix operator can be an arbitrary identifier. Infix operators have +precedence and associativity defined as follows: + +The _precedence_ of an infix operator is determined by the operator's first +character. Characters are listed below in increasing order of +precedence, with characters on the same line having the same precedence. + +```scala +(all letters, as defined in [chapter 1](01-lexical-syntax.html), including `_` and `$`) +| +^ +& += ! +< > +: ++ - +* / % +(other operator characters, as defined in [chapter 1](01-lexical-syntax.html), including Unicode categories `Sm` and `So`) +``` + +That is, operators starting with a letter have lowest precedence, +followed by operators starting with ‘`|`’, etc. + +There's one exception to this rule, which concerns +[_assignment operators_](#assignment-operators). +The precedence of an assignment operator is the same as the one +of simple assignment `(=)`. That is, it is lower than the +precedence of any other operator. + +The _associativity_ of an operator is determined by the operator's +last character. Operators ending in a colon ‘`:`’ are +right-associative. All other operators are left-associative. + +Precedence and associativity of operators determine the grouping of +parts of an expression as follows. + +- If there are several infix operations in an + expression, then operators with higher precedence bind more closely + than operators with lower precedence. +- If there are consecutive infix + operations ´e_0; \mathit{op}\_1; e_1; \mathit{op}\_2 \ldots \mathit{op}\_n; e_n´ + with operators ´\mathit{op}\_1 , \ldots , \mathit{op}\_n´ of the same precedence, + then all these operators must + have the same associativity. If all operators are left-associative, + the sequence is interpreted as + ´(\ldots(e_0;\mathit{op}\_1;e_1);\mathit{op}\_2\ldots);\mathit{op}\_n;e_n´. + Otherwise, if all operators are right-associative, the + sequence is interpreted as + ´e_0;\mathit{op}\_1;(e_1;\mathit{op}\_2;(\ldots \mathit{op}\_n;e_n)\ldots)´. +- Postfix operators always have lower precedence than infix + operators. E.g. ´e_1;\mathit{op}\_1;e_2;\mathit{op}\_2´ is always equivalent to + ´(e_1;\mathit{op}\_1;e_2);\mathit{op}\_2´. + +The right-hand operand of a left-associative operator may consist of +several arguments enclosed in parentheses, e.g. ´e;\mathit{op};(e_1,\ldots,e_n)´. +This expression is then interpreted as ´e.\mathit{op}(e_1,\ldots,e_n)´. + +A left-associative binary +operation ´e_1;\mathit{op};e_2´ is interpreted as ´e_1.\mathit{op}(e_2)´. If ´\mathit{op}´ is +right-associative and its parameter is passed by name, the same operation is interpreted as +´e_2.\mathit{op}(e_1)´. If ´\mathit{op}´ is right-associative and its parameter is passed by value, +it is interpreted as `{ val ´x´=´e_1´; ´e_2´.´\mathit{op}´(´x\,´) }`, where ´x´ is a fresh name. + +### Assignment Operators + +An _assignment operator_ is an operator symbol (syntax category +`op` in [Identifiers](01-lexical-syntax.html#identifiers)) that ends in an equals character +“`=`”, with the following exceptions: + +1. the operator also starts with an equals character, or +1. the operator is one of `(<=)`, `(>=)`, `(!=)`. + +Assignment operators are treated specially in that they +can be expanded to assignments if no other interpretation is valid. + +Let's consider an assignment operator such as `+=` in an infix +operation `´l´ += ´r´`, where ´l´, ´r´ are expressions. +This operation can be re-interpreted as an operation which corresponds +to the assignment + +```scala +´l´ = ´l´ + ´r´ +``` + +except that the operation's left-hand-side ´l´ is evaluated only once. + +The re-interpretation occurs if the following two conditions are fulfilled. + +1. The left-hand-side ´l´ does not have a member named + `+=`, and also cannot be converted by an + [implicit conversion](#implicit-conversions) + to a value with a member named `+=`. +1. The assignment `´l´ = ´l´ + ´r´` is type-correct. + In particular this implies that ´l´ refers to a variable or object + that can be assigned to, and that is convertible to a value with a member + named `+`. + +## Typed Expressions + +```ebnf +Expr1 ::= PostfixExpr ‘:’ CompoundType +``` + +The _typed expression_ ´e: T´ has type ´T´. The type of +expression ´e´ is expected to conform to ´T´. The result of +the expression is the value of ´e´ converted to type ´T´. + +###### Example +Here are examples of well-typed and ill-typed expressions. + +```scala +1: Int // legal, of type Int +1: Long // legal, of type Long +// 1: string // ***** illegal +``` + +## Annotated Expressions + +```ebnf +Expr1 ::= PostfixExpr ‘:’ Annotation {Annotation} +``` + +An _annotated expression_ `´e´: @´a_1´ ´\ldots´ @´a_n´` +attaches [annotations](11-annotations.html#user-defined-annotations) ´a_1 , \ldots , a_n´ to the +expression ´e´. + +## Assignments + +```ebnf +Expr1 ::= [SimpleExpr ‘.’] id ‘=’ Expr + | PrefixOperator SimpleExpr ‘=’ Expr + | SimpleExpr1 ArgumentExprs ‘=’ Expr +``` + +The interpretation of an assignment to a simple variable `´x´ = ´e´` +depends on the definition of ´x´. If ´x´ denotes a mutable +variable, then the assignment changes the current value of ´x´ to be +the result of evaluating the expression ´e´. The type of ´e´ is +expected to conform to the type of ´x´. If ´x´ is a parameterless +method defined in some template, and the same template contains a +setter method `´x´_=` as member, then the assignment +`´x´ = ´e´` is interpreted as the invocation +`´x´_=(´e\,´)` of that setter method. Analogously, an +assignment `´f.x´ = ´e´` to a parameterless method ´x´ +is interpreted as the invocation `´f.x´_=(´e\,´)`. +If ´x´ is an application of a unary operator, then the expression +is interpreted as though it were written as the explicit application +`´x´.unary_´\mathit{op}´`, namely, as `´x´.unary_´\mathit{op}´_=(´e\,´)`. + +An assignment `´f´(´\mathit{args}\,´) = ´e´` with a method application to the +left of the ‘`=`’ operator is interpreted as +`´f.´update(´\mathit{args}´, ´e\,´)`, i.e. +the invocation of an `update` method defined by ´f´. + +###### Example +Here are some assignment expressions and their equivalent expansions. + +| assignment | expansion | +|--------------------------|----------------------| +|`x.f = e` | `x.f_=(e)` | +|`x.f() = e` | `x.f.update(e)` | +|`x.f(i) = e` | `x.f.update(i, e)` | +|`x.f(i, j) = e` | `x.f.update(i, j, e)`| + +###### Example Imperative Matrix Multiplication + +Here is the usual imperative code for matrix multiplication. + +```scala +def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { + val zss: Array[Array[Double]] = new Array(xss.length, yss(0).length) + var i = 0 + while (i < xss.length) { + var j = 0 + while (j < yss(0).length) { + var acc = 0.0 + var k = 0 + while (k < yss.length) { + acc = acc + xss(i)(k) * yss(k)(j) + k += 1 + } + zss(i)(j) = acc + j += 1 + } + i += 1 + } + zss +} +``` + +Desugaring the array accesses and assignments yields the following +expanded version: + +```scala +def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { + val zss: Array[Array[Double]] = new Array(xss.length, yss.apply(0).length) + var i = 0 + while (i < xss.length) { + var j = 0 + while (j < yss.apply(0).length) { + var acc = 0.0 + var k = 0 + while (k < yss.length) { + acc = acc + xss.apply(i).apply(k) * yss.apply(k).apply(j) + k += 1 + } + zss.apply(i).update(j, acc) + j += 1 + } + i += 1 + } + zss +} +``` + +## Conditional Expressions + +```ebnf +Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] +``` + +The _conditional expression_ `if (´e_1´) ´e_2´ else ´e_3´` chooses +one of the values of ´e_2´ and ´e_3´, depending on the +value of ´e_1´. The condition ´e_1´ is expected to +conform to type `Boolean`. The then-part ´e_2´ and the +else-part ´e_3´ are both expected to conform to the expected +type of the conditional expression. The type of the conditional +expression is the [weak least upper bound](03-types.html#weak-conformance) +of the types of ´e_2´ and +´e_3´. A semicolon preceding the `else` symbol of a +conditional expression is ignored. + +The conditional expression is evaluated by evaluating first +´e_1´. If this evaluates to `true`, the result of +evaluating ´e_2´ is returned, otherwise the result of +evaluating ´e_3´ is returned. + +A short form of the conditional expression eliminates the +else-part. The conditional expression `if (´e_1´) ´e_2´` is +evaluated as if it was `if (´e_1´) ´e_2´ else ()`. + +## While Loop Expressions + +```ebnf +Expr1 ::= ‘while’ ‘(’ Expr ‘)’ {nl} Expr +``` + +The _while loop expression_ `while (´e_1´) ´e_2´` is typed and +evaluated as if it was an application of `whileLoop (´e_1´) (´e_2´)` where +the hypothetical method `whileLoop` is defined as follows. + +```scala +def whileLoop(cond: => Boolean)(body: => Unit): Unit = + if (cond) { body ; whileLoop(cond)(body) } else {} +``` + +## Do Loop Expressions + +```ebnf +Expr1 ::= ‘do’ Expr [semi] ‘while’ ‘(’ Expr ‘)’ +``` + +The _do loop expression_ `do ´e_1´ while (´e_2´)` is typed and +evaluated as if it was the expression `(´e_1´ ; while (´e_2´) ´e_1´)`. +A semicolon preceding the `while` symbol of a do loop expression is ignored. + +## For Comprehensions and For Loops + +```ebnf +Expr1 ::= ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) + {nl} [‘yield’] Expr +Enumerators ::= Generator {semi Generator} +Generator ::= [‘case’] Pattern1 ‘<-’ Expr {[semi] Guard | semi Pattern1 ‘=’ Expr} +Guard ::= ‘if’ PostfixExpr +``` + +A _for loop_ `for (´\mathit{enums}\,´) ´e´` executes expression ´e´ +for each binding generated by the enumerators ´\mathit{enums}´. +A _for comprehension_ `for (´\mathit{enums}\,´) yield ´e´` evaluates +expression ´e´ for each binding generated by the enumerators ´\mathit{enums}´ +and collects the results. An enumerator sequence always starts with a +generator; this can be followed by further generators, value +definitions, or guards. + +A _generator_ `´p´ <- ´e´` produces bindings from an expression ´e´ which is +matched in some way against pattern ´p´. Optionally, `case` can appear in front +of a generator pattern, this has no meaning in Scala 2 but will be [required in +Scala 3 if `p` is not +irrefutable](https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html). + +A _value definition_ `´p´ = ´e´` +binds the value name ´p´ (or several names in a pattern ´p´) to +the result of evaluating the expression ´e´. A _guard_ +`if ´e´` contains a boolean expression which restricts +enumerated bindings. The precise meaning of generators and guards is +defined by translation to invocations of four methods: `map`, +`withFilter`, `flatMap`, and `foreach`. These methods can +be implemented in different ways for different carrier types. + +The translation scheme is as follows. In a first step, every +generator `´p´ <- ´e´`, where ´p´ is not [irrefutable](08-pattern-matching.html#patterns) +for the type of ´e´ is replaced by + +```scala +´p´ <- ´e´.withFilter { case ´p´ => true; case _ => false } +``` + +Then, the following rules are applied repeatedly until all +comprehensions have been eliminated. + + - A for comprehension + `for (´p´ <- ´e\,´) yield ´e'´` + is translated to + `´e´.map { case ´p´ => ´e'´ }`. + - A for loop + `for (´p´ <- ´e\,´) ´e'´` + is translated to + `´e´.foreach { case ´p´ => ´e'´ }`. + - A for comprehension + + ```scala + for (´p´ <- ´e´; ´p'´ <- ´e'; \ldots´) yield ´e''´ + ``` + + where `´\ldots´` is a (possibly empty) + sequence of generators, definitions, or guards, + is translated to + + ```scala + ´e´.flatMap { case ´p´ => for (´p'´ <- ´e'; \ldots´) yield ´e''´ } + ``` + + - A for loop + + ```scala + for (´p´ <- ´e´; ´p'´ <- ´e'; \ldots´) ´e''´ + ``` + + where `´\ldots´` is a (possibly empty) + sequence of generators, definitions, or guards, + is translated to + + ```scala + ´e´.foreach { case ´p´ => for (´p'´ <- ´e'; \ldots´) ´e''´ } + ``` + + - A generator `´p´ <- ´e´` followed by a guard + `if ´g´` is translated to a single generator + `´p´ <- ´e´.withFilter((´x_1 , \ldots , x_n´) => ´g\,´)` where + ´x_1 , \ldots , x_n´ are the free variables of ´p´. + + - A generator `´p´ <- ´e´` followed by a value definition + `´p'´ = ´e'´` is translated to the following generator of pairs of values, where + ´x´ and ´x'´ are fresh names: + + ```scala + (´p´, ´p'´) <- for (´x @ p´ <- ´e´) yield { val ´x' @ p'´ = ´e'´; (´x´, ´x'´) } + ``` + +###### Example +The following code produces all pairs of numbers between ´1´ and ´n-1´ +whose sums are prime. + +```scala +for { i <- 1 until n + j <- 1 until i + if isPrime(i+j) +} yield (i, j) +``` + +The for comprehension is translated to: + +```scala +(1 until n) + .flatMap { + case i => (1 until i) + .withFilter { j => isPrime(i+j) } + .map { case j => (i, j) } } +``` + +###### Example +For comprehensions can be used to express vector +and matrix algorithms concisely. +For instance, here is a method to compute the transpose of a given matrix: + + + +```scala +def transpose[A](xss: Array[Array[A]]) = { + for (i <- Array.range(0, xss(0).length)) yield + for (xs <- xss) yield xs(i) +} +``` + +Here is a method to compute the scalar product of two vectors: + +```scala +def scalprod(xs: Array[Double], ys: Array[Double]) = { + var acc = 0.0 + for ((x, y) <- xs zip ys) acc = acc + x * y + acc +} +``` + +Finally, here is a method to compute the product of two matrices. +Compare with the [imperative version](#example-imperative-matrix-multiplication). + +```scala +def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { + val ysst = transpose(yss) + for (xs <- xss) yield + for (yst <- ysst) yield + scalprod(xs, yst) +} +``` + +The code above makes use of the fact that `map`, `flatMap`, +`withFilter`, and `foreach` are defined for instances of class +`scala.Array`. + +## Return Expressions + +```ebnf +Expr1 ::= ‘return’ [Expr] +``` + +A _return expression_ `return ´e´` must occur inside the body of some +enclosing user defined method. The innermost enclosing method in a +source program, ´m´, must have an explicitly declared result type, and +the type of ´e´ must conform to it. + +The return expression evaluates the expression ´e´ and returns its +value as the result of ´m´. The evaluation of any statements or +expressions following the return expression is omitted. The type of +a return expression is `scala.Nothing`. + +The expression ´e´ may be omitted. The return expression +`return` is type-checked and evaluated as if it were `return ()`. + +Returning from the method from within a nested function may be +implemented by throwing and catching a +`scala.runtime.NonLocalReturnControl`. Any exception catches +between the point of return and the enclosing methods might see +and catch that exception. A key comparison makes sure that this +exception is only caught by the method instance which is terminated +by the return. + +If the return expression is itself part of an anonymous function, it +is possible that the enclosing method ´m´ has already returned +before the return expression is executed. In that case, the thrown +`scala.runtime.NonLocalReturnControl` will not be caught, and will +propagate up the call stack. + +## Throw Expressions + +```ebnf +Expr1 ::= ‘throw’ Expr +``` + +A _throw expression_ `throw ´e´` evaluates the expression +´e´. The type of this expression must conform to +`Throwable`. If ´e´ evaluates to an exception +reference, evaluation is aborted with the thrown exception. If ´e´ +evaluates to `null`, evaluation is instead aborted with a +`NullPointerException`. If there is an active +[`try` expression](#try-expressions) which handles the thrown +exception, evaluation resumes with the handler; otherwise the thread +executing the `throw` is aborted. The type of a throw expression +is `scala.Nothing`. + +## Try Expressions + +```ebnf +Expr1 ::= ‘try’ Expr [‘catch’ Expr] [‘finally’ Expr] +``` + +A _try expression_ is of the form `try { ´b´ } catch ´h´` +where the handler ´h´ is usually a +[pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions) + +```scala +{ case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ } +``` + +This expression is evaluated by evaluating the block +´b´. If evaluation of ´b´ does not cause an exception to be +thrown, the result of ´b´ is returned. Otherwise the +handler ´h´ is applied to the thrown exception. +If the handler contains a case matching the thrown exception, +the first such case is invoked. If the handler contains +no case matching the thrown exception, the exception is +re-thrown. More generally, if the handler is a `PartialFunction`, +it is applied only if it is defined at the given exception. + +Let ´\mathit{pt}´ be the expected type of the try expression. The block +´b´ is expected to conform to ´\mathit{pt}´. The handler ´h´ +is expected conform to type `scala.Function[scala.Throwable, ´\mathit{pt}\,´]`. +The type of the try expression is the [weak least upper bound](03-types.html#weak-conformance) +of the type of ´b´ and the result type of ´h´. + +A try expression `try { ´b´ } finally ´e´` evaluates the block +´b´. If evaluation of ´b´ does not cause an exception to be +thrown, the expression ´e´ is evaluated. If an exception is thrown +during evaluation of ´e´, the evaluation of the try expression is +aborted with the thrown exception. If no exception is thrown during +evaluation of ´e´, the result of ´b´ is returned as the +result of the try expression. + +If an exception is thrown during evaluation of ´b´, the finally block +´e´ is also evaluated. If another exception ´e´ is thrown +during evaluation of ´e´, evaluation of the try expression is +aborted with the thrown exception. If no exception is thrown during +evaluation of ´e´, the original exception thrown in ´b´ is +re-thrown once evaluation of ´e´ has completed. The block +´b´ is expected to conform to the expected type of the try +expression. The finally expression ´e´ is expected to conform to +type `Unit`. + +A try expression `try { ´b´ } catch ´e_1´ finally ´e_2´` +is a shorthand +for `try { try { ´b´ } catch ´e_1´ } finally ´e_2´`. + +## Anonymous Functions + +```ebnf +Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr +ResultExpr ::= (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block +Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’ +Binding ::= (id | ‘_’) [‘:’ Type] +``` + +The anonymous function of arity ´n´, `(´x_1´: ´T_1 , \ldots , x_n´: ´T_n´) => e` maps parameters ´x_i´ of types ´T_i´ to a result given by expression ´e´. The scope of each formal parameter ´x_i´ is ´e´. Formal parameters must have pairwise distinct names. + +In the case of a single untyped formal parameter, `(´x\,´) => ´e´` can be abbreviated to `´x´ => ´e´`. If an anonymous function `(´x´: ´T\,´) => ´e´` with a single typed parameter appears as the result expression of a block, it can be abbreviated to `´x´: ´T´ => e`. + +A formal parameter may also be a wildcard represented by an underscore `_`. 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-implicits.html#implicit-parameters-and-views); however the parameter section itself does not count as an [implicit parameter section](07-implicits.html#implicit-parameters). Hence, arguments to anonymous functions always have to be given explicitly. + +### Translation +If the expected type of the anonymous function is of the shape `scala.Function´n´[´S_1 , \ldots , S_n´, ´R\,´]`, or can be [SAM-converted](#sam-conversion) to such a function type, the type `´T_i´` of a parameter `´x_i´` can be omitted, as far as `´S_i´` is defined in the expected type, and `´T_i´ = ´S_i´` is assumed. Furthermore, the expected type when type checking ´e´ is ´R´. + +If there is no expected type for the function literal, all formal parameter types `´T_i´` must be specified explicitly, and the expected type of ´e´ is undefined. The type of the anonymous function is `scala.Function´n´[´T_1 , \ldots , T_n´, ´R\,´]`, where ´R´ is the [packed type](#expression-typing) of ´e´. ´R´ must be equivalent to a type which does not refer to any of the formal parameters ´x_i´. + +The eventual run-time value of an anonymous function is determined by the expected type: + - a subclass of one of the builtin function types, `scala.Function´n´[´S_1 , \ldots , S_n´, ´R\,´]` (with ´S_i´ and ´R´ fully defined), + - a [single-abstract-method (SAM) type](#sam-conversion); + - `PartialFunction[´T´, ´U´]` + - some other type. + +The standard anonymous function evaluates in the same way as the following instance creation expression: + +```scala +new scala.Function´n´[´T_1 , \ldots , T_n´, ´T´] { + def apply(´x_1´: ´T_1 , \ldots , x_n´: ´T_n´): ´T´ = ´e´ +} +``` + +The same evaluation holds for a SAM type, except that the instantiated type is given by the SAM type, and the implemented method is the single abstract method member of this type. + +The underlying platform may provide more efficient ways of constructing these instances, such as Java 8's `invokedynamic` bytecode and `LambdaMetaFactory` class. + +When a `PartialFunction` is required, an additional member `isDefinedAt` +is synthesized, which simply returns `true`. +However, if the function literal has the shape `x => x match { $\ldots$ }`, +then `isDefinedAt` is derived from the pattern match in the following way: +each case from the match expression evaluates to `true`, +and if there is no default case, +a default case is added that evaluates to `false`. +For more details on how that is implemented see +["Pattern Matching Anonymous Functions"](08-pattern-matching.html#pattern-matching-anonymous-functions). + +###### Example +Examples of anonymous functions: + +```scala +x => x // The identity function + +f => g => x => f(g(x)) // Curried function composition + +(x: Int,y: Int) => x + y // A summation function + +() => { count += 1; count } // The function which takes an + // empty parameter list ´()´, + // increments a non-local variable + // `count' and returns the new value. + +_ => 5 // The function that ignores its argument + // and always returns 5. +``` + +### Placeholder Syntax for Anonymous Functions + +```ebnf +SimpleExpr1 ::= ‘_’ +``` + +An expression (of syntactic category `Expr`) +may contain embedded underscore symbols `_` at places where identifiers +are legal. Such an expression represents an anonymous function where subsequent +occurrences of underscores denote successive parameters. + +Define an _underscore section_ to be an expression of the form +`_:´T´` where ´T´ is a type, or else of the form `_`, +provided the underscore does not appear as the expression part of a +type ascription `_:´T´`. + +An expression ´e´ of syntactic category `Expr` _binds_ an underscore section +´u´, if the following two conditions hold: (1) ´e´ properly contains ´u´, and +(2) there is no other expression of syntactic category `Expr` +which is properly contained in ´e´ and which itself properly contains ´u´. + +If an expression ´e´ binds underscore sections ´u_1 , \ldots , u_n´, in this order, it is equivalent to +the anonymous function `(´u'_1´, ... ´u'_n´) => ´e'´` +where each ´u_i'´ results from ´u_i´ by replacing the underscore with a fresh identifier and +´e'´ results from ´e´ by replacing each underscore section ´u_i´ by ´u_i'´. + +###### Example +The anonymous functions in the left column use placeholder +syntax. Each of these is equivalent to the anonymous function on its right. + +| | | +|---------------------------|----------------------------| +|`_ + 1` | `x => x + 1` | +|`_ * _` | `(x1, x2) => x1 * x2` | +|`(_: Int) * 2` | `(x: Int) => (x: Int) * 2` | +|`if (_) x else y` | `z => if (z) x else y` | +|`_.map(f)` | `x => x.map(f)` | +|`_.map(_ + 1)` | `x => x.map(y => y + 1)` | + +## Constant Expressions + +Constant expressions are expressions that the Scala compiler can evaluate to a constant. +The definition of "constant expression" depends on the platform, but they +include at least the expressions of the following forms: + +- A literal of a value class, such as an integer +- A string literal +- A class constructed with [`Predef.classOf`](12-the-scala-standard-library.html#the-predef-object) +- An element of an enumeration from the underlying platform +- A literal array, of the form `Array´(c_1 , \ldots , c_n)´`, + where all of the ´c_i´'s are themselves constant expressions +- An identifier defined by a [constant value definition](04-basic-declarations-and-definitions.html#value-declarations-and-definitions). + +## Statements + +```ebnf +BlockStat ::= Import + | {Annotation} [‘implicit’] [‘lazy’] Def + | {Annotation} {LocalModifier} TmplDef + | Expr1 + | +TemplateStat ::= Import + | {Annotation} {Modifier} Def + | {Annotation} {Modifier} Dcl + | Expr + | +``` + +Statements occur as parts of blocks and templates. A _statement_ can be +an import, a definition or an expression, or it can be empty. +Statements used in the template of a class definition can also be +declarations. An expression that is used as a statement can have an +arbitrary value type. An expression statement ´e´ is evaluated by +evaluating ´e´ and discarding the result of the evaluation. + + + +Block statements may be definitions which bind local names in the +block. The only modifier allowed in all block-local definitions is +`implicit`. When prefixing a class or object definition, +modifiers `abstract`, `final`, and `sealed` are also +permitted. + +Evaluation of a statement sequence entails evaluation of the +statements in the order they are written. + +## Implicit Conversions + +Implicit conversions can be applied to expressions whose type does not +match their expected type, to qualifiers in selections, and to unapplied methods. The +available implicit conversions are given in the next two sub-sections. + +### Value Conversions + +The following seven implicit conversions can be applied to an +expression ´e´ which has some value type ´T´ and which is type-checked with +some expected type ´\mathit{pt}´. + +###### Static Overloading Resolution +If an expression denotes several possible members of a class, +[overloading resolution](#overloading-resolution) +is applied to pick a unique member. + +###### Type Instantiation +An expression ´e´ of polymorphic type + +```scala +[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´ +``` + +which does not appear as the function part of +a type application is converted to a type instance of ´T´ +by determining with [local type inference](#local-type-inference) +instance types `´T_1 , \ldots , T_n´` +for the type variables `´a_1 , \ldots , a_n´` and +implicitly embedding ´e´ in the [type application](#type-applications) +`´e´[´T_1 , \ldots , T_n´]`. + +###### Numeric Widening +If ´e´ has a primitive number type which [weakly conforms](03-types.html#weak-conformance) +to the expected type, it is widened to +the expected type using one of the numeric conversion methods +`toShort`, `toChar`, `toInt`, `toLong`, +`toFloat`, `toDouble` defined [in the standard library](12-the-scala-standard-library.html#numeric-value-types). + +Since conversions from `Int` to `Float` and from `Long` to `Float` or `Double` +may incur a loss of precision, those implicit conversions are deprecated. +The conversion is permitted for literals if the original value can be recovered, +that is, if conversion back to the original type produces the original value. + +###### Numeric Literal Narrowing +If the expected type is `Byte`, `Short` or `Char`, and +the expression ´e´ is an integer literal fitting in the range of that +type, it is converted to the same literal in that type. + +###### Value Discarding +If ´e´ has some value type and the expected type is `Unit`, +´e´ is converted to the expected type by embedding it in the +term `{ ´e´; () }`. + +###### SAM conversion +An expression `(p1, ..., pN) => body` of function type `(T1, ..., TN) => T` is sam-convertible to the expected type `S` if the following holds: + - the class `C` of `S` declares an abstract method `m` with signature `(p1: A1, ..., pN: AN): R`; + - besides `m`, `C` must not declare or inherit any other deferred value members; + - the method `m` must have a single argument list; + - there must be a type `U` that is a subtype of `S`, so that the expression + `new U { final def m(p1: A1, ..., pN: AN): R = body }` is well-typed (conforming to the expected type `S`); + - for the purpose of scoping, `m` should be considered a static member (`U`'s members are not in scope in `body`); + - `(A1, ..., AN) => R` is a subtype of `(T1, ..., TN) => T` (satisfying this condition drives type inference of unknown type parameters in `S`); + +Note that a function literal that targets a SAM is not necessarily compiled to the above instance creation expression. This is platform-dependent. + +It follows that: + - if class `C` defines a constructor, it must be accessible and must define exactly one, empty, argument list; + - class `C` cannot be `final` or `sealed` (for simplicity we ignore the possibility of SAM conversion in the same compilation unit as the sealed class); + - `m` cannot be polymorphic; + - it must be possible to derive a fully-defined type `U` from `S` by inferring any unknown type parameters of `C`. + +Finally, we impose some implementation restrictions (these may be lifted in future releases): + - `C` must not be nested or local (it must not capture its environment, as that results in a nonzero-argument constructor) + - `C`'s constructor must not have an implicit argument list (this simplifies type inference); + - `C` must not declare a self type (this simplifies type inference); + - `C` must not be `@specialized`. + +###### 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-implicits.html#views). + +###### Selection on `Dynamic` +If none of the previous conversions applies, and ´e´ is a prefix +of a selection ´e.x´, and ´e´'s type conforms to class `scala.Dynamic`, +then the selection is rewritten according to the rules for +[dynamic member selection](#dynamic-member-selection). + +### Method Conversions + +The following four implicit conversions can be applied to methods +which are not applied to some argument list. + +###### Evaluation +A parameterless method ´m´ of type `=> ´T´` is always converted to +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-implicits.html#implicit-parameters). + +###### Eta Expansion +Otherwise, if the method is not a constructor, +and the expected type ´\mathit{pt}´ is a function type, or, +for methods of non-zero arity, a type [sam-convertible](#sam-conversion) to a function type, +´(\mathit{Ts}') \Rightarrow T'´, [eta-expansion](#eta-expansion-section) +is performed on the expression ´e´. + +(The exception for zero-arity methods is to avoid surprises due to unexpected sam conversion.) + +###### Empty Application +Otherwise, if ´e´ has method type ´()T´, it is implicitly applied to the empty +argument list, yielding ´e()´. + +### Overloading Resolution + +If an identifier or selection ´e´ references several members of a +class, the context of the reference is used to identify a unique +member. The way this is done depends on whether or not ´e´ is used as +a function. Let ´\mathscr{A}´ be the set of members referenced by ´e´. + +Assume first that ´e´ appears as a function in an application, as in +`´e´(´e_1 , \ldots , e_m´)`. + +One first determines the set of functions that is potentially [applicable](#function-applications) +based on the _shape_ of the arguments. + +The *shape* of an argument expression ´e´, written ´\mathit{shape}(e)´, is +a type that is defined as follows: + - For a function expression `(´p_1´: ´T_1 , \ldots , p_n´: ´T_n´) => ´b´: (Any ´, \ldots ,´ Any) => ´\mathit{shape}(b)´`, + where `Any` occurs ´n´ times in the argument type. + - For a pattern-matching anonymous function definition `{ case ... }`: `PartialFunction[Any, Nothing]`. + - For a named argument `´n´ = ´e´`: ´\mathit{shape}(e)´. + - For all other expressions: `Nothing`. + +Let ´\mathscr{B}´ be the set of alternatives in ´\mathscr{A}´ that are [_applicable_](#function-applications) +to expressions ´(e_1 , \ldots , e_n)´ of types ´(\mathit{shape}(e_1) , \ldots , \mathit{shape}(e_n))´. +If there is precisely one alternative in ´\mathscr{B}´, that alternative is chosen. + +Otherwise, let ´S_1 , \ldots , S_m´ be the list of types obtained by typing each argument as follows. + +Normally, an argument is typed without an expected type, except when +all alternatives explicitly specify the same parameter type for this argument (a missing parameter type, +due to e.g. arity differences, is taken as `NoType`, thus resorting to no expected type), +or when trying to propagate more type information to aid inference of higher-order function parameter types, as explained next. + +The intuition for higher-order function parameter type inference is that all arguments must be of a function-like type +(`PartialFunction`, `FunctionN` or some equivalent [SAM type](#sam-conversion)), +which in turn must define the same set of higher-order argument types, so that they can safely be used as +the expected type of a given argument of the overloaded method, without unduly ruling out any alternatives. +The intent is not to steer overloading resolution, but to preserve enough type information to steer type +inference of the arguments (a function literal or eta-expanded method) to this overloaded method. + +Note that the expected type drives eta-expansion (not performed unless a function-like type is expected), +as well as inference of omitted parameter types of function literals. + +More precisely, an argument `´e_i´` is typed with an expected type that is derived from the `´i´`th argument +type found in each alternative (call these `´T_{ij}´` for alternative `´j´` and argument position `´i´`) when +all `´T_{ij}´` are function types `´(A_{1j},..., A_{nj}) => ?´` (or the equivalent `PartialFunction`, or SAM) +of some arity `´n´`, and their argument types `´A_{kj}´` are identical across all overloads `´j´` for a +given `´k´`. Then, the expected type for `´e_i´` is derived as follows: + - we use `´PartialFunction[A_{1j},..., A_{nj}, ?]´` if for some overload `´j´`, `´T_{ij}´`'s type symbol is `PartialFunction`; + - else, if for some `´j´`, `´T_{ij}´` is `FunctionN`, the expected type is `´FunctionN[A_{1j},..., A_{nj}, ?]´`; + - else, if for all `´j´`, `´T_{ij}´` is a SAM type of the same class, defining argument types `´A_{1j},..., A_{nj}´` + (and a potentially varying result type), the expected type encodes these argument types and the SAM class. + +For every member ´m´ in ´\mathscr{B}´ one determines whether it is applicable +to expressions (´e_1 , \ldots , e_m´) of types ´S_1, \ldots , S_m´. + +It is an error if none of the members in ´\mathscr{B}´ is applicable. If there is one +single applicable alternative, that alternative is chosen. Otherwise, let ´\mathscr{CC}´ +be the set of applicable alternatives which don't employ any default argument +in the application to ´e_1 , \ldots , e_m´. + +It is again an error if ´\mathscr{CC}´ is empty. +Otherwise, one chooses the _most specific_ alternative among the alternatives +in ´\mathscr{CC}´, according to the following definition of being "as specific as", and +"more specific than": + + + +- A parameterized method ´m´ of type `(´p_1:T_1, \ldots , p_n:T_n´)´U´` is + _as specific as_ some other member ´m'´ of type ´S´ if ´m'´ is [applicable](#function-applications) + to arguments `(´p_1 , \ldots , p_n´)` of types ´T_1 , \ldots , T_n´. +- A polymorphic method of type `[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´` is + as specific as some other member of type ´S´ if ´T´ is as specific as ´S´ + under the assumption that for ´i = 1 , \ldots , n´ each ´a_i´ is an abstract type name + bounded from below by ´L_i´ and from above by ´U_i´. +- A member of any other type is always as specific as a parameterized method or a polymorphic method. +- Given two members of types ´T´ and ´U´ which are neither parameterized nor polymorphic method types, + the member of type ´T´ is as specific as the member of type ´U´ if + the existential dual of ´T´ conforms to the existential dual of ´U´. + Here, the existential dual of a polymorphic type + `[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´` is + `´T´ forSome { type ´a_1´ >: ´L_1´ <: ´U_1´ ´, \ldots ,´ type ´a_n´ >: ´L_n´ <: ´U_n´}`. + The existential dual of every other type is the type itself. + +The _relative weight_ of an alternative ´A´ over an alternative ´B´ is a +number from 0 to 2, defined as the sum of + +- 1 if ´A´ is as specific as ´B´, 0 otherwise, and +- 1 if ´A´ is defined in a class or object which is derived from the class or object defining ´B´, 0 otherwise. + +A class or object ´C´ is _derived_ from a class or object ´D´ if one of +the following holds: + +- ´C´ is a subclass of ´D´, or +- ´C´ is a companion object of a class derived from ´D´, or +- ´D´ is a companion object of a class from which ´C´ is derived. + +An alternative ´A´ is _more specific_ than an alternative ´B´ if +the relative weight of ´A´ over ´B´ is greater than the relative +weight of ´B´ over ´A´. + +It is an error if there is no alternative in ´\mathscr{CC}´ which is more +specific than all other alternatives in ´\mathscr{CC}´. + +Assume next that ´e´ appears as a function in a type application, as +in `´e´[´\mathit{targs}\,´]`. Then all alternatives in +´\mathscr{A}´ which take the same number of type parameters as there are type +arguments in ´\mathit{targs}´ are chosen. It is an error if no such alternative exists. +If there are several such alternatives, overloading resolution is +applied again to the whole expression `´e´[´\mathit{targs}\,´]`. + +Assume finally that ´e´ does not appear as a function in either an application or a type application. +If an expected type is given, let ´\mathscr{B}´ be the set of those alternatives +in ´\mathscr{A}´ which are [compatible](03-types.html#compatibility) to it. +Otherwise, let ´\mathscr{B}´ be the same as ´\mathscr{A}´. +In this last case we choose the most specific alternative among all alternatives in ´\mathscr{B}´. +It is an error if there is no alternative in ´\mathscr{B}´ which is +more specific than all other alternatives in ´\mathscr{B}´. + +###### Example +Consider the following definitions: + +```scala +class A extends B {} +def f(x: B, y: B) = ´\ldots´ +def f(x: A, y: B) = ´\ldots´ +val a: A +val b: B +``` + +Then the application `f(b, b)` refers to the first +definition of ´f´ whereas the application `f(a, a)` +refers to the second. Assume now we add a third overloaded definition + +```scala +def f(x: B, y: A) = ´\ldots´ +``` + +Then the application `f(a, a)` is rejected for being ambiguous, since +no most specific applicable signature exists. + +### Local Type Inference + +Local type inference infers type arguments to be passed to expressions +of polymorphic type. Say ´e´ is of type [´a_1´ >: ´L_1´ <: ´U_1, \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´ +and no explicit type parameters are given. + +Local type inference converts this expression to a type +application `´e´[´T_1 , \ldots , T_n´]`. The choice of the +type arguments ´T_1 , \ldots , T_n´ depends on the context in which +the expression appears and on the expected type ´\mathit{pt}´. +There are three cases. + +###### Case 1: Selections +If the expression appears as the prefix of a selection with a name +´x´, then type inference is _deferred_ to the whole expression +´e.x´. That is, if ´e.x´ has type ´S´, it is now treated as having +type [´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´S´, +and local type inference is applied in turn to infer type arguments +for ´a_1 , \ldots , a_n´, using the context in which ´e.x´ appears. + +###### Case 2: Values +If the expression ´e´ appears as a value without being applied to +value arguments, the type arguments are inferred by solving a +constraint system which relates the expression's type ´T´ with the +expected type ´\mathit{pt}´. Without loss of generality we can assume that +´T´ is a value type; if it is a method type we apply +[eta-expansion](#eta-expansion-section) to convert it to a function type. Solving +means finding a substitution ´\sigma´ of types ´T_i´ for the type +parameters ´a_i´ such that + +- None of the inferred types ´T_i´ is a [singleton type](03-types.html#singleton-types) + unless it is a singleton type corresponding to an object or a constant value + definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. +- All type parameter bounds are respected, i.e. + ´\sigma L_i <: \sigma a_i´ and ´\sigma a_i <: \sigma U_i´ for ´i = 1 , \ldots , n´. +- The expression's type conforms to the expected type, i.e. + ´\sigma T <: \sigma \mathit{pt}´. + +It is a compile time error if no such substitution exists. +If several substitutions exist, local-type inference will choose for +each type variable ´a_i´ a minimal or maximal type ´T_i´ of the +solution space. A _maximal_ type ´T_i´ will be chosen if the type +parameter ´a_i´ appears [contravariantly](04-basic-declarations-and-definitions.html#variance-annotations) in the +type ´T´ of the expression. A _minimal_ type ´T_i´ will be chosen +in all other situations, i.e. if the variable appears covariantly, +non-variantly or not at all in the type ´T´. We call such a substitution +an _optimal solution_ of the given constraint system for the type ´T´. + +###### Case 3: Methods +The last case applies if the expression +´e´ appears in an application ´e(d_1 , \ldots , d_m)´. In that case +´T´ is a method type ´(p_1:R_1 , \ldots , p_m:R_m)T'´. Without loss of +generality we can assume that the result type ´T'´ is a value type; if +it is a method type we apply [eta-expansion](#eta-expansion-section) to +convert it to a function type. One computes first the types ´S_j´ of +the argument expressions ´d_j´, using two alternative schemes. Each +argument expression ´d_j´ is typed first with the expected type ´R_j´, +in which the type parameters ´a_1 , \ldots , a_n´ are taken as type +constants. If this fails, the argument ´d_j´ is typed instead with an +expected type ´R_j'´ which results from ´R_j´ by replacing every type +parameter in ´a_1 , \ldots , a_n´ with _undefined_. + +In a second step, type arguments are inferred by solving a constraint +system which relates the method's type with the expected type +´\mathit{pt}´ and the argument types ´S_1 , \ldots , S_m´. Solving the +constraint system means +finding a substitution ´\sigma´ of types ´T_i´ for the type parameters +´a_i´ such that + +- None of the inferred types ´T_i´ is a [singleton type](03-types.html#singleton-types) + unless it is a singleton type corresponding to an object or a constant value + definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. +- All type parameter bounds are respected, i.e. ´\sigma L_i <: \sigma a_i´ and + ´\sigma a_i <: \sigma U_i´ for ´i = 1 , \ldots , n´. +- The method's result type ´T'´ conforms to the expected type, i.e. ´\sigma T' <: \sigma \mathit{pt}´. +- Each argument type [weakly conforms](03-types.html#weak-conformance) + to the corresponding formal parameter + type, i.e. ´\sigma S_j <:_w \sigma R_j´ for ´j = 1 , \ldots , m´. + +It is a compile time error if no such substitution exists. If several +solutions exist, an optimal one for the type ´T'´ is chosen. + +All or parts of an expected type ´\mathit{pt}´ may be undefined. The rules for +[conformance](03-types.html#conformance) are extended to this case by adding +the rule that for any type ´T´ the following two statements are always +true: ´\mathit{undefined} <: T´ and ´T <: \mathit{undefined}´ + +It is possible that no minimal or maximal solution for a type variable +exists, in which case a compile-time error results. Because ´<:´ is a +pre-order, it is also possible that a solution set has several optimal +solutions for a type. In that case, a Scala compiler is free to pick +any one of them. + +###### Example +Consider the two methods: + +```scala +def cons[A](x: A, xs: List[A]): List[A] = x :: xs +def nil[B]: List[B] = Nil +``` + +and the definition + +```scala +val xs = cons(1, nil) +``` + +The application of `cons` is typed with an undefined expected +type. This application is completed by local type inference to +`cons[Int](1, nil)`. +Here, one uses the following +reasoning to infer the type argument `Int` for the type +parameter `a`: + +First, the argument expressions are typed. The first argument `1` +has type `Int` whereas the second argument `nil` is +itself polymorphic. One tries to type-check `nil` with an +expected type `List[a]`. This leads to the constraint system + +```scala +List[b?] <: List[a] +``` + +where we have labeled `b?` with a question mark to indicate +that it is a variable in the constraint system. +Because class `List` is covariant, the optimal +solution of this constraint is + +```scala +b = scala.Nothing +``` + +In a second step, one solves the following constraint system for +the type parameter `a` of `cons`: + +```scala +Int <: a? +List[scala.Nothing] <: List[a?] +List[a?] <: ´\mathit{undefined}´ +``` + +The optimal solution of this constraint system is + +```scala +a = Int +``` + +so `Int` is the type inferred for `a`. + +###### Example + +Consider now the definition + +```scala +val ys = cons("abc", xs) +``` + +where `xs` is defined of type `List[Int]` as before. +In this case local type inference proceeds as follows. + +First, the argument expressions are typed. The first argument +`"abc"` has type `String`. The second argument `xs` is +first tried to be typed with expected type `List[a]`. This fails, +as `List[Int]` is not a subtype of `List[a]`. Therefore, +the second strategy is tried; `xs` is now typed with expected type +`List[´\mathit{undefined}´]`. This succeeds and yields the argument type +`List[Int]`. + +In a second step, one solves the following constraint system for +the type parameter `a` of `cons`: + +```scala +String <: a? +List[Int] <: List[a?] +List[a?] <: ´\mathit{undefined}´ +``` + +The optimal solution of this constraint system is + +```scala +a = scala.Any +``` + +so `scala.Any` is the type inferred for `a`. + +### Eta Expansion + +_Eta-expansion_ converts an expression of method type to an +equivalent expression of function type. It proceeds in two steps. + +First, one identifies the maximal sub-expressions of ´e´; let's +say these are ´e_1 , \ldots , e_m´. For each of these, one creates a +fresh name ´x_i´. Let ´e'´ be the expression resulting from +replacing every maximal subexpression ´e_i´ in ´e´ by the +corresponding fresh name ´x_i´. Second, one creates a fresh name ´y_i´ +for every argument type ´T_i´ of the method (´i = 1 , \ldots , +n´). The result of eta-conversion is then: + +```scala +{ val ´x_1´ = ´e_1´; + ´\ldots´ + val ´x_m´ = ´e_m´; + (´y_1: T_1 , \ldots , y_n: T_n´) => ´e'´(´y_1 , \ldots , y_n´) +} +``` + +The behavior of [call-by-name parameters](#function-applications) +is preserved under eta-expansion: the corresponding actual argument expression, +a sub-expression of parameterless method type, is not evaluated in the expanded block. + +### Dynamic Member Selection + +The standard Scala library defines a marker trait `scala.Dynamic`. Subclasses of this trait are able to intercept selections and applications on their instances by defining methods of the names `applyDynamic`, `applyDynamicNamed`, `selectDynamic`, and `updateDynamic`. + +The following rewrites are performed, assuming ´e´'s type conforms to `scala.Dynamic`, and the original expression does not type check under the normal rules, as specified fully in the relevant subsection of [implicit conversion](#dynamic-member-selection): + + * `e.m[Ti](xi)` becomes `e.applyDynamic[Ti]("m")(xi)` + * `e.m[Ti]` becomes `e.selectDynamic[Ti]("m")` + * `e.m = x` becomes `e.updateDynamic("m")(x)` + +If any arguments are named in the application (one of the `xi` is of the shape `arg = x`), their name is preserved as the first component of the pair passed to `applyDynamicNamed` (for missing names, `""` is used): + + * `e.m[Ti](argi = xi)` becomes `e.applyDynamicNamed[Ti]("m")(("argi", xi))` + +Finally: + + * `e.m(x) = y` becomes `e.selectDynamic("m").update(x, y)` + +None of these methods are actually defined in the `scala.Dynamic`, so that users are free to define them with or without type parameters, or implicit arguments. diff --git a/docs/_spec/07-implicits.md b/docs/_spec/07-implicits.md new file mode 100644 index 000000000000..6f38fdd48074 --- /dev/null +++ b/docs/_spec/07-implicits.md @@ -0,0 +1,525 @@ +--- +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. To be accessible without a prefix, an identifier +must be a local name, a member of an enclosing template or a name introduced by 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 universal) 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 => ... ))) +``` + +Such infinite expansions should be detected and reported as errors, however to support the deliberate +implicit construction of recursive values we allow implicit arguments to be marked as by-name. At call +sites recursive uses of implicit values are permitted if they occur in an implicit by-name argument. + +Consider the following example, + +```scala +trait Foo { + def next: Foo +} + +object Foo { + implicit def foo(implicit rec: Foo): Foo = + new Foo { def next = rec } +} + +val foo = implicitly[Foo] +assert(foo eq foo.next) +``` + +As with the `magic` case above this diverges due to the recursive implicit argument `rec` of method +`foo`. If we mark the implicit argument as by-name, + +```scala +trait Foo { + def next: Foo +} + +object Foo { + implicit def foo(implicit rec: => Foo): Foo = + new Foo { def next = rec } +} + +val foo = implicitly[Foo] +assert(foo eq foo.next) +``` + +the example compiles with the assertion successful. + +When compiled, recursive by-name implicit arguments of this sort are extracted out as val members of a +local synthetic object at call sites as follows, + +```scala +val foo: Foo = scala.Predef.implicitly[Foo]( + { + object LazyDefns$1 { + val rec$1: Foo = Foo.foo(rec$1) + // ^^^^^ + // recursive knot tied here + } + LazyDefns$1.rec$1 + } +) +assert(foo eq foo.next) +``` + +Note that the recursive use of `rec$1` occurs within the by-name argument of `foo` and is consequently +deferred. The desugaring matches what a programmer would do to construct such a recursive value +explicitly. + +To prevent infinite expansions, such as the `magic` example above, 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, ´T´ is added to the stack paired with the implicit +definition which produces it, and whether it was required to satisfy a by-name implicit argument or +not. The type is removed from the stack once the search for the implicit argument either definitely +fails or succeeds. Everytime a type is about to be added to the stack, it is checked against +existing entries which were produced by the same implicit definition and then, + ++ if it is equivalent to some type which is already on the stack and there is a by-name argument between + that entry and the top of the stack. In this case the search for that type succeeds immediately and + the implicit argument is compiled as a recursive reference to the found argument. That argument is + added as an entry in the synthesized implicit dictionary if it has not already been added. ++ otherwise if the _core_ of the type _dominates_ the core of a type already on the stack, then the + implicit expansion is said to _diverge_ and the search for that type fails immediately. ++ otherwise it is added to the stack paired with the implicit definition which produces it. + Implicit resolution continues with the implicit arguments of that definition (if any). + +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. + +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´ and the _covering sets_ of ´T´ and ´U´ are equal. + +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)´ + +The _covering set_ ´\mathit{cs}(T)´ of a type ´T´ is the set of type designators mentioned in a type. +For example, given the following, + +```scala +type A = List[(Int, Int)] +type B = List[(Int, (Int, Int))] +type C = List[(Int, String)] +``` + +the corresponding covering sets are: + +- ´\mathit{cs}(A)´: List, Tuple2, Int +- ´\mathit{cs}(B)´: List, Tuple2, Int +- ´\mathit{cs}(C)´: List, Tuple2, Int, String + +###### 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 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 its 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. + +Evidence parameters are prepended to the existing implicit parameter section, if one exists. + +For example: + +```scala +def foo[A: M](implicit b: B): C +// expands to: +// def foo[A](implicit evidence´1: M[A], b: B): C +``` + +###### 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/docs/_spec/08-pattern-matching.md b/docs/_spec/08-pattern-matching.md new file mode 100644 index 000000000000..7607b0db85e0 --- /dev/null +++ b/docs/_spec/08-pattern-matching.md @@ -0,0 +1,817 @@ +--- +title: Pattern Matching +layout: default +chapter: 8 +--- + +# Pattern Matching + +## Patterns + +```ebnf + Pattern ::= Pattern1 { ‘|’ Pattern1 } + Pattern1 ::= boundvarid ‘:’ TypePat + | ‘_’ ‘:’ TypePat + | Pattern2 + Pattern2 ::= id [‘@’ Pattern3] + | Pattern3 + Pattern3 ::= SimplePattern + | SimplePattern {id [nl] SimplePattern} + SimplePattern ::= ‘_’ + | varid + | Literal + | StableId + | StableId ‘(’ [Patterns] ‘)’ + | StableId ‘(’ [Patterns ‘,’] [id ‘@’] ‘_’ ‘*’ ‘)’ + | ‘(’ [Patterns] ‘)’ + | XmlPattern + Patterns ::= Pattern {‘,’ Patterns} +``` + +A pattern is built from constants, constructors, variables and type +tests. Pattern matching tests whether a given value (or sequence of values) +has the shape defined by a pattern, and, if it does, binds the +variables in the pattern to the corresponding components of the value +(or sequence of values). The same variable name may not be bound more +than once in a pattern. + +###### Example +Some examples of patterns are: + 1. The pattern `ex: IOException` matches all instances of class + `IOException`, binding variable `ex` to the instance. + 1. The pattern `Some(x)` matches values of the form `Some(´v´)`, + binding `x` to the argument value ´v´ of the `Some` constructor. + 1. The pattern `(x, _)` matches pairs of values, binding `x` to + the first component of the pair. The second component is matched + with a wildcard pattern. + 1. The pattern `x :: y :: xs` matches lists of length ´\geq 2´, + binding `x` to the list's first element, `y` to the list's + second element, and `xs` to the remainder. + 1. The pattern `1 | 2 | 3` matches the integers between 1 and 3. + +Pattern matching is always done in a context which supplies an +expected type of the pattern. We distinguish the following kinds of +patterns. + +### Variable Patterns + +```ebnf + SimplePattern ::= ‘_’ + | varid +``` + +A _variable pattern_ ´x´ is a simple identifier which starts with a +lower case letter. It matches any value, and binds the variable name +to that value. The type of ´x´ is the expected type of the pattern as +given from outside. A special case is the wild-card pattern `_` +which is treated as if it was a fresh variable on each occurrence. + +### Typed Patterns + +```ebnf + Pattern1 ::= varid ‘:’ TypePat + | ‘_’ ‘:’ TypePat +``` + +A _typed pattern_ ´x: T´ consists of a pattern variable ´x´ and a +type pattern ´T´. The type of ´x´ is the type pattern ´T´, where +each type variable and wildcard is replaced by a fresh, unknown type. +This pattern matches any value matched by the [type pattern](#type-patterns) +´T´; it binds the variable name to +that value. + +### Pattern Binders + +```ebnf + Pattern2 ::= varid ‘@’ Pattern3 +``` + +A _pattern binder_ `´x´@´p´` consists of a pattern variable ´x´ and a +pattern ´p´. The type of the variable ´x´ is the static type ´T´ implied +by the pattern ´p´. +This pattern matches any value ´v´ matched by the pattern ´p´, +and it binds the variable name to that value. + +A pattern ´p´ _implies_ a type ´T´ if the pattern matches only values of the type ´T´. + +### Literal Patterns + +```ebnf + SimplePattern ::= Literal +``` + +A _literal pattern_ ´L´ matches any value that is equal (in terms of +`==`) to the literal ´L´. The type of ´L´ must conform to the +expected type of the pattern. + +### Interpolated string patterns + +```ebnf + Literal ::= interpolatedString +``` + +The expansion of interpolated string literals in patterns is the same as +in expressions. If it occurs in a pattern, a interpolated string literal +of either of the forms +``` +id"text0{ pat1 }text1 … { patn }textn" +id"""text0{ pat1 }text1 … { patn }textn""" +``` +is equivalent to: +``` +StringContext("""text0""", …, """textn""").id(pat1, …, patn) +``` +You could define your own `StringContext` to shadow the default one that's +in the `scala` package. + +This expansion is well-typed if the member `id` evaluates to an extractor +object. If the extractor object has `apply` as well as `unapply` or +`unapplySeq` methods, processed strings can be used as either expressions +or patterns. + +Taking XML as an example +```scala +implicit class XMLinterpolation(s: StringContext) = { + object xml { + def apply(exprs: Any*) = + // parse ‘s’ and build an XML tree with ‘exprs’ + //in the holes + def unapplySeq(xml: Node): Option[Seq[Node]] = + // match `s’ against `xml’ tree and produce + //subtrees in holes + } +} +``` +Then, XML pattern matching could be expressed like this: +```scala +case xml""" + + $linktext + + """ => ... +``` +where linktext is a variable bound by the pattern. + +### Stable Identifier Patterns + +```ebnf + SimplePattern ::= StableId +``` + +A _stable identifier pattern_ is a [stable identifier](03-types.html#paths) ´r´. +The type of ´r´ must conform to the expected +type of the pattern. The pattern matches any value ´v´ such that +`´r´ == ´v´` (see [here](12-the-scala-standard-library.html#root-classes)). + +To resolve the syntactic overlap with a variable pattern, a +stable identifier pattern may not be a simple name starting with a lower-case +letter. However, it is possible to enclose such a variable name in +backquotes; then it is treated as a stable identifier pattern. + +###### Example +Consider the following class definition: + +```scala +class C { c => + val x = 42 + val y = 27 + val Z = 8 + def f(x: Int) = x match { + case c.x => 1 // matches 42 + case `y` => 2 // matches 27 + case Z => 3 // matches 8 + case x => 4 // matches any value + } +} +``` + +Here, the first three patterns are stable identifier patterns, while the last +one is a variable pattern. + +### Constructor Patterns + +```ebnf +SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ +``` + +A _constructor pattern_ is of the form ´c(p_1 , \ldots , p_n)´ where ´n +\geq 0´. It consists of a stable identifier ´c´, followed by element +patterns ´p_1 , \ldots , p_n´. The constructor ´c´ is a simple or +qualified name which denotes a [case class](05-classes-and-objects.html#case-classes). +If the case class is monomorphic, then it +must conform to the expected type of the pattern, and the formal +parameter types of ´x´'s [primary constructor](05-classes-and-objects.html#class-definitions) +are taken as the expected types of the element patterns ´p_1, \ldots , +p_n´. If the case class is polymorphic, then its type parameters are +instantiated so that the instantiation of ´c´ conforms to the expected +type of the pattern. The instantiated formal parameter types of ´c´'s +primary constructor are then taken as the expected types of the +component patterns ´p_1, \ldots , p_n´. The pattern matches all +objects created from constructor invocations ´c(v_1 , \ldots , v_n)´ +where each element pattern ´p_i´ matches the corresponding value +´v_i´. + +A special case arises when ´c´'s formal parameter types end in a +repeated parameter. This is further discussed [here](#pattern-sequences). + +### Tuple Patterns + +```ebnf + SimplePattern ::= ‘(’ [Patterns] ‘)’ +``` + +A _tuple pattern_ `(´p_1 , \ldots , p_n´)` is an alias +for the constructor pattern `scala.Tuple´n´(´p_1 , \ldots , p_n´)`, +where ´n \geq 2´. The empty tuple +`()` is the unique value of type `scala.Unit`. + +### Extractor Patterns + +```ebnf + SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ +``` + +An _extractor pattern_ ´x(p_1 , \ldots , p_n)´ where ´n \geq 0´ is of +the same syntactic form as a constructor pattern. However, instead of +a case class, the stable identifier ´x´ denotes an object which has a +member method named `unapply` or `unapplySeq` that matches +the pattern. + +An extractor pattern cannot match the value `null`. The implementation +ensures that the `unapply`/`unapplySeq` method is not applied to `null`. + +A type is said to be an _extractor type_ for some type `T` if it has a +method `get` with return type `T`, and a method `isEmpty` with a return type +that conforms to `Boolean`. `Option[T]` is an extractor type for type `T`. + +An `unapply` method in an object ´x´ _matches_ the pattern +´x(p_1 , \ldots , p_n)´ if it has a single parameter (and, optionally, an +implicit parameter list) and one of the following applies: + +* ´n=0´ and `unapply`'s result type conforms to `Boolean`. In this case + the extractor pattern matches all values ´v´ for which + `´x´.unapply(´v´)` yields `true`. +* ´n=1´ and `unapply`'s result type is an extractor type for some + type ´T´. In this case, the (only) argument pattern ´p_1´ is typed in + turn with expected type ´T´. The extractor pattern matches then all + values ´v´ for which `´x´.unapply(´v´)` yields a value ´u´ for which `´u´.isEmpty` yields + `false`, `´u´.get` yields a value ´v_1´, and ´p_1´ matches ´v_1´. +* ´n>1´ and `unapply`'s result type is + an extractor type for some type ´T´ with members ´\_1 , \ldots , \_n´ returning + types ´T_1 , \ldots , T_n´. In this case, the argument patterns ´p_1 + , \ldots , p_n´ are typed in turn with expected types ´T_1 , \ldots , + T_n´. The extractor pattern matches then all values ´v´ for which + `´x´.unapply(´v´)` yields a value ´u´ for which + `´u´.isEmpty` yields `false`, `´u´.get` yields some value ´t´, and each pattern + ´p_i´ matches the corresponding value ´t._1´ from + ´t._1 , \ldots , t._n´. + +An `unapplySeq` method in an object ´x´ matches the pattern +´x(q_1 , \ldots , q_m, p_1 , \ldots , p_n)´ if it takes exactly one argument +and its result type is of the form `Option[(´T_1 , \ldots , T_m´, Seq[S])]` (if `m = 0`, the type `Option[Seq[S]]` is also accepted). +This case is further discussed [below](#pattern-sequences). + +###### Example 1 + +If we define an extractor object `Pair`: + +```scala +object Pair { + def apply[A, B](x: A, y: B) = Tuple2(x, y) + def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x) +} +``` + +This means that the name `Pair` can be used in place of `Tuple2` for tuple +formation as well as for deconstruction of tuples in patterns. +Hence, the following is possible: + +```scala +val x = (1, 2) +val y = x match { + case Pair(i, s) => Pair(s + i, i * i) +} +``` + +###### Example 2 + +If we define a class `NameBased` + +```scala +class NameBased[A, B](a: A, b: B) { + def isEmpty = false + def get = this + def _1 = a + def _2 = b +} +``` + +Then `NameBased` is an extractor type for `NameBased` itself, since it has a +member `isEmpty` returning a value of type Boolean, and it has a member `get` +returning a value of type `NameBased`. + +Since it also has members `_1` and `_2`, it can be used in an extractor pattern +with n = 2 as follows: + +```scala +object Extractor { + def unapply(x: Any) = new NameBased(1, "two") +} + +"anything" match { + case Extractor(a, b) => println(s"\$a, \$b") //prints "1, two" +} +``` + + +### Pattern Sequences + +```ebnf +SimplePattern ::= StableId ‘(’ [Patterns ‘,’] [varid ‘@’] ‘_’ ‘*’ ‘)’ +``` + +A _pattern sequence_ ´p_1 , \ldots , p_n´ appears in two contexts. +First, in a constructor pattern ´c(q_1 , \ldots , q_m, p_1 , \ldots , p_n)´, where ´c´ is a case class which has ´m+1´ primary constructor parameters, ending in a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type `S*`. +Second, in an extractor pattern ´x(q_1 , \ldots , q_m, p_1 , \ldots , p_n)´ if the extractor object ´x´ does not have an `unapply` method, +but it does define an `unapplySeq` method with a result type that is an extractor type for type `(T_1, ... , T_m, Seq[S])` (if `m = 0`, an extractor type for the type `Seq[S]` is also accepted). The expected type for the patterns ´p_i´ is ´S´. + +The last pattern in a pattern sequence may be a _sequence wildcard_ `_*`. +Each element pattern ´p_i´ is type-checked with +´S´ as expected type, unless it is a sequence wildcard. If a final +sequence wildcard is present, the pattern matches all values ´v´ that +are sequences which start with elements matching patterns +´p_1 , \ldots , p_{n-1}´. If no final sequence wildcard is given, the +pattern matches all values ´v´ that are sequences of +length ´n´ which consist of elements matching patterns ´p_1 , \ldots , +p_n´. + +### Infix Operation Patterns + +```ebnf + Pattern3 ::= SimplePattern {id [nl] SimplePattern} +``` + +An _infix operation pattern_ ´p;\mathit{op};q´ is a shorthand for the +constructor or extractor pattern ´\mathit{op}(p, q)´. The precedence and +associativity of operators in patterns is the same as in +[expressions](06-expressions.html#prefix,-infix,-and-postfix-operations). + +An infix operation pattern ´p;\mathit{op};(q_1 , \ldots , q_n)´ is a +shorthand for the constructor or extractor pattern ´\mathit{op}(p, q_1 +, \ldots , q_n)´. + +### Pattern Alternatives + +```ebnf + Pattern ::= Pattern1 { ‘|’ Pattern1 } +``` + +A _pattern alternative_ `´p_1´ | ´\ldots´ | ´p_n´` +consists of a number of alternative patterns ´p_i´. All alternative +patterns are type checked with the expected type of the pattern. They +may not bind variables other than wildcards. The alternative pattern +matches a value ´v´ if at least one its alternatives matches ´v´. + +### XML Patterns + +XML patterns are treated [here](10-xml-expressions-and-patterns.html#xml-patterns). + +### Regular Expression Patterns + +Regular expression patterns have been discontinued in Scala from version 2.0. + +Later version of Scala provide a much simplified version of regular +expression patterns that cover most scenarios of non-text sequence +processing. A _sequence pattern_ is a pattern that stands in a +position where either (1) a pattern of a type `T` which is +conforming to +`Seq[A]` for some `A` is expected, or (2) a case +class constructor that has an iterated formal parameter +`A*`. A wildcard star pattern `_*` in the +rightmost position stands for arbitrary long sequences. It can be +bound to variables using `@`, as usual, in which case the variable will have the +type `Seq[A]`. + +### Irrefutable Patterns + +A pattern ´p´ is _irrefutable_ for a type ´T´, if one of the following applies: + +1. ´p´ is a variable pattern, +1. ´p´ is a typed pattern ´x: T'´, and ´T <: T'´, +1. ´p´ is a constructor pattern ´c(p_1 , \ldots , p_n)´, the type ´T´ + is an instance of class ´c´, the [primary constructor](05-classes-and-objects.html#class-definitions) + of type ´T´ has argument types ´T_1 , \ldots , T_n´, and each ´p_i´ is + irrefutable for ´T_i´. +1. ´p´ is an extractor pattern for which the extractor type is `Some[´T´]` for + some type ´T´ +1. ´p´ is an extractor pattern for which the extractor types `isEmpty` method + is the singleton type `false` +1. ´p´ is an extractor pattern for which the return type is the singleton type + `true` + +## Type Patterns + +```ebnf + TypePat ::= Type +``` + +Type patterns consist of types, type variables, and wildcards. +A type pattern ´T´ is of one of the following forms: + +* A reference to a class ´C´, ´p.C´, or `´T´#´C´`. This + type pattern matches any non-null instance of the given class. + Note that the prefix of the class, if it exists, is relevant for determining + class instances. For instance, the pattern ´p.C´ matches only + instances of classes ´C´ which were created with the path ´p´ as + prefix. This also applies to prefixes which are not given syntactically. + For example, if ´C´ refers to a class defined in the nearest enclosing + class and is thus equivalent to ´this.C´, it is considered to have a prefix. + + The bottom types `scala.Nothing` and `scala.Null` cannot + be used as type patterns, because they would match nothing in any case. + +* A singleton type `´p´.type`. This type pattern matches only the value + denoted by the path ´p´ (the `eq` method is used to compare the matched value + to ´p´). + +* A literal type `´lit´`. This type pattern matches only the value + denoted by the literal ´lit´ (the `==` method is used to compare the matched + value to ´lit´). + +* A compound type pattern `´T_1´ with ´\ldots´ with ´T_n´` where each ´T_i´ is a + type pattern. This type pattern matches all values that are matched by each of + the type patterns ´T_i´. + +* A parameterized type pattern ´T[a_1 , \ldots , a_n]´, where the ´a_i´ + are type variable patterns or wildcards `_`. + This type pattern matches all values which match ´T´ for + some arbitrary instantiation of the type variables and wildcards. The + bounds or alias type of these type variable are determined as + described [here](#type-parameter-inference-in-patterns). + +* A parameterized type pattern `scala.Array´[T_1]´`, where + ´T_1´ is a type pattern. This type pattern matches any non-null instance + of type `scala.Array´[U_1]´`, where ´U_1´ is a type matched by ´T_1´. + +Types which are not of one of the forms described above are also +accepted as type patterns. However, such type patterns will be translated to their +[erasure](03-types.html#type-erasure). The Scala +compiler will issue an "unchecked" warning for these patterns to +flag the possible loss of type-safety. + +A _type variable pattern_ is a simple identifier which starts with +a lower case letter. + +## Type Parameter Inference in Patterns + +Type parameter inference is the process of finding bounds for the +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 + +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 +the type variables in ´T´. These type variables are considered bound +in the pattern. Let the expected type of the pattern be ´\mathit{pt}´. + +Type parameter inference constructs first a set of subtype constraints over +the type variables ´a_i´. The initial constraints set ´\mathcal{C}\_0´ reflects +just the bounds of these type variables. That is, assuming ´T´ has +bound type variables ´a_1 , \ldots , a_n´ which correspond to class +type parameters ´a_1' , \ldots , a_n'´ with lower bounds ´L_1, \ldots , L_n´ +and upper bounds ´U_1 , \ldots , U_n´, ´\mathcal{C}_0´ contains the constraints + +$$ +\begin{cases} +a_i &<: \sigma U_i & \quad (i = 1, \ldots , n) \\\\ +\sigma L_i &<: a_i & \quad (i = 1, \ldots , n) +\end{cases} +$$ + +where ´\sigma´ is the substitution ´[a_1' := a_1 , \ldots , a_n' :=a_n]´. + +The set ´\mathcal{C}_0´ is then augmented by further subtype constraints. There are two +cases. + +###### Case 1 +If there exists a substitution ´\sigma´ over the type variables ´a_i , \ldots , a_n´ such that ´\sigma T´ conforms to ´\mathit{pt}´, one determines the weakest subtype constraints +´\mathcal{C}\_1´ over the type variables ´a_1, \ldots , a_n´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}_1´ implies that ´T´ conforms to ´\mathit{pt}´. + +###### Case 2 +Otherwise, if ´T´ can not be made to conform to ´\mathit{pt}´ by +instantiating its type variables, one determines all type variables in +´\mathit{pt}´ which are defined as type parameters of a method enclosing +the pattern. Let the set of such type parameters be ´b_1 , \ldots , +b_m´. Let ´\mathcal{C}\_0'´ be the subtype constraints reflecting the bounds of the +type variables ´b_i´. If ´T´ denotes an instance type of a final +class, let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type +variables ´a_1 , \ldots , a_n´ and ´b_1 , \ldots , b_m´ such that +´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that ´T´ conforms to +´\mathit{pt}´. If ´T´ does not denote an instance type of a final class, +let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type variables +´a_1 , \ldots , a_n´ and ´b_1 , \ldots , b_m´ such that ´\mathcal{C}\_0 \wedge +\mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that it is possible to construct a type +´T'´ which conforms to both ´T´ and ´\mathit{pt}´. It is a static error if +there is no satisfiable set of constraints ´\mathcal{C}\_2´ with this property. + +The final step consists in choosing type bounds for the type +variables which imply the established constraint system. The process +is different for the two cases above. + +###### Case 1 +We take ´a_i >: L_i <: U_i´ where each ´L_i´ is minimal and each ´U_i´ is maximal wrt ´<:´ such that ´a_i >: L_i <: U_i´ for ´i = 1, \ldots, n´ implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_1´. + +###### Case 2 +We take ´a_i >: L_i <: U_i´ and ´b\_i >: L_i' <: U_i' ´ where each ´L_i´ +and ´L_j'´ is minimal and each ´U_i´ and ´U_j'´ is maximal such that +´a_i >: L_i <: U_i´ for ´i = 1 , \ldots , n´ and +´b_j >: L_j' <: U_j'´ for ´j = 1 , \ldots , m´ +implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}_2´. + +In both cases, local type inference is permitted to limit the +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 +Assume a constructor pattern ´C(p_1 , \ldots , p_n)´ where class ´C´ +has type parameters ´a_1 , \ldots , a_n´. These type parameters +are inferred in the same way as for the typed pattern +`(_: ´C[a_1 , \ldots , a_n]´)`. + +###### Example +Consider the program fragment: + +```scala +val x: Any +x match { + case y: List[a] => ... +} +``` + +Here, the type pattern `List[a]` is matched against the +expected type `Any`. The pattern binds the type variable +`a`. Since `List[a]` conforms to `Any` +for every type argument, there are no constraints on `a`. +Hence, `a` is introduced as an abstract type with no +bounds. The scope of `a` is right-hand side of its case clause. + +On the other hand, if `x` is declared as + +```scala +val x: List[List[String]], +``` + +this generates the constraint +`List[a] <: List[List[String]]`, which simplifies to +`a <: List[String]`, because `List` is covariant. Hence, +`a` is introduced with upper bound +`List[String]`. + +###### Example +Consider the program fragment: + +```scala +val x: Any +x match { + case y: List[String] => ... +} +``` + +Scala does not maintain information about type arguments at run-time, +so there is no way to check that `x` is a list of strings. +Instead, the Scala compiler will [erase](03-types.html#type-erasure) the +pattern to `List[_]`; that is, it will only test whether the +top-level runtime-class of the value `x` conforms to +`List`, and the pattern match will succeed if it does. This +might lead to a class cast exception later on, in the case where the +list `x` contains elements other than strings. The Scala +compiler will flag this potential loss of type-safety with an +"unchecked" warning message. + +###### Example +Consider the program fragment + +```scala +class Term[A] +class Number(val n: Int) extends Term[Int] +def f[B](t: Term[B]): B = t match { + case y: Number => y.n +} +``` + +The expected type of the pattern `y: Number` is +`Term[B]`. The type `Number` does not conform to +`Term[B]`; hence Case 2 of the rules above +applies. This means that `B` is treated as another type +variable for which subtype constraints are inferred. In our case the +applicable constraint is `Number <: Term[B]`, which +entails `B = Int`. Hence, `B` is treated in +the case clause as an abstract type with lower and upper bound +`Int`. Therefore, the right hand side of the case clause, +`y.n`, of type `Int`, is found to conform to the +function's declared result type, `Number`. + +## Pattern Matching Expressions + +```ebnf + Expr ::= PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’ + CaseClauses ::= CaseClause {CaseClause} + CaseClause ::= ‘case’ Pattern [Guard] ‘=>’ Block +``` + +A _pattern matching expression_ + +```scala +e match { case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ } +``` + +consists of a selector expression ´e´ and a number ´n > 0´ of +cases. Each case consists of a (possibly guarded) pattern ´p_i´ and a +block ´b_i´. Each ´p_i´ might be complemented by a guard +`if ´e´` where ´e´ is a boolean expression. +The scope of the pattern +variables in ´p_i´ comprises the pattern's guard and the corresponding block ´b_i´. + +Let ´T´ be the type of the selector expression ´e´ and let ´a_1 +, \ldots , a_m´ be the type parameters of all methods enclosing +the pattern matching expression. For every ´a_i´, let ´L_i´ be its +lower bound and ´U_i´ be its higher bound. Every pattern ´p \in \{p_1, , \ldots , p_n\}´ +can be typed in two ways. First, it is attempted +to type ´p´ with ´T´ as its expected type. If this fails, ´p´ is +instead typed with a modified expected type ´T'´ which results from +´T´ by replacing every occurrence of a type parameter ´a_i´ by +*undefined*. If this second step fails also, a compile-time +error results. If the second step succeeds, let ´T_p´ be the type of +pattern ´p´ seen as an expression. One then determines minimal bounds +´L_11 , \ldots , L_m'´ and maximal bounds ´U_1' , \ldots , U_m'´ such +that for all ´i´, ´L_i <: L_i'´ and ´U_i' <: U_i´ and the following +constraint system is satisfied: + +$$ +L_1 <: a_1 <: U_1\;\wedge\;\ldots\;\wedge\;L_m <: a_m <: U_m \ \Rightarrow\ T_p <: T +$$ + +If no such bounds can be found, a compile time error results. If such +bounds are found, the pattern matching clause starting with ´p´ is +then typed under the assumption that each ´a_i´ has lower bound ´L_i'´ +instead of ´L_i´ and has upper bound ´U_i'´ instead of ´U_i´. + +The expected type of every block ´b_i´ is the expected type of the +whole pattern matching expression. The type of the pattern matching +expression is then the [weak least upper bound](03-types.html#weak-conformance) +of the types of all blocks +´b_i´. + +When applying a pattern matching expression to a selector value, +patterns are tried in sequence until one is found which matches the +[selector value](#patterns). Say this case is `case ´p_i \Rightarrow b_i´`. +The result of the whole expression is the result of evaluating ´b_i´, +where all pattern variables of ´p_i´ are bound to +the corresponding parts of the selector value. If no matching pattern +is found, a `scala.MatchError` exception is thrown. + +The pattern in a case may also be followed by a guard suffix +`if e` with a boolean expression ´e´. The guard expression is +evaluated if the preceding pattern in the case matches. If the guard +expression evaluates to `true`, the pattern match succeeds as +normal. If the guard expression evaluates to `false`, the pattern +in the case is considered not to match and the search for a matching +pattern continues. + +In the interest of efficiency the evaluation of a pattern matching +expression may try patterns in some other order than textual +sequence. This might affect evaluation through +side effects in guards. However, it is guaranteed that a guard +expression is evaluated only if the pattern it guards matches. + +If the selector of a pattern match is an instance of a +[`sealed` class](05-classes-and-objects.html#modifiers), +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 + +Consider the following definitions of arithmetic terms: + +```scala +abstract class Term[T] +case class Lit(x: Int) extends Term[Int] +case class Succ(t: Term[Int]) extends Term[Int] +case class IsZero(t: Term[Int]) extends Term[Boolean] +case class If[T](c: Term[Boolean], + t1: Term[T], + t2: Term[T]) extends Term[T] +``` + +There are terms to represent numeric literals, incrementation, a zero +test, and a conditional. Every term carries as a type parameter the +type of the expression it represents (either `Int` or `Boolean`). + +A type-safe evaluator for such terms can be written as follows. + +```scala +def eval[T](t: Term[T]): T = t match { + case Lit(n) => n + case Succ(u) => eval(u) + 1 + case IsZero(u) => eval(u) == 0 + case If(c, u1, u2) => eval(if (eval(c)) u1 else u2) +} +``` + +Note that the evaluator makes crucial use of the fact that type +parameters of enclosing methods can acquire new bounds through pattern +matching. + +For instance, the type of the pattern in the second case, +`Succ(u)`, is `Int`. It conforms to the selector type +`T` only if we assume an upper and lower bound of `Int` for `T`. +Under the assumption `Int <: T <: Int` we can also +verify that the type right hand side of the second case, `Int` +conforms to its expected type, `T`. + +## Pattern Matching Anonymous Functions + +```ebnf + BlockExpr ::= ‘{’ CaseClauses ‘}’ +``` + +An anonymous function can be defined by a sequence of cases + +```scala +{ case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ } +``` + +which appear as an expression without a prior `match`. The +expected type of such an expression must in part be defined. It must +be either `scala.Function´k´[´S_1 , \ldots , S_k´, ´R´]` for some ´k > 0´, +or `scala.PartialFunction[´S_1´, ´R´]`, where the +argument type(s) ´S_1 , \ldots , S_k´ must be fully determined, but the result type +´R´ may be undetermined. + +If the expected type is [SAM-convertible](06-expressions.html#sam-conversion) +to `scala.Function´k´[´S_1 , \ldots , S_k´, ´R´]`, +the expression is taken to be equivalent to the anonymous function: + +```scala +(´x_1: S_1 , \ldots , x_k: S_k´) => (´x_1 , \ldots , x_k´) match { + case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ +} +``` + +Here, each ´x_i´ is a fresh name. +As was shown [here](06-expressions.html#anonymous-functions), this anonymous function is in turn +equivalent to the following instance creation expression, where + ´T´ is the weak least upper bound of the types of all ´b_i´. + +```scala +new scala.Function´k´[´S_1 , \ldots , S_k´, ´T´] { + def apply(´x_1: S_1 , \ldots , x_k: S_k´): ´T´ = (´x_1 , \ldots , x_k´) match { + case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ + } +} +``` + +If the expected type is `scala.PartialFunction[´S´, ´R´]`, +the expression is taken to be equivalent to the following instance creation expression: + +```scala +new scala.PartialFunction[´S´, ´T´] { + def apply(´x´: ´S´): ´T´ = x match { + case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ + } + def isDefinedAt(´x´: ´S´): Boolean = { + case ´p_1´ => true ´\ldots´ case ´p_n´ => true + case _ => false + } +} +``` + +Here, ´x´ is a fresh name and ´T´ is the weak least upper bound of the +types of all ´b_i´. The final default case in the `isDefinedAt` +method is omitted if one of the patterns ´p_1 , \ldots , p_n´ is +already a variable or wildcard pattern. + +###### Example +Here's an example which uses +`foldLeft` to compute the scalar product of +two vectors: + +```scala +def scalarProduct(xs: Array[Double], ys: Array[Double]) = + (xs zip ys).foldLeft(0.0) { + case (a, (b, c)) => a + b * c + } +``` + +The case clauses in this code are equivalent to the following +anonymous function: + +```scala +(x, y) => (x, y) match { + case (a, (b, c)) => a + b * c +} +``` diff --git a/docs/_spec/09-top-level-definitions.md b/docs/_spec/09-top-level-definitions.md new file mode 100644 index 000000000000..33c436e8d77b --- /dev/null +++ b/docs/_spec/09-top-level-definitions.md @@ -0,0 +1,210 @@ +--- +title: Top-Level Definitions +layout: default +chapter: 9 +--- + +# Top-Level Definitions + +## Compilation Units + +```ebnf +CompilationUnit ::= {‘package’ QualId semi} TopStatSeq +TopStatSeq ::= TopStat {semi TopStat} +TopStat ::= {Annotation} {Modifier} TmplDef + | Import + | Packaging + | PackageObject + | +QualId ::= id {‘.’ id} +``` + +A compilation unit consists of a sequence of packagings, import +clauses, and class and object definitions, which may be preceded by a +package clause. + +A _compilation unit_ + +```scala +package ´p_1´; +´\ldots´ +package ´p_n´; +´\mathit{stats}´ +``` + +starting with one or more package +clauses is equivalent to a compilation unit consisting of the +packaging + +```scala +package ´p_1´ { ´\ldots´ + package ´p_n´ { + ´\mathit{stats}´ + } ´\ldots´ +} +``` + +Every compilation unit implicitly imports the following packages, in the given order: + 1. the package `java.lang`, + 2. the package `scala`, and + 3. the object [`scala.Predef`](12-the-scala-standard-library.html#the-predef-object), unless there is an explicit top-level import that references `scala.Predef`. + +Members of a later import in that order hide members of an earlier import. + +The exception to the implicit import of `scala.Predef` can be useful to hide, e.g., predefined implicit conversions. + +## Packagings + +```ebnf +Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ +``` + +A _package_ is a special object which defines a set of member classes, +objects and packages. Unlike other objects, packages are not introduced +by a definition. Instead, the set of members of a package is determined by +packagings. + +A packaging `package ´p´ { ´\mathit{ds}´ }` injects all +definitions in ´\mathit{ds}´ as members into the package whose qualified name +is ´p´. Members of a package are called _top-level_ definitions. +If a definition in ´\mathit{ds}´ is labeled `private`, it is +visible only for other members in the package. + +Inside the packaging, all members of package ´p´ are visible under their +simple names. However this rule does not extend to members of enclosing +packages of ´p´ that are designated by a prefix of the path ´p´. + +```scala +package org.net.prj { + ... +} +``` + +all members of package `org.net.prj` are visible under their +simple names, but members of packages `org` or `org.net` require +explicit qualification or imports. + +Selections ´p´.´m´ from ´p´ as well as imports from ´p´ +work as for objects. However, unlike other objects, packages may not +be used as values. It is illegal to have a package with the same fully +qualified name as a module or a class. + +Top-level definitions outside a packaging are assumed to be injected +into a special empty package. That package cannot be named and +therefore cannot be imported. However, members of the empty package +are visible to each other without qualification. + +## Package Objects + +```ebnf +PackageObject ::= ‘package’ ‘object’ ObjectDef +``` + +A _package object_ `package object ´p´ extends ´t´` adds the +members of template ´t´ to the package ´p´. There can be only one +package object per package. The standard naming convention is to place +the definition above in a file named `package.scala` that's +located in the directory corresponding to package ´p´. + +The package object should not define a member with the same name as +one of the top-level objects or classes defined in package ´p´. If +there is a name conflict, the behavior of the program is currently +undefined. It is expected that this restriction will be lifted in a +future version of Scala. + +## Package References + +```ebnf +QualId ::= id {‘.’ id} +``` + +A reference to a package takes the form of a qualified identifier. +Like all other references, package references are relative. That is, +a package reference starting in a name ´p´ will be looked up in the +closest enclosing scope that defines a member named ´p´. + +If a package name is shadowed, it's possible to refer to its +fully-qualified name by prefixing it with +the special predefined name `_root_`, which refers to the +outermost root package that contains all top-level packages. + +The name `_root_` has this special denotation only when +used as the first element of a qualifier; it is an ordinary +identifier otherwise. + +###### Example +Consider the following program: + +```scala +package b { + class B +} + +package a { + package b { + class A { + val x = new _root_.b.B + } + class C { + import _root_.b._ + def y = new B + } + } +} + +``` + +Here, the reference `_root_.b.B` refers to class `B` in the +toplevel package `b`. If the `_root_` prefix had been +omitted, the name `b` would instead resolve to the package +`a.b`, and, provided that package does not also +contain a class `B`, a compiler-time error would result. + +## Programs + +A _program_ is a top-level object that has a member method +_main_ of type `(Array[String])Unit`. Programs can be +executed from a command shell. The program's command arguments are +passed to the `main` method as a parameter of type +`Array[String]`. + +The `main` method of a program can be directly defined in the +object, or it can be inherited. The scala library defines a special class +`scala.App` whose body acts as a `main` method. +An objects ´m´ inheriting from this class is thus a program, +which executes the initialization code of the object ´m´. + +###### Example +The following example will create a hello world program by defining +a method `main` in module `test.HelloWorld`. + +```scala +package test +object HelloWorld { + def main(args: Array[String]) { println("Hello World") } +} +``` + +This program can be started by the command + +```scala +scala test.HelloWorld +``` + +In a Java environment, the command + +```scala +java test.HelloWorld +``` + +would work as well. + +`HelloWorld` can also be defined without a `main` method +by inheriting from `App` instead: + +```scala +package test +object HelloWorld extends App { + println("Hello World") +} +``` diff --git a/docs/_spec/10-xml-expressions-and-patterns.md b/docs/_spec/10-xml-expressions-and-patterns.md new file mode 100644 index 000000000000..a9b7edb14fff --- /dev/null +++ b/docs/_spec/10-xml-expressions-and-patterns.md @@ -0,0 +1,145 @@ +--- +title: XML +layout: default +chapter: 10 +--- + +# XML Expressions and Patterns + +__By Burak Emir__ + +This chapter describes the syntactic structure of XML expressions and patterns. +It follows as closely as possible the XML 1.0 specification, +changes being mandated by the possibility of embedding Scala code fragments. + +## XML expressions + +XML expressions are expressions generated by the following production, where the +opening bracket `<` of the first element must be in a position to start the lexical +[XML mode](01-lexical-syntax.html#xml-mode). + +```ebnf +XmlExpr ::= XmlContent {Element} +``` + +Well-formedness constraints of the XML specification apply, which +means for instance that start tags and end tags must match, and +attributes may only be defined once, except for constraints +related to entity resolution. + +The following productions describe Scala's extensible markup language, +designed as close as possible to the W3C extensible markup language +standard. Only the productions for attribute values and character data are changed. +Scala does not support declarations. Entity references are not resolved at runtime. + +```ebnf +Element ::= EmptyElemTag + | STag Content ETag + +EmptyElemTag ::= ‘<’ Name {S Attribute} [S] ‘/>’ + +STag ::= ‘<’ Name {S Attribute} [S] ‘>’ +ETag ::= ‘’ +Content ::= [CharData] {Content1 [CharData]} +Content1 ::= XmlContent + | Reference + | ScalaExpr +XmlContent ::= Element + | CDSect + | PI + | Comment +``` + +If an XML expression is a single element, its value is a runtime +representation of an XML node (an instance of a subclass of +`scala.xml.Node`). If the XML expression consists of more +than one element, then its value is a runtime representation of a +sequence of XML nodes (an instance of a subclass of +`scala.Seq[scala.xml.Node]`). + +If an XML expression is an entity reference, CDATA section, processing +instruction, or a comment, it is represented by an instance of the +corresponding Scala runtime class. + +By default, beginning and trailing whitespace in element content is removed, +and consecutive occurrences of whitespace are replaced by a single space +character `\u0020`. This behavior can be changed to preserve all whitespace +with a compiler option. + +```ebnf +Attribute ::= Name Eq AttValue + +AttValue ::= ‘"’ {CharQ | CharRef} ‘"’ + | ‘'’ {CharA | CharRef} ‘'’ + | ScalaExpr + +ScalaExpr ::= Block + +CharData ::= { CharNoRef } ´\textit{ without}´ {CharNoRef}‘{’CharB {CharNoRef} + ´\textit{ and without}´ {CharNoRef}‘]]>’{CharNoRef} +``` + + +XML expressions may contain Scala expressions as attribute values or +within nodes. In the latter case, these are embedded using a single opening +brace `{` and ended by a closing brace `}`. To express a single opening braces +within XML text as generated by CharData, it must be doubled. +Thus, `{{` represents the XML text `{` and does not introduce an embedded Scala expression. + + +```ebnf +BaseChar, CDSect, Char, Comment, CombiningChar, Ideographic, NameChar, PI, S, Reference + ::= ´\textit{“as in W3C XML”}´ + +Char1 ::= Char ´\textit{ without}´ ‘<’ | ‘&’ +CharQ ::= Char1 ´\textit{ without}´ ‘"’ +CharA ::= Char1 ´\textit{ without}´ ‘'’ +CharB ::= Char1 ´\textit{ without}´ ‘{’ + +Name ::= XNameStart {NameChar} + +XNameStart ::= ‘_’ | BaseChar | Ideographic + ´\textit{ (as in W3C XML, but without }´ ‘:’´)´ +``` + +## XML patterns + +XML patterns are patterns generated by the following production, where +the opening bracket `<` of the element patterns must be in a position +to start the lexical [XML mode](01-lexical-syntax.html#xml-mode). + +```ebnf +XmlPattern ::= ElementPattern +``` + +Well-formedness constraints of the XML specification apply. + +An XML pattern has to be a single element pattern. It +matches exactly those runtime +representations of an XML tree +that have the same structure as described by the pattern. +XML patterns may contain [Scala patterns](08-pattern-matching.html#pattern-matching-expressions). + +Whitespace is treated the same way as in XML expressions. + +By default, beginning and trailing whitespace in element content is removed, +and consecutive occurrences of whitespace are replaced by a single space +character `\u0020`. This behavior can be changed to preserve all whitespace +with a compiler option. + +```ebnf +ElemPattern ::= EmptyElemTagP + | STagP ContentP ETagP + +EmptyElemTagP ::= ‘<’ Name [S] ‘/>’ +STagP ::= ‘<’ Name [S] ‘>’ +ETagP ::= ‘’ +ContentP ::= [CharData] {(ElemPattern|ScalaPatterns) [CharData]} +ContentP1 ::= ElemPattern + | Reference + | CDSect + | PI + | Comment + | ScalaPatterns +ScalaPatterns ::= ‘{’ Patterns ‘}’ +``` diff --git a/docs/_spec/11-annotations.md b/docs/_spec/11-annotations.md new file mode 100644 index 000000000000..388d99b60e56 --- /dev/null +++ b/docs/_spec/11-annotations.md @@ -0,0 +1,176 @@ +--- +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 the following field + definition in Java: + + ```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 the 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: , since: )`
+ Marks a formal parameter name as deprecated. Invocations of this entity + using named parameter syntax referring 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 that would otherwise be emitted. For instance, no warnings + would be produced for the method definition below. + + ```scala + def f(x: Option[Int]) = (x: @unchecked) match { + case Some(y) => y + } + ``` + + 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: + + ```scala + 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` + + ```scala + 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](https://docs.scala-lang.org/sips/scala-specialization.html) for more details of the implementation. + + +## User-defined Annotations + +Other annotations may be interpreted by platform- or application-dependent +tools. The class `scala.annotation.Annotation` is the base class for +user-defined annotations. It has two sub-traits: +- `scala.annotation.StaticAnnotation`: Instances of a subclass of this trait + will be stored in the generated class files, and therefore accessible to + runtime reflection and later compilation runs. +- `scala.annotation.ConstantAnnotation`: Instances of a subclass of this trait + may only have arguments which are + [constant expressions](06-expressions.html#constant-expressions), and are + also stored in the generated class files. +- If an annotation class inherits from neither `scala.ConstantAnnotation` nor + `scala.StaticAnnotation`, its instances are visible only locally during the + compilation run that analyzes them. + +## Host-platform Annotations + +The host platform may define its own annotation format. These annotations do not +extend any of the classes in the `scala.annotation` package, but can generally +be used in the same way as Scala annotations. The host platform may impose +additional restrictions on the expressions which are valid as annotation +arguments. diff --git a/docs/_spec/12-the-scala-standard-library.md b/docs/_spec/12-the-scala-standard-library.md new file mode 100644 index 000000000000..80d66c0c4166 --- /dev/null +++ b/docs/_spec/12-the-scala-standard-library.md @@ -0,0 +1,816 @@ +--- +title: Standard Library +layout: default +chapter: 12 +--- + +# The Scala Standard Library + +The Scala standard library consists of the package `scala` with a +number of classes and modules. Some of these classes are described in +the following. + +![Class hierarchy of Scala](public/images/classhierarchy.png) + +## Root Classes + +The root of this hierarchy is formed by class `Any`. +Every class in a Scala execution environment inherits directly or +indirectly from this class. Class `Any` has two direct +subclasses: `AnyRef` and `AnyVal`. + +The subclass `AnyRef` represents all values which are represented +as objects in the underlying host system. Classes written in other languages +inherit from `scala.AnyRef`. + +The predefined subclasses of class `AnyVal` describe +values which are not implemented as objects in the underlying host +system. + +User-defined Scala classes which do not explicitly inherit from +`AnyVal` inherit directly or indirectly from `AnyRef`. They cannot +inherit from both `AnyRef` and `AnyVal`. + +Classes `AnyRef` and `AnyVal` are required to provide only +the members declared in class `Any`, but implementations may add +host-specific methods to these classes (for instance, an +implementation may identify class `AnyRef` with its own root +class for objects). + +The signatures of these root classes are described by the following +definitions. + +```scala +package scala +/** The universal root class */ +abstract class Any { + + /** Defined equality; abstract here */ + def equals(that: Any): Boolean + + /** Semantic equality between values */ + final def == (that: Any): Boolean = + if (null eq this) null eq that else this equals that + + /** Semantic inequality between values */ + final def != (that: Any): Boolean = !(this == that) + + /** Hash code; abstract here */ + def hashCode: Int = ´\ldots´ + + /** Textual representation; abstract here */ + def toString: String = ´\ldots´ + + /** Type test; needs to be inlined to work as given */ + def isInstanceOf[a]: Boolean + + /** Type cast; needs to be inlined to work as given */ */ + def asInstanceOf[A]: A = this match { + case x: A => x + case _ => if (this eq null) this + else throw new ClassCastException() + } +} + +/** The root class of all value types */ +final class AnyVal extends Any + +/** The root class of all reference types */ +class AnyRef extends Any { + def equals(that: Any): Boolean = this eq that + final def eq(that: AnyRef): Boolean = ´\ldots´ // reference equality + final def ne(that: AnyRef): Boolean = !(this eq that) + + def hashCode: Int = ´\ldots´ // hashCode computed from allocation address + def toString: String = ´\ldots´ // toString computed from hashCode and class name + + def synchronized[T](body: => T): T // execute `body` in while locking `this`. +} +``` + +The type test `´x´.isInstanceOf[´T´]` is equivalent to a typed +pattern match + +```scala +´x´ match { + case _: ´T'´ => true + case _ => false +} +``` + +where the type ´T'´ is the same as ´T´ except if ´T´ is +of the form ´D´ or ´D[\mathit{tps}]´ where ´D´ is a type member of some outer class ´C´. +In this case ´T'´ is `´C´#´D´` (or `´C´#´D[tps]´`, respectively), whereas ´T´ itself would expand to `´C´.this.´D[tps]´`. +In other words, an `isInstanceOf` test does not check that types have the same enclosing instance. + +The test `´x´.asInstanceOf[´T´]` is treated specially if ´T´ is a +[numeric value type](#value-classes). In this case the cast will +be translated to an application of a [conversion method](#numeric-value-types) +`x.to´T´`. For non-numeric values ´x´ the operation will raise a +`ClassCastException`. + +## Value Classes + +Value classes are classes whose instances are not represented as +objects by the underlying host system. All value classes inherit from +class `AnyVal`. Scala implementations need to provide the +value classes `Unit`, `Boolean`, `Double`, `Float`, +`Long`, `Int`, `Char`, `Short`, and `Byte` +(but are free to provide others as well). +The signatures of these classes are defined in the following. + +### Numeric Value Types + +Classes `Double`, `Float`, +`Long`, `Int`, `Char`, `Short`, and `Byte` +are together called _numeric value types_. Classes `Byte`, +`Short`, or `Char` are called _subrange types_. +Subrange types, as well as `Int` and `Long` are called _integer types_, whereas `Float` and `Double` are called _floating point types_. + +Numeric value types are ranked in the following partial order: + +```scala +Byte - Short + \ + Int - Long - Float - Double + / + Char +``` + +`Byte` and `Short` are the lowest-ranked types in this order, +whereas `Double` is the highest-ranked. Ranking does _not_ +imply a [conformance relationship](03-types.html#conformance); for +instance `Int` is not a subtype of `Long`. However, object +[`Predef`](#the-predef-object) defines [views](07-implicits.html#views) +from every numeric value type to all higher-ranked numeric value types. +Therefore, lower-ranked types are implicitly converted to higher-ranked types +when required by the [context](06-expressions.html#implicit-conversions). + +Given two numeric value types ´S´ and ´T´, the _operation type_ of +´S´ and ´T´ is defined as follows: If both ´S´ and ´T´ are subrange +types then the operation type of ´S´ and ´T´ is `Int`. Otherwise +the operation type of ´S´ and ´T´ is the larger of the two types wrt +ranking. Given two numeric values ´v´ and ´w´ the operation type of +´v´ and ´w´ is the operation type of their run-time types. + +Any numeric value type ´T´ supports the following methods. + + * Comparison methods for equals (`==`), not-equals (`!=`), + less-than (`<`), greater-than (`>`), less-than-or-equals + (`<=`), greater-than-or-equals (`>=`), which each exist in 7 + overloaded alternatives. Each alternative takes a parameter of some + numeric value type. Its result type is type `Boolean`. The + operation is evaluated by converting the receiver and its argument to + their operation type and performing the given comparison operation of + that type. + * Arithmetic methods addition (`+`), subtraction (`-`), + multiplication (`*`), division (`/`), and remainder + (`%`), which each exist in 7 overloaded alternatives. Each + alternative takes a parameter of some numeric value type ´U´. Its + result type is the operation type of ´T´ and ´U´. The operation is + evaluated by converting the receiver and its argument to their + operation type and performing the given arithmetic operation of that + type. + * Parameterless arithmetic methods identity (`+`) and negation + (`-`), with result type ´T´. The first of these returns the + receiver unchanged, whereas the second returns its negation. + * Conversion methods `toByte`, `toShort`, `toChar`, + `toInt`, `toLong`, `toFloat`, `toDouble` which + convert the receiver object to the target type, using the rules of + Java's numeric type cast operation. The conversion might truncate the + numeric value (as when going from `Long` to `Int` or from + `Int` to `Byte`) or it might lose precision (as when going + from `Double` to `Float` or when converting between + `Long` and `Float`). + +Integer numeric value types support in addition the following operations: + + * Bit manipulation methods bitwise-and (`&`), bitwise-or + {`|`}, and bitwise-exclusive-or (`^`), which each exist in 5 + overloaded alternatives. Each alternative takes a parameter of some + integer numeric value type. Its result type is the operation type of + ´T´ and ´U´. The operation is evaluated by converting the receiver and + its argument to their operation type and performing the given bitwise + operation of that type. + + * A parameterless bit-negation method (`~`). Its result type is + the receiver type ´T´ or `Int`, whichever is larger. + The operation is evaluated by converting the receiver to the result + type and negating every bit in its value. + * Bit-shift methods left-shift (`<<`), arithmetic right-shift + (`>>`), and unsigned right-shift (`>>>`). Each of these + methods has two overloaded alternatives, which take a parameter ´n´ + of type `Int`, respectively `Long`. The result type of the + operation is the receiver type ´T´, or `Int`, whichever is larger. + The operation is evaluated by converting the receiver to the result + type and performing the specified shift by ´n´ bits. + +Numeric value types also implement operations `equals`, +`hashCode`, and `toString` from class `Any`. + +The `equals` method tests whether the argument is a numeric value +type. If this is true, it will perform the `==` operation which +is appropriate for that type. That is, the `equals` method of a +numeric value type can be thought of being defined as follows: + +```scala +def equals(other: Any): Boolean = other match { + case that: Byte => this == that + case that: Short => this == that + case that: Char => this == that + case that: Int => this == that + case that: Long => this == that + case that: Float => this == that + case that: Double => this == that + case _ => false +} +``` + +The `hashCode` method returns an integer hashcode that maps equal +numeric values to equal results. It is guaranteed to be the identity +for type `Int` and for all subrange types. + +The `toString` method displays its receiver as an integer or +floating point number. + +###### Example + +This is the signature of the numeric value type `Int`: + +```scala +package scala +abstract sealed class Int extends AnyVal { + def == (that: Double): Boolean // double equality + def == (that: Float): Boolean // float equality + def == (that: Long): Boolean // long equality + def == (that: Int): Boolean // int equality + def == (that: Short): Boolean // int equality + def == (that: Byte): Boolean // int equality + def == (that: Char): Boolean // int equality + /* analogous for !=, <, >, <=, >= */ + + def + (that: Double): Double // double addition + def + (that: Float): Double // float addition + def + (that: Long): Long // long addition + def + (that: Int): Int // int addition + def + (that: Short): Int // int addition + def + (that: Byte): Int // int addition + def + (that: Char): Int // int addition + /* analogous for -, *, /, % */ + + def & (that: Long): Long // long bitwise and + def & (that: Int): Int // int bitwise and + def & (that: Short): Int // int bitwise and + def & (that: Byte): Int // int bitwise and + def & (that: Char): Int // int bitwise and + /* analogous for |, ^ */ + + def << (cnt: Int): Int // int left shift + def << (cnt: Long): Int // long left shift + /* analogous for >>, >>> */ + + def unary_+ : Int // int identity + def unary_- : Int // int negation + def unary_~ : Int // int bitwise negation + + def toByte: Byte // convert to Byte + def toShort: Short // convert to Short + def toChar: Char // convert to Char + def toInt: Int // convert to Int + def toLong: Long // convert to Long + def toFloat: Float // convert to Float + def toDouble: Double // convert to Double +} +``` + +### Class `Boolean` + +Class `Boolean` has only two values: `true` and +`false`. It implements operations as given in the following +class definition. + +```scala +package scala +abstract sealed class Boolean extends AnyVal { + def && (p: => Boolean): Boolean = // boolean and + if (this) p else false + def || (p: => Boolean): Boolean = // boolean or + if (this) true else p + def & (x: Boolean): Boolean = // boolean strict and + if (this) x else false + def | (x: Boolean): Boolean = // boolean strict or + if (this) true else x + def == (x: Boolean): Boolean = // boolean equality + if (this) x else x.unary_! + def != (x: Boolean): Boolean = // boolean inequality + if (this) x.unary_! else x + def unary_!: Boolean = // boolean negation + if (this) false else true +} +``` + +The class also implements operations `equals`, `hashCode`, +and `toString` from class `Any`. + +The `equals` method returns `true` if the argument is the +same boolean value as the receiver, `false` otherwise. The +`hashCode` method returns a fixed, implementation-specific hash-code when invoked on `true`, +and a different, fixed, implementation-specific hash-code when invoked on `false`. The `toString` method +returns the receiver converted to a string, i.e. either `"true"` or `"false"`. + +### Class `Unit` + +Class `Unit` has only one value: `()`. It implements only +the three methods `equals`, `hashCode`, and `toString` +from class `Any`. + +The `equals` method returns `true` if the argument is the +unit value `()`, `false` otherwise. The +`hashCode` method returns a fixed, implementation-specific hash-code, +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 +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. + +### Class `String` + +Scala's `String` class is usually derived from the standard String +class of the underlying host system (and may be identified with +it). For Scala clients the class is taken to support in each case a +method + +```scala +def + (that: Any): String +``` + +which concatenates its left operand with the textual representation of its +right operand. + +### The `Tuple` classes + +Scala defines tuple classes `Tuple´n´` for ´n = 2 , \ldots , 22´. +These are defined as follows. + +```scala +package scala +case class Tuple´n´[+T_1, ..., +T_n](_1: T_1, ..., _´n´: T_´n´) { + def toString = "(" ++ _1 ++ "," ++ ´\ldots´ ++ "," ++ _´n´ ++ ")" +} +``` + +### The `Function` Classes + +Scala defines function classes `Function´n´` for ´n = 1 , \ldots , 22´. +These are defined as follows. + +```scala +package scala +trait Function´n´[-T_1, ..., -T_´n´, +R] { + def apply(x_1: T_1, ..., x_´n´: T_´n´): R + def toString = "" +} +``` + +The `PartialFunction` subclass of `Function1` represents functions that (indirectly) specify their domain. +Use the `isDefined` method to query whether the partial function is defined for a given input (i.e., whether the input is part of the function's domain). + +```scala +class PartialFunction[-A, +B] extends Function1[A, B] { + def isDefinedAt(x: A): Boolean +} +``` + +The implicitly imported [`Predef`](#the-predef-object) object defines the name +`Function` as an alias of `Function1`. + +### Class `Array` + +All operations on arrays desugar to the corresponding operations of the +underlying platform. Therefore, the following class definition is given for +informational purposes only: + +```scala +final class Array[T](_length: Int) +extends java.io.Serializable with java.lang.Cloneable { + def length: Int = ´\ldots´ + def apply(i: Int): T = ´\ldots´ + def update(i: Int, x: T): Unit = ´\ldots´ + override def clone(): Array[T] = ´\ldots´ +} +``` + +If ´T´ is not a type parameter or abstract type, the type `Array[T]` +is represented as the array type `|T|[]` in the +underlying host system, where `|T|` is the erasure of `T`. +If ´T´ is a type parameter or abstract type, a different representation might be +used (it is `Object` on the Java platform). + +#### Operations + +`length` returns the length of the array, `apply` means subscripting, +and `update` means element update. + +Because of the syntactic sugar for `apply` and `update` operations, +we have the following correspondences between Scala and Java code for +operations on an array `xs`: + +|_Scala_ |_Java_ | +|------------------|------------| +|`xs.length` |`xs.length` | +|`xs(i)` |`xs[i]` | +|`xs(i) = e` |`xs[i] = e` | + +Two implicit conversions exist in `Predef` that are frequently applied to arrays: +a conversion to `scala.collection.mutable.ArrayOps` and a conversion to +`scala.collection.mutable.ArraySeq` (a subtype of `scala.collection.Seq`). + +Both types make many of the standard operations found in the Scala +collections API available. The conversion to `ArrayOps` is temporary, as all operations +defined on `ArrayOps` return a value of type `Array`, while the conversion to `ArraySeq` +is permanent as all operations return a value of type `ArraySeq`. +The conversion to `ArrayOps` takes priority over the conversion to `ArraySeq`. + +Because of the tension between parametrized types in Scala and the ad-hoc +implementation of arrays in the host-languages, some subtle points +need to be taken into account when dealing with arrays. These are +explained in the following. + +#### Variance + +Unlike arrays in Java, arrays in Scala are _not_ +co-variant; That is, ´S <: T´ does not imply +`Array[´S´] ´<:´ Array[´T´]` in Scala. +However, it is possible to cast an array +of ´S´ to an array of ´T´ if such a cast is permitted in the host +environment. + +For instance `Array[String]` does not conform to +`Array[Object]`, even though `String` conforms to `Object`. +However, it is possible to cast an expression of type +`Array[String]` to `Array[Object]`, and this +cast will succeed without raising a `ClassCastException`. Example: + +```scala +val xs = new Array[String](2) +// val ys: Array[Object] = xs // **** error: incompatible types +val ys: Array[Object] = xs.asInstanceOf[Array[Object]] // OK +``` + +The instantiation of an array with a polymorphic element type ´T´ requires +information about type ´T´ at runtime. +This information is synthesized by adding a [context bound](07-implicits.html#context-bounds-and-view-bounds) +of `scala.reflect.ClassTag` to type ´T´. +An example is the +following implementation of method `mkArray`, which creates +an array of an arbitrary type ´T´, given a sequence of ´T´`s which +defines its elements: + +```scala +import reflect.ClassTag +def mkArray[T : ClassTag](elems: Seq[T]): Array[T] = { + val result = new Array[T](elems.length) + var i = 0 + for (elem <- elems) { + result(i) = elem + i += 1 + } + result +} +``` + +If type ´T´ is a type for which the host platform offers a specialized array +representation, this representation is used. + +###### Example +On the Java Virtual Machine, an invocation of `mkArray(List(1,2,3))` +will return a primitive array of `int`s, written as `int[]` in Java. + +#### Companion object + +`Array`'s companion object provides various factory methods for the +instantiation of single- and multi-dimensional arrays, an extractor method +[`unapplySeq`](08-pattern-matching.html#extractor-patterns) which enables pattern matching +over arrays and additional utility methods: + +```scala +package scala +object Array { + /** copies array elements from `src` to `dest`. */ + def copy(src: AnyRef, srcPos: Int, + dest: AnyRef, destPos: Int, length: Int): Unit = ´\ldots´ + + /** Returns an array of length 0 */ + def empty[T: ClassTag]: Array[T] = + + /** Create an array with given elements. */ + def apply[T: ClassTag](xs: T*): Array[T] = ´\ldots´ + + /** Creates array with given dimensions */ + def ofDim[T: ClassTag](n1: Int): Array[T] = ´\ldots´ + /** Creates a 2-dimensional array */ + def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = ´\ldots´ + ´\ldots´ + + /** Concatenate all argument arrays into a single array. */ + def concat[T: ClassTag](xss: Array[T]*): Array[T] = ´\ldots´ + + /** Returns an array that contains the results of some element computation a number + * of times. */ + def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = ´\ldots´ + /** Returns a two-dimensional array that contains the results of some element + * computation a number of times. */ + def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = ´\ldots´ + ´\ldots´ + + /** Returns an array containing values of a given function over a range of integer + * values starting from 0. */ + def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = ´\ldots´ + /** Returns a two-dimensional array containing values of a given function + * over ranges of integer values starting from `0`. */ + def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = ´\ldots´ + ´\ldots´ + + /** Returns an array containing a sequence of increasing integers in a range. */ + def range(start: Int, end: Int): Array[Int] = ´\ldots´ + /** Returns an array containing equally spaced values in some integer interval. */ + def range(start: Int, end: Int, step: Int): Array[Int] = ´\ldots´ + + /** Returns an array containing repeated applications of a function to a start value. */ + def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = ´\ldots´ + + /** Enables pattern matching over arrays */ + def unapplySeq[A](x: Array[A]): Option[IndexedSeq[A]] = Some(x) +} +``` + +## Class Node + +```scala +package scala.xml + +trait Node { + + /** the label of this node */ + def label: String + + /** attribute axis */ + def attribute: Map[String, String] + + /** child axis (all children of this node) */ + def child: Seq[Node] + + /** descendant axis (all descendants of this node) */ + def descendant: Seq[Node] = child.toList.flatMap { + x => x::x.descendant.asInstanceOf[List[Node]] + } + + /** descendant axis (all descendants of this node) */ + def descendant_or_self: Seq[Node] = this::child.toList.flatMap { + x => x::x.descendant.asInstanceOf[List[Node]] + } + + override def equals(x: Any): Boolean = x match { + case that:Node => + that.label == this.label && + that.attribute.sameElements(this.attribute) && + that.child.sameElements(this.child) + case _ => false + } + + /** XPath style projection function. Returns all children of this node + * that are labeled with 'that'. The document order is preserved. + */ + def \(that: Symbol): NodeSeq = { + new NodeSeq({ + that.name match { + case "_" => child.toList + case _ => + var res:List[Node] = Nil + for (x <- child.elements if x.label == that.name) { + res = x::res + } + res.reverse + } + }) + } + + /** XPath style projection function. Returns all nodes labeled with the + * name 'that' from the 'descendant_or_self' axis. Document order is preserved. + */ + def \\(that: Symbol): NodeSeq = { + new NodeSeq( + that.name match { + case "_" => this.descendant_or_self + case _ => this.descendant_or_self.asInstanceOf[List[Node]]. + filter(x => x.label == that.name) + }) + } + + /** hashcode for this XML node */ + override def hashCode = + Utility.hashCode(label, attribute.toList.hashCode, child) + + /** string representation of this node */ + override def toString = Utility.toXML(this) + +} +``` + +## The `Predef` Object + +The `Predef` object defines standard functions and type aliases +for Scala programs. It is implicitly imported, as described in +[the chapter on name binding](02-identifiers-names-and-scopes.html), +so that all its defined members are available without qualification. +Its definition for the JVM environment conforms to the following signature: + +```scala +package scala +object Predef { + + // classOf --------------------------------------------------------- + + /** Returns the runtime representation of a class type. */ + def classOf[T]: Class[T] = null + // this is a dummy, classOf is handled by compiler. + + // valueOf ----------------------------------------------------------- + + /** Retrieve the single value of a type with a unique inhabitant. */ + @inline def valueOf[T](implicit vt: ValueOf[T]): T {} = vt.value + // instances of the ValueOf type class are provided by the compiler. + + // Standard type aliases --------------------------------------------- + + type String = java.lang.String + type Class[T] = java.lang.Class[T] + + // Miscellaneous ----------------------------------------------------- + + type Function[-A, +B] = Function1[A, B] + + type Map[A, +B] = collection.immutable.Map[A, B] + type Set[A] = collection.immutable.Set[A] + + val Map = collection.immutable.Map + val Set = collection.immutable.Set + + // Manifest types, companions, and incantations for summoning --------- + + type ClassManifest[T] = scala.reflect.ClassManifest[T] + type Manifest[T] = scala.reflect.Manifest[T] + type OptManifest[T] = scala.reflect.OptManifest[T] + val ClassManifest = scala.reflect.ClassManifest + val Manifest = scala.reflect.Manifest + val NoManifest = scala.reflect.NoManifest + + def manifest[T](implicit m: Manifest[T]) = m + def classManifest[T](implicit m: ClassManifest[T]) = m + def optManifest[T](implicit m: OptManifest[T]) = m + + // Minor variations on identity functions ----------------------------- + def identity[A](x: A): A = x + def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world + @inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements + + // Asserts, Preconditions, Postconditions ----------------------------- + + def assert(assertion: Boolean) { + if (!assertion) + throw new java.lang.AssertionError("assertion failed") + } + + def assert(assertion: Boolean, message: => Any) { + if (!assertion) + throw new java.lang.AssertionError("assertion failed: " + message) + } + + def assume(assumption: Boolean) { + if (!assumption) + throw new IllegalArgumentException("assumption failed") + } + + def assume(assumption: Boolean, message: => Any) { + if (!assumption) + throw new IllegalArgumentException(message.toString) + } + + def require(requirement: Boolean) { + if (!requirement) + throw new IllegalArgumentException("requirement failed") + } + + def require(requirement: Boolean, message: => Any) { + if (!requirement) + throw new IllegalArgumentException("requirement failed: "+ message) + } +``` + +```scala + // Printing and reading ----------------------------------------------- + + def print(x: Any) = Console.print(x) + def println() = Console.println() + def println(x: Any) = Console.println(x) + def printf(text: String, xs: Any*) = Console.printf(text.format(xs: _*)) + + // Implicit conversions ------------------------------------------------ + + ... +} +``` + +### Predefined Implicit Definitions + +The `Predef` object also contains a number of implicit definitions, which are available by default (because `Predef` is implicitly imported). +Implicit definitions come in two priorities. High-priority implicits are defined in the `Predef` class itself whereas low priority implicits are defined in a class inherited by `Predef`. The rules of +static [overloading resolution](06-expressions.html#overloading-resolution) +stipulate that, all other things being equal, implicit resolution +prefers high-priority implicits over low-priority ones. + +The available low-priority implicits include definitions falling into the following categories. + +1. For every primitive type, a wrapper that takes values of that type + to instances of a `runtime.Rich*` class. For instance, values of type `Int` + can be implicitly converted to instances of class `runtime.RichInt`. + +1. For every array type with elements of primitive type, a wrapper that + takes the arrays of that type to instances of a `ArraySeq` class. For instance, values of type `Array[Float]` can be implicitly converted to instances of class `ArraySeq[Float]`. + There are also generic array wrappers that take elements + of type `Array[T]` for arbitrary `T` to `ArraySeq`s. + +1. An implicit conversion from `String` to `WrappedString`. + +The available high-priority implicits include definitions falling into the following categories. + + * An implicit wrapper that adds `ensuring` methods + with the following overloaded variants to type `Any`. + + ```scala + def ensuring(cond: Boolean): A = { assert(cond); x } + def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x } + def ensuring(cond: A => Boolean): A = { assert(cond(x)); x } + def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x } + ``` + + * An implicit wrapper that adds a `->` method with the following implementation + to type `Any`. + + ```scala + def -> [B](y: B): (A, B) = (x, y) + ``` + + * For every array type with elements of primitive type, a wrapper that + takes the arrays of that type to instances of a `runtime.ArrayOps` + class. For instance, values of type `Array[Float]` can be implicitly + converted to instances of class `runtime.ArrayOps[Float]`. There are + also generic array wrappers that take elements of type `Array[T]` for + arbitrary `T` to `ArrayOps`s. + + * An implicit wrapper that adds `+` and `formatted` method with the following + implementations to type `Any`. + + ```scala + def +(other: String) = String.valueOf(self) + other + def formatted(fmtstr: String): String = fmtstr format self + ``` + + * Numeric primitive conversions that implement the transitive closure of the + following mappings: + + ``` + Byte -> Short + Short -> Int + Char -> Int + Int -> Long + Long -> Float + Float -> Double + ``` + + * Boxing and unboxing conversions between primitive types and their boxed + versions: + + ``` + Byte <-> java.lang.Byte + Short <-> java.lang.Short + Char <-> java.lang.Character + Int <-> java.lang.Integer + Long <-> java.lang.Long + Float <-> java.lang.Float + Double <-> java.lang.Double + Boolean <-> java.lang.Boolean + ``` + + * An implicit definition that generates instances of type `T <:< T`, for + any type `T`. Here, `<:<` is a class defined as follows. + + ```scala + sealed abstract class <:<[-From, +To] extends (From => To) + ``` + + Implicit parameters of `<:<` types are typically used to implement type constraints. diff --git a/docs/_spec/13-syntax-summary.md b/docs/_spec/13-syntax-summary.md new file mode 100644 index 000000000000..6ece538e2ff1 --- /dev/null +++ b/docs/_spec/13-syntax-summary.md @@ -0,0 +1,330 @@ +--- +title: Syntax Summary +layout: default +chapter: 13 +--- + +# Syntax Summary + +The following descriptions of Scala tokens uses literal characters `‘c’` when referring to the ASCII fragment `\u0000` – `\u007F`. + +## Lexical Syntax + +The lexical syntax of Scala is given by the following grammar in EBNF form: + +```ebnf +whiteSpace ::= ‘\u0020’ | ‘\u0009’ | ‘\u000D’ | ‘\u000A’ +upper ::= ‘A’ | … | ‘Z’ | ‘$’ and any character in Unicode categories Lu, Lt or Nl, + and any character in Unicode categories Lo and Lm that doesn't have + contributory property Other_Lowercase +lower ::= ‘a’ | … | ‘z’ | ‘_’ and any character in Unicode category Ll, + and any character in Unicode categories Lo or Lm that has contributory + property Other_Lowercase +letter ::= upper | lower +digit ::= ‘0’ | … | ‘9’ +paren ::= ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ +delim ::= ‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ +opchar ::= ‘!’ | ‘#’ | ‘%’ | ‘&’ | ‘*’ | ‘+’ | ‘-’ | ‘/’ | ‘:’ | + ‘<’ | ‘=’ | ‘>’ | ‘?’ | ‘@’ | ‘\’ | ‘^’ | ‘|’ | ‘~’ + and any character in Unicode categories Sm or So +printableChar ::= all characters in [\u0020, \u007E] inclusive +UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit +hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ +charEscapeSeq ::= ‘\’ (‘b’ | ‘t’ | ‘n’ | ‘f’ | ‘r’ | ‘"’ | ‘'’ | ‘\’) +escapeSeq ::= UnicodeEscape | charEscapeSeq +op ::= opchar {opchar} +varid ::= lower idrest +boundvarid ::= varid + | ‘`’ varid ‘`’ +plainid ::= upper idrest + | varid + | op +id ::= plainid + | ‘`’ { charNoBackQuoteOrNewline | escapeSeq } ‘`’ +idrest ::= {letter | digit} [‘_’ op] + +integerLiteral ::= (decimalNumeral | hexNumeral) [‘L’ | ‘l’] +decimalNumeral ::= digit {digit} +hexNumeral ::= ‘0’ (‘x’ | ‘X’) hexDigit {hexDigit} + +floatingPointLiteral + ::= digit {digit} ‘.’ digit {digit} [exponentPart] [floatType] + | ‘.’ digit {digit} [exponentPart] [floatType] + | digit {digit} exponentPart [floatType] + | digit {digit} [exponentPart] floatType +exponentPart ::= (‘E’ | ‘e’) [‘+’ | ‘-’] digit {digit} +floatType ::= ‘F’ | ‘f’ | ‘D’ | ‘d’ + +booleanLiteral ::= ‘true’ | ‘false’ + +characterLiteral ::= ‘'’ (charNoQuoteOrNewline | escapeSeq) ‘'’ + +stringLiteral ::= ‘"’ {stringElement} ‘"’ + | ‘"""’ multiLineChars ‘"""’ +stringElement ::= charNoDoubleQuoteOrNewline + | escapeSeq +multiLineChars ::= {[‘"’] [‘"’] charNoDoubleQuote} {‘"’} + +interpolatedString + ::= alphaid ‘"’ {[‘\’] interpolatedStringPart | ‘\\’ | ‘\"’} ‘"’ + | alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘\$’) | escape} {‘"’} ‘"""’ +interpolatedStringPart + ::= printableChar \ (‘"’ | ‘$’ | ‘\’) | escape +escape ::= ‘\$\$’ + | ‘\$"’ + | ‘\$’ alphaid + | ‘\$’ BlockExpr +alphaid ::= upper idrest + | varid + +symbolLiteral ::= ‘'’ plainid + +comment ::= ‘/*’ “any sequence of characters; nested comments are allowed” ‘*/’ + | ‘//’ “any sequence of characters up to end of line” + +nl ::= ´\mathit{“new line character”}´ +semi ::= ‘;’ | nl {nl} +``` + +## Context-free Syntax + +The context-free syntax of Scala is given by the following EBNF +grammar: + +```ebnf + Literal ::= [‘-’] integerLiteral + | [‘-’] floatingPointLiteral + | booleanLiteral + | characterLiteral + | stringLiteral + | interpolatedString + | symbolLiteral + | ‘null’ + + QualId ::= id {‘.’ id} + ids ::= id {‘,’ id} + + Path ::= StableId + | [id ‘.’] ‘this’ + StableId ::= id + | Path ‘.’ id + | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id + ClassQualifier ::= ‘[’ id ‘]’ + + Type ::= FunctionArgTypes ‘=>’ Type + | InfixType [ExistentialClause] + FunctionArgTypes ::= InfixType + | ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’ + ExistentialClause ::= ‘forSome’ ‘{’ ExistentialDcl {semi ExistentialDcl} ‘}’ + ExistentialDcl ::= ‘type’ TypeDcl + | ‘val’ ValDcl + InfixType ::= CompoundType {id [nl] CompoundType} + CompoundType ::= AnnotType {‘with’ AnnotType} [Refinement] + | Refinement + AnnotType ::= SimpleType {Annotation} + SimpleType ::= SimpleType TypeArgs + | SimpleType ‘#’ id + | StableId + | Path ‘.’ ‘type’ + | ‘(’ Types ‘)’ + TypeArgs ::= ‘[’ Types ‘]’ + Types ::= Type {‘,’ Type} + Refinement ::= [nl] ‘{’ RefineStat {semi RefineStat} ‘}’ + RefineStat ::= Dcl + | ‘type’ TypeDef + | + TypePat ::= Type + + Ascription ::= ‘:’ InfixType + | ‘:’ Annotation {Annotation} + | ‘:’ ‘_’ ‘*’ + + Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr + | Expr1 + Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] + | ‘while’ ‘(’ Expr ‘)’ {nl} Expr + | ‘try’ Expr [‘catch’ Expr] [‘finally’ Expr] + | ‘do’ Expr [semi] ‘while’ ‘(’ Expr ‘)’ + | ‘for’ (‘(’ Enumerators ‘)’ | ‘{’ Enumerators ‘}’) {nl} [‘yield’] Expr + | ‘throw’ Expr + | ‘return’ [Expr] + | [SimpleExpr ‘.’] id ‘=’ Expr + | PrefixOperator SimpleExpr ‘=’ Expr + | SimpleExpr1 ArgumentExprs ‘=’ Expr + | PostfixExpr + | PostfixExpr Ascription + | PostfixExpr ‘match’ ‘{’ CaseClauses ‘}’ + PostfixExpr ::= InfixExpr [id [nl]] + InfixExpr ::= PrefixExpr + | InfixExpr id [nl] InfixExpr + PrefixExpr ::= [PrefixOperator] SimpleExpr + PrefixOperator ::= ‘-’ | ‘+’ | ‘~’ | ‘!’ + SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody) + | BlockExpr + | SimpleExpr1 [‘_’] + SimpleExpr1 ::= Literal + | Path + | ‘_’ + | ‘(’ [Exprs] ‘)’ + | SimpleExpr ‘.’ id + | SimpleExpr TypeArgs + | SimpleExpr1 ArgumentExprs + | XmlExpr + Exprs ::= Expr {‘,’ Expr} + ArgumentExprs ::= ‘(’ [Exprs] ‘)’ + | ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ‘)’ + | [nl] BlockExpr + BlockExpr ::= ‘{’ CaseClauses ‘}’ + | ‘{’ Block ‘}’ + Block ::= BlockStat {semi BlockStat} [ResultExpr] + BlockStat ::= Import + | {Annotation} [‘implicit’] [‘lazy’] Def + | {Annotation} {LocalModifier} TmplDef + | Expr1 + | + ResultExpr ::= Expr1 + | (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block + + Enumerators ::= Generator {semi Generator} + Generator ::= [‘case’] Pattern1 ‘<-’ Expr {[semi] Guard | semi Pattern1 ‘=’ Expr} + + CaseClauses ::= CaseClause { CaseClause } + CaseClause ::= ‘case’ Pattern [Guard] ‘=>’ Block + Guard ::= ‘if’ PostfixExpr + + Pattern ::= Pattern1 { ‘|’ Pattern1 } + Pattern1 ::= boundvarid ‘:’ TypePat + | ‘_’ ‘:’ TypePat + | Pattern2 + Pattern2 ::= id [‘@’ Pattern3] + | Pattern3 + Pattern3 ::= SimplePattern + | SimplePattern { id [nl] SimplePattern } + SimplePattern ::= ‘_’ + | varid + | Literal + | StableId + | StableId ‘(’ [Patterns] ‘)’ + | StableId ‘(’ [Patterns ‘,’] [id ‘@’] ‘_’ ‘*’ ‘)’ + | ‘(’ [Patterns] ‘)’ + | XmlPattern + Patterns ::= Pattern [‘,’ Patterns] + | ‘_’ ‘*’ + + TypeParamClause ::= ‘[’ VariantTypeParam {‘,’ VariantTypeParam} ‘]’ + FunTypeParamClause::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’ + VariantTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeParam + TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] + {‘<%’ Type} {‘:’ Type} + ParamClauses ::= {ParamClause} [[nl] ‘(’ ‘implicit’ Params ‘)’] + ParamClause ::= [nl] ‘(’ [Params] ‘)’ + Params ::= Param {‘,’ Param} + Param ::= {Annotation} id [‘:’ ParamType] [‘=’ Expr] + ParamType ::= Type + | ‘=>’ Type + | Type ‘*’ + ClassParamClauses ::= {ClassParamClause} + [[nl] ‘(’ ‘implicit’ ClassParams ‘)’] + ClassParamClause ::= [nl] ‘(’ [ClassParams] ‘)’ + ClassParams ::= ClassParam {‘,’ ClassParam} + ClassParam ::= {Annotation} {Modifier} [(‘val’ | ‘var’)] + id ‘:’ ParamType [‘=’ Expr] + Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’ + Binding ::= (id | ‘_’) [‘:’ Type] + + Modifier ::= LocalModifier + | AccessModifier + | ‘override’ + LocalModifier ::= ‘abstract’ + | ‘final’ + | ‘sealed’ + | ‘implicit’ + | ‘lazy’ + AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier] + AccessQualifier ::= ‘[’ (id | ‘this’) ‘]’ + + Annotation ::= ‘@’ SimpleType {ArgumentExprs} + ConstrAnnotation ::= ‘@’ SimpleType ArgumentExprs + + TemplateBody ::= [nl] ‘{’ [SelfType] TemplateStat {semi TemplateStat} ‘}’ + TemplateStat ::= Import + | {Annotation [nl]} {Modifier} Def + | {Annotation [nl]} {Modifier} Dcl + | Expr + | + SelfType ::= id [‘:’ Type] ‘=>’ + | ‘this’ ‘:’ Type ‘=>’ + + Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} + ImportExpr ::= StableId ‘.’ (id | ‘_’ | ImportSelectors) + ImportSelectors ::= ‘{’ {ImportSelector ‘,’} (ImportSelector | ‘_’) ‘}’ + ImportSelector ::= id [‘=>’ id | ‘=>’ ‘_’] + + Dcl ::= ‘val’ ValDcl + | ‘var’ VarDcl + | ‘def’ FunDcl + | ‘type’ {nl} TypeDcl + + ValDcl ::= ids ‘:’ Type + VarDcl ::= ids ‘:’ Type + FunDcl ::= FunSig [‘:’ Type] + FunSig ::= id [FunTypeParamClause] ParamClauses + TypeDcl ::= id [TypeParamClause] [‘>:’ Type] [‘<:’ Type] + + PatVarDef ::= ‘val’ PatDef + | ‘var’ VarDef + Def ::= PatVarDef + | ‘def’ FunDef + | ‘type’ {nl} TypeDef + | TmplDef + PatDef ::= Pattern2 {‘,’ Pattern2} [‘:’ Type] ‘=’ Expr + VarDef ::= PatDef + | ids ‘:’ Type ‘=’ ‘_’ + FunDef ::= FunSig [‘:’ Type] ‘=’ Expr + | FunSig [nl] ‘{’ Block ‘}’ + | ‘this’ ParamClause ParamClauses + (‘=’ ConstrExpr | [nl] ConstrBlock) + TypeDef ::= id [TypeParamClause] ‘=’ Type + + TmplDef ::= [‘case’] ‘class’ ClassDef + | [‘case’] ‘object’ ObjectDef + | ‘trait’ TraitDef + ClassDef ::= id [TypeParamClause] {ConstrAnnotation} [AccessModifier] + ClassParamClauses ClassTemplateOpt + TraitDef ::= id [TypeParamClause] TraitTemplateOpt + ObjectDef ::= id ClassTemplateOpt + ClassTemplateOpt ::= ‘extends’ ClassTemplate | [[‘extends’] TemplateBody] + TraitTemplateOpt ::= ‘extends’ TraitTemplate | [[‘extends’] TemplateBody] + ClassTemplate ::= [EarlyDefs] ClassParents [TemplateBody] + TraitTemplate ::= [EarlyDefs] TraitParents [TemplateBody] + ClassParents ::= Constr {‘with’ AnnotType} + TraitParents ::= AnnotType {‘with’ AnnotType} + Constr ::= AnnotType {ArgumentExprs} + EarlyDefs ::= ‘{’ [EarlyDef {semi EarlyDef}] ‘}’ ‘with’ + EarlyDef ::= {Annotation [nl]} {Modifier} PatVarDef + + ConstrExpr ::= SelfInvocation + | ConstrBlock + ConstrBlock ::= ‘{’ SelfInvocation {semi BlockStat} ‘}’ + SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} + + TopStatSeq ::= TopStat {semi TopStat} + TopStat ::= {Annotation [nl]} {Modifier} TmplDef + | Import + | Packaging + | PackageObject + | + Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ + PackageObject ::= ‘package’ ‘object’ ObjectDef + + CompilationUnit ::= {‘package’ QualId semi} TopStatSeq +``` + + diff --git a/docs/_spec/14-references.md b/docs/_spec/14-references.md new file mode 100644 index 000000000000..cc088dfcae11 --- /dev/null +++ b/docs/_spec/14-references.md @@ -0,0 +1,207 @@ +--- +title: References +layout: default +chapter: 14 +--- + +# References + +TODO (see comments in markdown source) + + diff --git a/docs/_spec/15-changelog.md b/docs/_spec/15-changelog.md new file mode 100644 index 000000000000..5d24511ff1cb --- /dev/null +++ b/docs/_spec/15-changelog.md @@ -0,0 +1,847 @@ +--- +title: Changelog +layout: default +chapter: 15 +--- + +# Changelog + +This changelog was no longer maintained after version 2.8.0. + +A pull request updating this chapter to list the most significant +changes made in more recent Scala versions would be highly welcome. + +Many language changes, especially larger ones, are documented in SIP +(Scala Improvement Process) proposals. Most proposals that were +accepted and implemented have not merged into the main spec. Pull +requests that merge SIPs into the main spec are also highly welcome. + +To find out what has changed in Scala 2 since 2.8.0, you can consult +the following sources: + +* Scala release notes (recent versions): https://github.com/scala/scala/releases +* Scala release notes (older versions): https://scala-lang.org/blog/announcements/ +* Scala release notes (even older versions): presumably findable via search engine +* Spec changelog in version control: https://github.com/scala/scala/commits/2.13.x/spec +* SIPs: https://docs.scala-lang.org/sips/all.html + +## Changes in Version 2.8.0 + +Trailing commas in expression, argument, type or pattern sequences are +no longer supported. + +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 accidental [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 function 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 a [companion extractor object for every case class] +(05-classes-and-objects.html#case-classes) now. 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] +(04-basic-declarations-and-definitions.html#variable-declarations-and-definitions), +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`](05-classes-and-objects.html#templates). 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](03-types.html#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`](04-basic-declarations-and-definitions.html#value-declarations-and-definitions). +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] +(03-types.html#compound-types). 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 + +_Implemented by Adriaan Moors_ + +[Type parameters](04-basic-declarations-and-definitions.html#type-parameters) +and abstract +[type members](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases) can now also abstract over [type constructors](03-types.html#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 + +[Early object initialization](05-classes-and-objects.html#early-definitions) +makes it 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](06-expressions.html#for-comprehensions-and-for-loops) +has changed. +In the new syntax, generators do not start with a `val` anymore, but filters +start with an `if` (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] +(06-expressions.html#placeholder-syntax-for-anonymous-functions) 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](06-expressions.html#method-values) +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] +(08-pattern-matching.html#pattern-matching-anonymous-functions) +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]) = + (xs zip ys).foldLeft(0.0) { + 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](05-classes-and-objects.html#modifiers). +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 [`private` or `protected`] +(05-classes-and-objects.html#class-definitions). +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*](11-annotations.html). 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](05-classes-and-objects.html#inheritance-closure) +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](05-classes-and-objects.html#templates) `this`. For instance, in + + class C { self: D => + ... + } + +the name `self` is introduced as an alias for `this` within `C` and the +[self type](05-classes-and-objects.html#class-definitions) of `C` is +assumed to be `D`. 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] +(06-expressions.html#assignment-operators). 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 +`unapply` methods in [extractor objects](08-pattern-matching.html#extractor-patterns). +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 `apply` method is used to build even numbers. + +- The `unapply` method is used to decompose an even number; it is in a sense + the reverse of `apply`. `unapply` methods return option types: + `Some(...)` for a match that succeeds, `None` for a match that fails. + Pattern variables are returned as the elements of `Some`. + If there are several variables, they are grouped in a tuple. + +In the second-to-last line, `Twice`’s method is used to construct a number `x`. +In the last line, `x` is tested against the pattern `Twice(n)`. +This pattern succeeds for even numbers and assigns to the variable `n` one half +of the number that was tested. +The pattern match makes use of the `unapply` method of object `Twice`. +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](06-expressions.html#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](06-expressions.html#infix-operations). 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`](11-annotations.html#deprecation-annotations) +is available. 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 [methods returning `unit`] +(04-basic-declarations-and-definitions.html#procedures) has been introduced. +Scala now allows the following shorthands: + +`def f(params)` **for** `def f(params): unit` +`def f(params) { ... }` **for** `def f(params): unit = { ... }` + +#### Type Patterns + +The [syntax of types in patterns](08-pattern-matching.html#type-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[]`](05-classes-and-objects.html#protected). +In particular, one can now simulate package protected access as in Java writing + + protected[P] def X ... + +where would name the package containing `X`. + +#### Relaxation of Private Access + +[Private members of a class](05-classes-and-objects.html#private) can now be +referenced from the companion module of the class and vice versa. + +#### Implicit Lookup + +The lookup method for [implicit definitions](07-implicits.html#implicit-parameters) +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 `HashSet`, +`List`, `Int`, and `String`. Before, it was just the static part of . + +#### Tightened Pattern Match + +A typed [pattern match with a singleton type `p.type`](08-pattern-matching.html#type-patterns) +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 “q”. Before, the +singleton types were erased to `List`, 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] +(01-lexical-syntax.html#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](06-expressions.html#anonymous-functions) +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](06-expressions.html#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](01-lexical-syntax.html#identifiers): + + implicit match requires + +#### Newlines as Statement Separators + +[Newlines](https://www.scala-lang.org/files/archive/spec/2.11/) +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](05-classes-and-objects.html#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 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](06-expressions.html#for-comprehensions-and-for-loops) +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] +(06-expressions.html#method-conversions) 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_](05-classes-and-objects.html#class-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](05-classes-and-objects.html#class-definitions) +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](05-classes-and-objects.html#modifiers) +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] +(05-classes-and-objects.html#templates) 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. + +#### Implicit Parameters + +Views in Scala 1.0 have been replaced by the more general concept of +[implicit parameters](07-implicits.html#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] +(08-pattern-matching.html#pattern-matching-expressions). +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. diff --git a/docs/_spec/README.md b/docs/_spec/README.md new file mode 100644 index 000000000000..d748dddedfd2 --- /dev/null +++ b/docs/_spec/README.md @@ -0,0 +1,45 @@ +# Scala Language Reference + +First of all, the language specification is meant to be correct, precise and clear. + +Second, editing, previewing and generating output for the markdown should be simple and easy. + +Third, we'd like to support different output formats. An html page per chapter with MathJax seems like a good start, as it satisfies the second requirement, and enables the first one. + +## Editing + +We are using Jekyll and [Redcarpet](https://github.com/vmg/redcarpet) to generate the html. + +Check `Gemfile` for the current versions. + +We aim to track the configuration GitHub Pages uses but differences may arise as GitHub Pages evolves. + +## Building + +Travis CI builds the spec automatically after every merged pull release and publishes to https://www.scala-lang.org/files/archive/spec/2.13/. + +To preview locally, run the following commands in the root of your checkout scala/scala: +`bundle install` to install Jekyll and `bundle exec jekyll serve -d build/spec/ -s spec/ -w --baseurl=""` to start it, +and open http://0.0.0.0:4000/ to view the spec. Jekyll will rebuild as you edit the markdown, but make sure to restart it when you change `_config.yml`. + +## General Advice for editors + +- All files must be saved as UTF-8: ensure your editors are configured appropriately. +- Use of the appropriate unicode characters instead of the latex modifiers for accents, etc. is necessary. For example, é instead of `\'e`. +- MathJAX errors will appear within the rendered DOM as span elements with class `mtext` and style attribute `color: red` applied. It is possible to search for this combination in the development tools of the browser of your choice. In chrome, CTRL+F / CMD+F within the inspect element panel allows you to do this. + +### Macro replacements: + +- While MathJAX just support LaTeX style command definition, it is recommended to not use this as it will likely cause issues with preparing the document for PDF or ebook distribution. +- `\SS` (which I could not find defined within the latex source) seems to be closest to `\mathscr{S}` +- `\TYPE` is equivalent to `\boldsymbol{type}' +- As MathJAX has no support for slanted font (latex command \sl), so in all instances this should be replaced with \mathit{} +- The macro \U{ABCD} used for unicode character references can be replaced with \\uABCD. +- The macro \URange{ABCD}{DCBA} used for unicode character ranges can be replaced with \\uABCD-\\uDBCA. +- The macro \commadots can be replaced with ` , … , `. +- There is no adequate replacement for `\textsc{...}` (small caps) in pandoc markdown. While unicode contains a number of small capital letters, it is notably missing Q and X as these glyphs are intended for phonetic spelling, therefore these cannot be reliably used. For now, the best option is to use underscore emphasis and capitalise the text manually, `_LIKE THIS_`. + +### Unicode Character replacements + +- The unicode left and right single quotation marks (‘ and ’ (U+2018 and U+2019, respectively)) have been used in place of ` and ', where the quotation marks are intended to be paired. These can be typed on a mac using Option+] for a left quote and Option+Shift+] for the right quote. +- Similarly for left and right double quotation marks (“ and ” (U+201C and U+201D, respectively)) in place of ". These can be typed on a mac using Option+[ and Option+Shift+]. diff --git a/docs/_spec/_config.yml b/docs/_spec/_config.yml new file mode 100644 index 000000000000..bd1f691c65d0 --- /dev/null +++ b/docs/_spec/_config.yml @@ -0,0 +1,11 @@ +baseurl: /files/archive/spec/2.13 +latestScalaVersion: 2.13 +thisScalaVersion: 2.13 +versionCompareMessage: "an upcoming" +safe: true +lsi: false +highlighter: false +markdown: redcarpet +encoding: utf-8 +redcarpet: + extensions: ["no_intra_emphasis", "fenced_code_blocks", "autolink", "tables", "with_toc_data", "strikethrough", "lax_spacing", "space_after_headers", "superscript", "footnotes"] diff --git a/docs/_spec/_includes/numbering.css b/docs/_spec/_includes/numbering.css new file mode 100644 index 000000000000..2a22ce28b558 --- /dev/null +++ b/docs/_spec/_includes/numbering.css @@ -0,0 +1,60 @@ +h1 { + /* must reset here */ + counter-reset: chapter {{ page.chapter }}; +} +h1:before { + /* and must reset again here */ + counter-reset: chapter {{ page.chapter }}; + content: "Chapter " counter(chapter); + display: block; +} + +h2 { + /* must increment here */ + counter-increment: section; + counter-reset: subsection; +} +h2:before { + /* and must reset again here */ + counter-reset: chapter {{ page.chapter }}; + + content: counter(chapter) "." counter(section) ; + display: inline; + margin-right: 1em; +} +h2:after { + /* can only have one counter-reset per tag, so can't do it in h2/h2:before... */ + counter-reset: example; +} + +h3 { + /* must increment here */ + counter-increment: subsection; +} +h3:before { + /* and must reset again here */ + counter-reset: chapter {{ page.chapter }}; + + content: counter(chapter) "." counter(section) "." counter(subsection); + display: inline; + margin-right: 1em; +} +h3[id*='example'] { + /* must increment here */ + counter-increment: example; + display: inline; +} +h3[id*='example']:before { + /* and must reset again here */ + counter-reset: chapter {{ page.chapter }}; + + content: "Example " counter(chapter) "." counter(section) "." counter(example); + display: inline; + margin-right: 1em; +} + +.no-numbering, .no-numbering:before, .no-numbering:after { + content: normal; + counter-reset: none; + counter-increment: none; +} diff --git a/docs/_spec/_includes/table-of-contents.yml b/docs/_spec/_includes/table-of-contents.yml new file mode 100644 index 000000000000..b70f97da5424 --- /dev/null +++ b/docs/_spec/_includes/table-of-contents.yml @@ -0,0 +1,23 @@ + +
+ +

Table of Contents

+ +
    + {% assign sorted_pages = site.pages | sort:"name" %} + {% for post in sorted_pages %} + + {% if post.chapter >= 0 %} +
  1. + {{ post.title }} +
  2. + {% endif %} + {% endfor %} +
+
+ + diff --git a/docs/_spec/_includes/version-notice.yml b/docs/_spec/_includes/version-notice.yml new file mode 100644 index 000000000000..5a7286631c11 --- /dev/null +++ b/docs/_spec/_includes/version-notice.yml @@ -0,0 +1,3 @@ +{% if site.thisScalaVersion != site.latestScalaVersion %} +
This is the specification of {{ site.versionCompareMessage }} version of Scala. See the Scala {{ site.latestScalaVersion }} spec.
+{% endif %} diff --git a/docs/_spec/_layouts/default.yml b/docs/_spec/_layouts/default.yml new file mode 100644 index 000000000000..2589a105dff2 --- /dev/null +++ b/docs/_spec/_layouts/default.yml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + {{ page.title }} | Scala {{ site.thisScalaVersion }} + + + +
+ +
+ + +
+{% include version-notice.yml %} +{{ content }} +
+ + + + + + + diff --git a/docs/_spec/_layouts/toc.yml b/docs/_spec/_layouts/toc.yml new file mode 100644 index 000000000000..1106222bd088 --- /dev/null +++ b/docs/_spec/_layouts/toc.yml @@ -0,0 +1,34 @@ + + + + + + + + + + {{ page.title }} | Scala {{ site.thisScalaVersion }} + + + + + + + + +
+
+ + Scala Language Specification + Edit at GitHub +
+
Version {{ site.thisScalaVersion }}
+
+
+{% include version-notice.yml %} +{{ content }} +
+ + + + diff --git a/docs/_spec/id_dsa_travis.enc b/docs/_spec/id_dsa_travis.enc new file mode 100644 index 000000000000..6709463580af --- /dev/null +++ b/docs/_spec/id_dsa_travis.enc @@ -0,0 +1,68 @@ +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 diff --git a/docs/_spec/index.md b/docs/_spec/index.md new file mode 100644 index 000000000000..df126db7bd44 --- /dev/null +++ b/docs/_spec/index.md @@ -0,0 +1,55 @@ +--- +title: Scala Language Specification +layout: toc +--- + +{% include table-of-contents.yml %} + +#### 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 +object-oriented language in the sense that every value is an +object. Types and behavior of objects are described by +classes. Classes can be composed using mixin composition. Scala is +designed to work seamlessly with less pure but mainstream +object-oriented languages like Java. + +Scala is a functional language in the sense that every function is a +value. Nesting of function definitions and higher-order functions are +naturally supported. Scala also supports a general notion of pattern +matching which can model the algebraic types used in many functional +languages. + +Scala has been designed to interoperate seamlessly with Java. +Scala classes can call Java methods, create Java objects, inherit from Java +classes and implement Java interfaces. None of this requires interface +definitions or glue code. + +Scala has been developed from 2001 in the programming methods +laboratory at EPFL. Version 1.0 was released in November 2003. This +document describes the second version of the language, which was +released in March 2006. It acts as a reference for the language +definition and some core library modules. It is not intended to teach +Scala or its concepts; for this there are [other documents](14-references.html). + +Scala has been a collective effort of many people. The design and the +implementation of version 1.0 was completed by Philippe Altherr, +Vincent Cremet, Gilles Dubochet, Burak Emir, Stéphane Micheloud, +Nikolay Mihaylov, Michel Schinz, Erik Stenman, Matthias Zenger, and +the author. Iulian Dragos, Gilles Dubochet, Philipp Haller, Sean +McDirmid, Lex Spoon, and Geoffrey Washburn joined in the effort to +develop the second version of the language and tools. Gilad Bracha, +Craig Chambers, Erik Ernst, Matthias Felleisen, Shriram Krishnamurti, +Gary Leavens, Sebastian Maneth, Erik Meijer, Klaus Ostermann, Didier +Rémy, Mads Torgersen, and Philip Wadler have shaped the design of +the language through lively and inspiring discussions and comments on +previous versions of this document. The contributors to the Scala +mailing list have also given very useful feedback that helped us +improve the language and its tools. diff --git a/docs/_spec/public/favicon.ico b/docs/_spec/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9eb6ef516488909512715a5b752f0a9fe46c89e9 GIT binary patch literal 6518 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 literal 0 HcmV?d00001 diff --git a/docs/_spec/public/fonts/Heuristica-Bold.woff b/docs/_spec/public/fonts/Heuristica-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..904579683d54e3e033fe1180b36fe9e1a5dba551 GIT binary patch literal 106188 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�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�Ry1~_)C`@ant74wcM{@{B{V8|@wh@Lj-Xctk*8UYM$hENJk8d@yup;? zYgITP7i^JAg}1VN3=GzdFnpVf{Pb}lg9d80Khf8a0rE+npSa`IAl86YmbcFfW9Vsk zUd0cwE$a}ZPgU8Lt!hU%NEt@P!sJN}KS7@vgwMcF>u~%IeP#we(?r)EelX4+t`3dO z$ix4DWn{C5Bh}iV{2f`uZW7!jq&x>XAv4|RVF>GFUk%nyIRhkGXZhI6X~Wt$VYITK za-)}#PI#!|GiW1JjGNHd7h89Cjr_ADM~Sm`MLj5+y|p%AB@BY zA!q9}Ti*aBZGFSoI99@vk@f>81vJWa3Zx+f@>39Woic*0m#C3x)Pm}Rmdsxm%!rKY9G?KHQx?Glv;H&f%Zp%zzi3TvhUcVXZ!ZM>;APAD0 z(7x+87bP+Dq0MBpq|;-l)3<6&uDW)4C*OSC=LVciidp(0T7&1JenioV{HPcqr?og! zAGf~L-4ota;i)3;tcql8G9+Rbvdo=iV$`LHp(CBlvHU=LSyC;|N&xw2=?+_ot|(`n zqcsM79Fnt~9QLp10LDiwl{IxV#&Y9OTzD|)ruANUqUo#G*&3?+keSnnI;u1ZhUx!wphV;1v37E zR^fs}=>Of^vsz6mvvJdT=fi-{T3gli8!B)+$q9q&&?o9vVcT}_>@GcoriMznd-e)= zJHoZJnvI*_Hf5dD2hrDXg0HKNvnc9=NqjJd+`Bd+F!3+Y?C8$yui#S{hn;+eV2)}W zL0U|TP2#Dgky|w+)iiEUU9>U(u1mKJXziMqBjMdLF`3-nuy!NWT5lPNZJNAwgFR)k zm9mv{wqJI!O26UU^TxM2h~>HXbz+G+H(yuV@Vuq)=!JXjwD+Og&3awT=5=Qi<@!12 zP4AM|2|Rjm&yk%@KUY+9x4+Lrn=d~1(ZbZWBR9O(*&|-N{_6L&bCORmkD)nOr~aI3 z4q|*_z-1qVk=HZGgG{JNmi3&K8%&sRYHlk!m;hBZjJ-t-w;(933w)%)D_Lo+7a_aI zgeFo6`Q#;JZGw~HLG#N~6f%wluvCR8oP#mQ16Oj^XY`!aA4?3vfO$9ptt2$092{bo zAdeY85d3KMH$Ab8c&rPl59W+S^Mztb(SwP4nm12v@z6uH9;Mq}4RxEiHu|_kyhd9V z`5kDjO#$A&WDiVMnpKf$R=$OjA~-;uPU0fCWKfrzvyN1~WDU~%x*|V>i%0kZ!Jzgd zl^yqEBJc=O+0*?kuTeaYR4wZ$nhdQGxB?Qlnj3AKS)6rbw4<2|L!7ncOlKUhGUJ@! zO(Lc1w+iJ7tk4k%Z9=dU)@U||{?}WZ=+li;IPRcM6)RMy{XBN>+efUPR5jMtnB{#t zE+-muVpm|O|9tt|M+=ofm!uLO^3s-zuu8n@sE7rQ#wLr#=25hUtJEJ+BqkjpIOt_5 zs#cbwYB+qB?GsF+`5HN3naWaPB{30k_tMvjicCyKn96AWd{ zL<^(}h0{gBy4PG+0IWCY6nui5N*%Us%ANXi{Ca@u!dl05 z$wX(qAIUpMeL&QiE}}D?o@`rZ3ejbTWxu4f_RJ=}o2+1hg?b6mpv3-LAlU2C$)B9g zqgy81K1TJo`V01A$*Ehe$@<82(JtZBgT44qScWwTCs2oFnCkFv;`fKKOtIgNWLl$B zB9=Fvw-ssL+F>KgR0SKzIi15B(O^5|izn?65$)hNez1#()`ac6VgT<+UvB>L|#)Ne|ws;Ph^dR*vMfdlcb^)yK< z3QP=-ITK`DXnZln21fNpBTnPfnS-#J9G+Cg_yLX9?a|UP&5&NNrZq;LR#j76GM2Nr zN3<_%vLW~4bH&O0rs>;ZIoUQEecP?{58M`GGKqWxgDp4^@UwG&aN*t{CXuiu7FE-U zeH3tC-?g-;c#?UZ8bUk87W$}IVK{&mK)P!&%+*G65D#8g6>4auL@RTuQT$*_RZyV^ zZZy1G@$lA>5msk~8MI3Tj0?gxX#t73t!2q62ik@*+ftR)5aYe>#82=zCD@iT0TDtM zTvaVMei4PM^r2P^Ka9f_exd?D(W=5#)vDnaBltQBSNO?w_zPR$+C-o3s%C7WUxT|i zL?9s=Fr`-~98Om(UT!m=lVP{2)b41aHZr0L)hJ-PjlAEp&Fj#n=JnQl~P)@l`M`tjfUIsEPsaKoTRz-MhrkLHotD>|heSR9N4UN`j@TqT@npjWMw`WIYYma3{ zw$vOGB+u#RXfheFei$Pi=9kO~?)4 zjgAr=G~NQwB)(Q%MQlx9KC`eI_VBSRKMlC0*k1So)r^7s;%H5VD@|G~n5U2k6%Jf5 zKVXQ_$Z8va$bGH2+$bord}&_LB2j6&L-d>!qEE9eHVp<_2ChwXm8}*QR)j2!~^ z%)^~Xyd~&**5@Z>;baSJZ-+05VSCX&Q2qePcar)m(N>1~SSB+L#(`uzPl)<31c~er zp@d00h>-}Uig0S#&jPkeo|JCcOzk{H{#9XK7(q`P^VF2FJzevK#z^Fv*jSkTrcsw>z|I`@|0fs{wjpif` z#fPUDk4;5>>iFCw(IGQuu0uLc&(6pQlT%2=Os`VctW^K3aJ=41DXn14`YI}hx(n&4 z18CeLR32jec1Elv!#7SeXmpzc4c{oW3v>FM9n_T`oXi3a;C9I4prDpD;wswi0raxG zkAx#M^DS*ugH%->u1$26sVZ%QI;PQjebIb7tS^6s$0d!NofggL9XJsnm%w!lLP#&B zNZU?(>>t(8vOxb`C5BpdwEL89L=?2*hRt+YI@qQE?R%#@&3|g~1MMSRVwWp#W9HZt zm1ph)G)ww*>0IS=NY+6r3tnW9AubHLkq%Wv+s&R1!dZ$Pq?{}AiQ|G7$#tOr!U*Ao z(XxhM3&_H?iLNraTJdoSXANaL$0eOt$T@1H0G>aCMd=ly_ujE*CK%(tK}91m34vlK%VuS zmrP4~*ENPDm=~cQAh76Aan?Bl=L=@=T=H6>qAo_bw|rs<(b*A1_!FZ6N){Nr7a;ND(e^1dB7ApvheOtV$L$< zgJQx(Tp}-9o^UZf_O%Z@0`z6~=7S``;)`88W^v>PAH}?y6BJMC;e@CTQy@{|*%fw$ zg)wCQx+>%z>B6~mm9m@2S!fDvS(8QHd|W6y7lf%^`6gL@82P^js8Lb@p<^mJjD_p< zC5K6kBf3isOQJ2KW!lo}@&!B-VJSA%ssc_DZ;0?aBMi&QkdB~GU1_V)?Po)U#`Yo%Yqc&a150zdm8jB?_qsEa9XaA;c-LlE5^Vh zJaV6A{)>uIMabL>xAz>Ef`CfF@vs^feek*>ri(;NJ7!w|#D**cGHsYEQiw_5K3T45 z4ns8;L>@J2n3V%)V`y0^zfHt#vBIeiQ~{Wk8nwoSe7J7#7Qz>2rnj%lL?6Ct&u%sz zJ@0}GuFND^r7yX=k=-;Am$SzecBel-L~GU$U7=EN_RSj%%EC~&$V8$6Yj$T{#v^yn z$Fa{2HJCcI5BSh7P=)heKp~h5X{nl0#Q!O47uw-Lza7>((Affpk&S~W7cd4EEem`R zI|xF=4>QDBhCUZLfwe%N%ORxCbd)WY5j!pN6Ju&i97M%gin#a!dTXKW>UIg(tfw|} z<><&Ry@_?MuWWnp?Vds{>G?=7dEtbrmSGg-O$oa)liTxD@xlWe()Fk-VzYZajB<2v z<~*$@xvo4pb##NtpmfZbBY~99R(d=3gGQEqLw^n9xLhRT^#$NLVnATH79qec@BvoP z0#l$FjdKM<)dXOCjV9DXEq6?%=R6_I-D`);KT6P}&K{$TCVMm{^|nsba|%WmetrRt?EMC8UT+Sr=`%i*Tsw zkicnh7Xd&-&&??0>*#$hi;O81Z=B&f>8gSo)3f z0yLJp>2s;(6!dt@&T4h8L4bMi158jng$tk{pg0S4fOuI)lIW8x`J_vn?#(hl5l)o{ z&?m!CcpTg|1^d|Mt;jnFBKIML*>um5gL@go^&jLg-SbBDvW6sEV}%*?WTpsr1@th( zE(m)>tvqo8*P-)U3Vfu%Z()U5?j#tiVf5b?wiVg}8H}@RD>@4y$jxwt=Ud^q;#q*> z+dR8vtNb_`!-_$ukT-Bm*0r;NkEHo+4WTxJ1~k^-3tThVn1bgSt1vbWtFr-&$La>Z zjhmxtW8)iv&yo$INo=s${h6XTz!;5;#wJ#Q!7x*8Q$tgQlH{J+cVwGj>@tFe0mOp! zn1v>_|H*-TD5X)EO^IC!y~plb9|-2Jt@=wvzh=7n@X&_v1LuuyJ=I4H)Aff(ri1Uj zXmsliZzvzP|K*l=dcZ!IbZnY72FC}o@qaM>=#qOX>3(k(DnB*8cI2T7IYS0qt{sh<>uX@5 z?>Wxu4rFiwh!q1qQ37Wmx%XC1h{n-}+}5Vo7wVM%$_|S0IkBim$UBniOcvtaGUHE{ z$1jT*0u$>u9~cj8yzf(6#~U-Z-*ouGx49EhwM&%=PZcjJ%%n&6IIlU9n>8zxn=3QB zHc%bxXS}8k%CMk+#U>TMg7Zg)k!AL=-RF;N=lqd91u}IK(1=%k{&*g0%R2yPg!-k( z4M|mngnog*j93(y^K;InryQ_|Ef~YjuFJJl7MC_Rr|e*h%vFOqiwXUwr7B8{G{P6q z4vtoE83r$c)~1L&GEscxUwV*7I1zaSEzSnp(l)?V9ENKXUAtYyCaoP7DN!}r;fBmf zjFq9RKbV6F5#b<7Rj4LlbBv@jU}Et>41E?RIUjALQjFa~#vBbcMhS6Xo=&y6iKsir zk{C?nyhD2TnD(ctElQhtcYJ(&ebDYG`NR5RI#bDo4Sue`1vXz$DjFhOk<|s&M*2ep z2w?Gt_S8Ev8%7*?pTjgUuJGk5liKt|jQd0_Vw!ZNV*&0eFR7XT4Raa&GBrT`JJs~V zm}IMh3ylff17HZ$&uidRcS?hg9$}R1RqR*7{hU=q!OC~|#|K~eEwNIKEN__?k^?9C z`27DP?mOTkxvTqUW_zF6-h0!owrE$&CM5rufb@Uw_nXJ0Rl{xqle9FnEI$_T1_Y~P z(8W6(MuRanVqkB((iR{93|GVs8k26HpLg`dMlMX}Yq65cwX2XC989Of25V&Lb%?-l zCtFPfC+1!bjB zv_x(1)vW{urO*GIm_7OA$-e))osv6EF*97H=XBWfwsHOs|AmNz2kyI1O34`9Pj%Ku z^um4LNhu*<&UaXkNef32*=qRX@6k6B(L9X>1$FcvU(q74=XEJTDqEjL_aru!_e?(ijj5L zJ3)u}neQ+JR|0hyLQ4=x0*kD}v__^b>neikvS9SN@L;Z&0-!>u=^OSqoe#z zSw}gadvfAi|9J;pM>7!{9ipMZTEn)_59-Sgic9qH^Ck}>b9(WL_kDO@0}9OQp`l3B zU?#K03M=4WL2?ikSVM^yy77(>=tm|m?Dq_cDjI%E^G#RFKqQw(6AzBGb4C_O{a7jJ!XGp4l(kx%Kf$!N;(BE3(oUf9`88rS95mswwUUZ?FkIVGEv*xB8mmp{95#Y-2%Q?Rrxv9O>(y+%mO$ z&!J1pDGsNjxz0e%GaohM-C$F>eygOp|*))k0dv?elYgc~kp&vg~iSBdcxndyIjPq_6%3V zPOf`xT-Oc zw6^||a^$T5FLv&<(La-*VH`Phm8)U2$4Qa}K`>!O#@Q0w<>qM}v}OHcpjooGQK7}w zLxYCr>7#umQBE$O$NY%7oY55Y)uA;TX%l^wix>LsgP~pdxHIk7#q_R0i$Ry@G}I>R za}})Dn_+!Y%==~JU#D5dPjb{L0&rCC<6v_UH7~A&Qc718%(98U{m*eib~}(a2;_C3 zGUo}-kS&PlR3W^!;Hr{jTa%f$@xc&{n%e9R`L$v(^{~s6+#V#QAcf-!At^W`l9JP$ z1~WCBy9%f_&Zm4A2OL(jR@>I<^^`EIJ^ZF?vI%RDQ0w2uZ>)r4Q9+RP`(*R8k3V=j zQifHq1erSXMTX`Pru$)cZ3QBDW3^f^j*Dv=GI`3rNOlv37xjC(-GZxy?Rtv^( zz22d+Sgb7c6E>6#&MtJdT@|r*YN3xRi)>#Fl*JHL7DJVVEL9eB8(5wh)$+{n^IKEk8(%R8bdYU>sSM|#?F3t*;k_=%R`v(sfUG2PfX6Pd*Pl( zk8Ef)odLJ3TC|msjV^39*|$>J=(wbMwGn^#cibC^uBk95sFx|_6tp%&T}qg-iU%W1 zI=GwA;YJ~W>AALk7iu6IhBvAev2Y5UIugoer2d@XoVV~^Ge(6Hh!eu3noWt*fq_QM zb(f4$24w0OUnCOfkCePy)yhY6XkeQc9gZFe5A+wV&2hzxW)41Z&-qsdl4CopBT3uV z^t6Z7Xyb{(&e8CMhrRXJ zCnvuCpI1=!O~Cy)ux}ETaq6V#;OBV-ZAclD%o|5y25H^-%`*rD)Fa`m1=3p*Q z*wRIz{#3yA!#SsliaJ-LtyR#7O>o5{NXyHw@()@=muh1Q2`{~><8%|9{BuIhn=blF zQM2^#G9mY|FPF6kjUi*~XHur=>tqC7pUg*U5(4#XoI<^Ln|g`oquyFHS{+tb3j2gM z8qpbO^1O6dYwAiIkYfoB<<)Xd6u}iuwQ)s58j6OuV7H~PP|4nbZqVBo5s5=!!GOCK z32uWPgMNPS{6N_VLdzRUQk*+GxgAwu`^g{;^!OH|s+}GW7}E>+{f<~|m*<0)4_K^z zm*ddZ$lS}%zb-v{=R?PD38e)8Sl{i3%j5A#+O9pvd+lXMYd2gmwTG@D>^C(pCAf`5 zDtz*eGa(=AQ*=#zotzowc~KibC8$w&7mN{~-A3Z(ieSWCi(-r?GjzGsGO}V58trUC zbz&5@no*3DMWSS5DY9}@OomY(Ul!NV` z9ENF!Pvk~MMS*sf3G?%ja1qlc@CsXUSGY*rIHxNdDHJ=@%i#&F-keC1Ga3)lk^zpB zqIx{J_4yOHdFm4+lLZJ|riZm{Xi24U!dTa)T>)OiQ`!awxAc5C;!j(G*?6M9@6EUU zxDyfyc}JQ_|NdIMpY>c7D;Sg7{WHVi3&cYJ|!mwJM#p>YI=RRIMnX|iX6m%VH5(5}tZVBF) zj7FVmsNvT&by^&#%PBycdc*!J=gf0)b8yu7@4Du<&EFZ*_1!jn&(h1B)0Yh=Oap;y zVg{d;{k!s;@)|=tr2Bv6W#+)uZ~vcviWaWE=(26`o%hZ;x6?f;#=0h8ZL`dsHCS0q zr*=s=i%#p#9#8>TB{sxlm>Z~WUkK5|K618A@G=Q1nqUP#$n8t%mE5K*1v~W+uu}&p zJ(ECy^(99DOts$a4UudUlhE?S6NK)*5FU?`H>xvk0_xX6HBlzQw%Dfd9WkNXC^->byH*dG#pZjl%m_FQ`t`FtO-4;WMK1HD#Z##k-Q=@CnH zlEJe^G+Bw@XSyT!3;vNP;_ Xyc@|D+H99SS85pph4!GI$R*f^phbB8h2v)aeh7# zPr{2nem>uqJ1w{m_wXP1PAA5nNUDRwN{qkzuIyGA>LgSwj-YuSZmt>QU*T_b!u)BK zRx&H1z&^jS6;PtUojYxW z!Zc_Kt`CiD2sQ?-Tz^HbhU=qIU}s>>C~#N6*M;ZkxMA?gF&#MqoV=nF0aoGUZ?%SC z8^*HQZ31t7M2P^ud6yCaes??A`^SecEECtocM2iiUI^{V!#do_Fq(th0#jy2*{Gb) zS;NQ+zDSv5NI;!wQ8dD`Xo30y(K4b1R|ySov1~$k+y&oAqG%(Va8?{6sqJMNax3#B z>n?&oHj$y#fNaKBtQZF?lf%LU+cX>Syc_OTqrJ1uytGQ4mPV{x9Q z=!WHUdvf{8s8SlmS=8^3(m6Ns^k%o;xx$v=C{69x0{Tr+f91`gP=c7N{$fr`@!&kC>SPz|FAmZ#M&LS zsRA)927H(4c7e)$hyZMq6ZlrPtLd`7ldRmDMs0+ZHZ`-l`YR@1ToPnEe8p9PqJgv6 zV>g6j3HDsIIi}rdetN}yADxly@w@hCh~KzH)OLAoU^m~PCkscvVW77scyaQiK5Sq!3sfrNrezMQgUETk4**hGF%_Zm04LL9IU72^PUN~h4s}N zLkSAsa^La(JrCJeM? zb#L+N^HBSInawFP58gMp@eu}*Uw5R701Ee~l^uo4)sP!{uL zvA|1x;9cc;jFvq4ci;Qry>x-hNWnzLwq|egK5l&L_b2Otk*DEuB>{s+Q1N)`3UQUsgIpi zO8L#Y@&2LL40_JveQ_h#G$w?|quxq!W}D6&NDU5!Lq*f@8=IzbGhUF`2hL;P@mp)* z_$?7L`(RL`O(wNm=t0(On%;K20KRr?ZuV!^|C*hRM=D02bR zvXJg_m;kH*el!J-(fq(_7l#ORXN;`Y(#5>HcXFf2=2Z@LE6 zwG$-M7pR~IZBDerEzNd?#QX259~l#tJ|~3Pt)|=e+`t-NbE8}i(Rl2l*PMI!-igt7 zyo-!o&i`N>j1PR63*-p2Q%PQqz}Wp>n^xI$CTQyp7irxQ!kxNnQA)zUAs)*@v>rbh zyVps_9>MU4shzaEqEl*0uhi0zTxC^yeQCS@2|n^EdvkKggh|SseEM6@-G2L2;+#9& zv^Tg0Yh^MZ2L$_<)~7L`o-{H_W)LP4Bnc!zr-}CMlX0&6BzMv8F%^{-ekTt;_c&qv z7$~bGEwG zJj*^lduV4-f#o=U!%~ACZv3au!_l+JCMb`mNZkEmnN}9rE%ngogNHz-dju0ED0biDD+}W2Ax#I2AXS2HM|YsNwTEeRXG}ZPZBSht8l$4Px)h z=68)2FQ<8zb^1U$PdD>gi_OBD1?@*(RMk6p((N+8^uO1$VfW3c5N_KI4&Lt!8!VseD~{YpSO8eqd1^tR9$RwtS~^;^ zgJn?ifqwhdY6ZIl`#CkZCX^mqJam3MGn_FN%Ewkk)0;SF(d96!@bqX7+d=LohQ~e^ zBqmCNXjTNbMy0NmS4XIbrc(-%wUe~_> z@7OyqvhBv}Dqu(4vXiCgCrdH4-?}$*8nR*GFRh=OR;@?4`aTuD;peJL&&VsHu45U- zvnzsw)=#=NF>;WnL6l>GUqqvcxMl(SqFAjVx~NnD*L>b!6r7~dvM^;b=^fs9BGpgP z%$!oPf?F;}KNhsW9;;IA6tv_TzTuTsEjokGkh8NZYFnJ%fk2M;NT8|A6Q}@Rh^kgDOi9ML2yh(O|s6gbn6UQ2~>s_qp7&y zC^C8_L`hmCO9{s!CN1P>Q}lU*D+jA!q^n@8EEwo2V1wiYhTwHv38Mo!Vcz0*^wVl= zQWukJA0jq7d(2K7xo-Lac@0!avER+)*wTJbQW4jEFU#zB@t*06%1NhN@AnqBMx0|6 zVMJD5f3dBf58idx#S_OX75#|D2P<7Unf+|29P2btD!0eCCx1pDA9T2G6{HUErCAo)0{8es5z75PBc|_P)x(UP|a2R@$d4 z2-ebtGN$Gg{Cx5X#MHcypRZhqn3@;h74Khpg@UPh;T0WB%?mEP;>xu!HLszVn#V7J ze-9~`nn#aOOw9$v)I10GPkZ-)CL5aGe*iyd2;v^}YWBio4m71JFCjavL%Xi|6XI(Q z50WC-O@`QXl(V|N+;y7_viYz5M{-8*&8q=zVr^X?sja(`eVl0>LOwlqd8fASP`kG7 zP`kEn8X5TLh6?P&?UjWcWJkCVJATLqynHb^+7Oe#$yYs3ncan*GP{f5&PAlmZZEL- zHkzJR-nQ3BYVO1XnBXu?8TiDCP319Ce|LSG<4x zSiAo2;-kloKTrML<#PSqB~5AYB3gg9SD0^Z-*E`}?|@SpI0w(<1t|-LR_faZOx!;{ zv4yCtLp$J6+xC(oQ|Z7#__s-_^p2A%y)74#D!tgIRq3sj<+d4>drp^$wEqZv$g&&CN0^_0)vuu()y zS^soUEvYZjM{54|v9q+MSE>2KW+SbA8!Y@2Yn6pMRWLiFQ&}-gcef z-hJvi!R^2UzG$sJMU9r|ZA#<77cEC-5*NB8VEkR0sv`&Bjf_C5dBvTimaw?Bhg!n5 z@?AGtVCc5F6tU0cHd1TY?=Dxmb6rh(O-NbfETuL~^&PU>`7nIq#GvCQ$^={HUdLwYQ6p-t(BbFoGsK+b|w-W0Hw*5>Mc6uFE0B@=fpAq1eWiCgI4(_MS z44Y(HgR&kdgC3Y6x*XH7{J4*ZQzZ~5&Tc#c>pPws^n;*}6G30lvJot#e<+#vA`#>=1^oP~i}gLtvR zyepmQQ>O=HRrvv3(oR?Tc`Ju6zh}2)&ZslkF>N66Vatd1t0mkX4X#;2%+<;nubagj zf(Ob=A8E^Wa_ur=*;c=mocAagm?cSSRhIK)lJB zXzr9!d@#N`sL;@g9#S>ZLn;n;W3ZM({Je7rdq~yzc~{Mi2%vby`-4NoVk7dSI~K1E ztpI9s;my+z4y0@jJib1~Os6wzw}e`OoL5&GKXmnkTB8rtX*lHO3Zk&hcK3l=rTNoJ zG~b^f@|wE&Q^yWt-D-)AQJfT|ZWS|-s4-qE^+*g>7DCkM8vFCOV#Q7wYZ>977W~x4 zdi)8nv1w{!(-j4Xq_S3uacRvu*MhpvwFKt3gmtb3e%@5TkX{k5c)!1-)VUVA>s$-P z{?f{oOk*;#J&US0AA*PUV@gG`xC+>?##!dR?59 z%_`WFmxC;gFh7xHsX(!*^ZgBkpA4WhS!fct$?j8bp>#<$KlW*>F#%Yn0Y$Lp!%P5! zVay9$j6$>MO*nO2iA1ywb1~br7$*K;isdRTQrQyyE>@y(3=fOtpTRc)`sT z;J96Z*42b*WfPgixz0)?U$a_F>Vt$8 z@)KWEej+C&7dWnNSh6@sPaLHu0@4#f>51YM@5kaqdgfV|J5pB554?}Y;-}S#$Gj*t zfo>^j$KVWW)r+&&2bW}gq^m*uIDNG z@}My9OXlMgh?(dCMzSLYZ~?dFGb!-3PMStLg_Ytwzez{qfh_Aq1|P2i_~)GxUY6AY{xA{*v7dT2l!Ge+eIEs|@&JCMVetQW~uC*-oa7O}xP_K7bD zzj)_$d-m$>jY0S9?&0eA_-%Kv*E;vR zLiJDfopWTiRNi|1^+TBf&A{$gzG%u7g|l$fn7jktxMcWl9GYPhPBs-9r&4zI5!iiHFwBOi{fnu6u)PVHT5R}KbHcHQOdxK3);l&(`? zI+FJ6;)6of8xp*}P8n)BE9^O~UbUU8^_}B)lj73z#(rBF%Q-W#VtIx8p=Fa>Mp%|s ztg^496{{#SmsN$S!5nrZp4l!jEL+UlyBcXD_fBL^3FwC^WpLVm_n z#0oo%{PM6p6Ka^3f{Q-lcqWF6rzK^?o|BTXA5nY})x_n&P@5aCEx4+-TrL9Si=W7A zxPb3moh8%zG1t^f3Tb>47>yMW3Xj9XIVGFGgBvTQSdVpR8f6v(s+dXO*OUe$+(=dL z7`<9QJ@SSzP1vgB5cDm5@5IH|z3RL`MhM*Yam$N-Y5m__Kb%MfssAR^j2UEZ?8av2 z&~dZZB@Os;jEzTZ_Chhm*~s3gV8p6kY>1(B!T5siH@0?vgvv=tA4a+`^Lj&NfMyOT zuhfX@dY`K|Gxt+UX!WADf{=pD&1|7nA_e8AM zTdxynzkrVuUBX{yy;f&1rK$!&;NG0h>bcO;Z$5Zsj5LtoYm#RY#RRz!*rg z!YxMtyFUZ%$#Ht$sfB#|yj;rnk){@mWW`{Xiv+Dw1k(k_tmM+g*bYk~KSsGOI|iSm z;5P85$B-&z_q|bfzRwXVn&CV3fOSf9m(v}nnEuBU&8IKD(RV1H$x;({u5mbFIlx^x z;`UD(vsztl-$!i!G?>tU-)_)E-}hEu2w!qs>iky>e(Q)<-W%&Rk+0mdFTxRAc@yl5 zXMrd8vr|lKFVbPAt`vjrC5883;c`4S$!_WQwu?hCfwdK&6`~6X`t?KrV^&y*KhFnn zBP>vRND8j%m4!js9v-NOqo)=IO%=PQnl1P`zS`boK5enOQ|a05?JgJ= zt4n=@^6msSBS}ml&+Z+Bmjk0s((iC$3XkKR60@5o?e{mugmd20SD5RZTG3Vx4dhls zt`So}nU$~=9%`*&1+&BqRuGJVR;`*+KB4OH4|0Mgrxje|nr|9noF~wn3Z{}?N8K78 zDH?fetQHg83Lt}yD^v;v8?Vs@HHoqQbfFe0C9lvV^zU(5xL8g5mP~42WTek`*~gPX z_C`l3Sy>UFws0&LA063dtQyA0QotYgEYE18q_^G=<-D8#?NmFYfT|NoNs*9qOYh0H zn`k5AbEXD9&b)QVW<;160?@;E`eyS=-)wXwtKdjhx*>XQefAHhchUB$dPL9;Qw7+Y z_nl-urSnFjeT7bc6OZb>;>S1yidZRDNCzS*fKpphC#I}yn|+3E1NV?^_eZPy zgs}5zjSyg;gT8G^fKVVW4G|!Wucih4nNm!Ig$B>?bX!*VlB% zyW+YP2um+5(>lHnfla!G#E}1y;(tg*6ZZ97rKb%>7weV+_KB#Q>E1tmY9Y01sf=A5 z=EcV84Q?vx1~(Ocp0A*@S;cD$uB$h=sZ_zRo!;Q4`!+rLOA|=gbv3$K5h~tbzZ+r; z4{fyPO=lyh?t60;$Qj~XjUYy4zk+iWXrI$^bt*{&cOqI@h|$1sUElAZYay|YF6^r& z_Lf)(Q~3&nGaz5oeGu~%S?t=O$QAN64DvOo#%V#&tcnUW3l_~*v6DrEt2oHd0~^EY z!Bv$+4Ij!NTA$Y1_)1mD)x*`(Xc0|Ib+6q8B!fk*1%mXBDahdr?JyNoOcpK8Bg$w1?)p!PWq#gSMsX_PwFTGiW+78%j0yV# z=}f5$ba2(%Yc(>G%bQTHI$ImuJR7L6tqc)wS48C4ft^G|YNn-c$kG*W7CX{)T4-32 z5V;l3d+I|Sk)p9Cxds{b$$N;sx^($j&Fi=?GW}q&{(>PjWh4~mL^=-|7Z*x_jFUo& zl#Cd3lAD!FCi`N`#1P0DJ$MEt+Vdu4h0P)Dx8boa&c{6iAV-O|yC8+~2xSlKDh>z> z0cSK*A~`3p;~-e}fhbstcrq`i92A@4ptHqjJk&UJnh<(@lUg~kD1mQDo;PvEh6cf( z*Cpg~y-UL>&q&;#w4}!N+%Wyn{Xyr_L1*J_FNtMSr8kyd^SJ(;Ircp8=A8r0m$N^O zk0qn-VYA)Lmd`mjntt7*p8WZH=FUGl`<6)JO%GPm+TF2K<#I~5LqNyRf&R%dWz4=O z7zTctb!L~_H?U%bQp&cHQYqk6OHJ~)v44i>q1_w=*cRfsf5C&;8vZDS^C7^pAlrVy z`GiH#gu-bO;_RYEL&>r-$N)b+l1Med>a#l9P(*(y6-@Leo9_4DHGS?wk7xRdbH(UI z?~M-CqPxyzhYlUf^q$PDH}mhHBJ{?-po4emY~^Ov`bPx{}-XLbzOb=MSyD<}J3 zPkCmB@JtPMW$$4qtBfM9Pelw=#415`Ae=J32B(xeoPtc#Xmd-W!!5XJ3zdNs)_#(3 zk{4QmNWDoqnSUypcJ>uUyIChsTH=Xy0koVrx_-7n?3s2F(mI(ZJ~}fS&FXTQ_pO(M z+)nS@iT)!Me&QchjD&pDNBC%r*@}2S^_6@y4WtAIFDqNAZEJAUNQa}w2}kvVn@-(~ z`FN_|sQB!_k_&PADn)Z}k?pX1fM*0GllWu(f>;N~+bQ`6noVg-3f3TMpYCGEdKSJM zNB`U}VAIiQnK_%I33TA9p2vdY4YB+by3j?<-F!~-P4;aBFX%_@3j6eW>;285NvW`(TC3jQv}%RDiB{N~ z+IT^v=LGjvKF5BN`!|9=z^E$zZQbLsb;e^;kH^`m_#Z_Cg|o#UpfwOA=W!2f=+1{) ziDNu$DxSGr_x4Wy+VQQBgpnUJ0A$9=13KkiVnA9n~O{i&V( zxTBN(s3bq(VS5u(+IH_Dk%LcpynWVcfuz7WrEH!;g#?>YxCF{2s-!}dwh$i+58uwF zi}wcVC)P@TtRB4S{#8mT_OCAw^1guWB`;pHvVzuC+z2{pl3AAPDkkxgWt41clGH}B zsW;LLp&7-3sfDJT3AqJBbhMQZ1rcBM_k&@&}S)@xK~nNiKHCyR0QQVv{ZbYa|9r;NTM7Ai68NNmDVu+Fj!H(cvaYkIkB%i)8A zJN8#&e!tG;DozHc*Ok}w$FCf^dDu0RjwC>;{_Hk3-JRED=UxFamB9EMktuRk>A=+q zA*d3OoRCK@SQ0IDHKtM=OOz0ofF@)}I+9KxOBX99E5xN-Rd5oj+zX`x5Y4@as&khT zAX5pDtui0yx!^0{U&`$u^HVZ}G# zz6riSR`bo<&=dG!+wywO!V~bGy(b{!2JWSP0Q>K49K)PEnlt$U6jKCi^>tvo!!WZ~ z%RRf|N(QqD_Iw!)!bl?W+Pp0&80mQy_U-~xY>hCW*J&l9XsgI+K-khtk6p{GB%P5r35dS@ck(0+$>uCy`hLqU)E>g<-~Ca5=oZqygy)*CdCVf)sc$ z!_s61TcHtJ2CIvh5Ca~sGbXbmtei45U`ALHqnwo~(;05q+44Ic&z!TR6uIo->7zT} zdhygnf9CU)&a+%_*`0eX_VeW}nf~yd`;Q%b^xAzPU-}IfTaUuplXcVF0(|)MThRl& z8fNnnvhvw8@uA4JS9KV-!|QMWoPT2^I63uQ%%{6HcbNXwnvQ^1cB`&Yy-y#_{A zAfrmGXH;!p`xfxEf3EVi>CCEUH?uuG&8+QjlX-F9ZTs7FO#Np!rpaE%gneNjq3d5l zDm~L4(dY{?qW1bH<@JAr(1~rYe{DUZlKb7h3w)On^BC>7g)I?V<|0}|Gxoa;gJMD# z)1@sgWQ1ZEyvU4^8A357jh7_@Y!`yHmVxYv4O-X}8+bW?R18(n{9)s?JZ;D<*$sm8 zQ*KWYoJ~A|r2s=%`z5DP?F+0M3-l*rNPqFUM`PY8zU02=migSmp32!J7 z-QV1{$DZ*1UFp1MJ@(AdCpqJd$F977Kk*-yf3a-ik_12VFPIj`$VlsM4FwoQ!dMcV z8wg`DGQ&t1+AXxmWB*&xkM(0dN)KN}PJ_nAxM^$}=cH{!eTbY@YD#Ip;QX|ObK4`) zoD4k^2KpornVm7lFk%NhFmHp;@ny&<`TRg4w;(!!Lji|2eU@Ouw`8P18T4zl8UdKf6jEK+p_I8h`>xs|!S@K@SJ96r|a(53YuG0Bj zrt_Q0oL=0XQ{e3A9PV{aIL6CmUH#8wOn0?)bzq&gn)D{8HfTF?&;M)Bs(yB}8rd8h zl#%E4D4Cb9J+JCI=XD{hS5ej*ERl;}wdK@*7J8%Ho17AS&k3qGaK9lVeCF0U9vai6 zb87pGWJYwY3TL-gQ$4R0nO8Rt+S+SX*w9+t4{P-w%sjJlX6Ei^m^;rfpEfh5Gc*2d zmy5_2nb&pPuVG#bu(Rl%R~|Qi>M@x*V=}4c^&!yB*T_2Kqhwysw&&$LyA><-sxz>k z)Pu5a){}V&?Rojv>EGp-XSgqcf0tq&?!=~61;!Dh6$KC{T@jsckm^FUQPu1aAS;^La5{nw z#j^SdO%6irq&|Y3G|s$_X^knJvWGdj1rmC_VyUuFmZLfo>XzVxF#Q5O&oLGTjY@xT zv4Nglj?!hat5^7-@M&GZ94nQ_2uO)j60nc9yMUQhq<~}$PuFsVL5z9E1aSnT*|d>( zW<8C>m17+J%5$9O?Jgb~@S6ASq7Ba~LuY6+Ud%cR_Hrmc=)&V0T|nPwC8lQ z-E(?1%qo{$zAg#gT8+MQnkZBzJ<`>~mcis8ooEpFFwd_7z+d9U@<}NOLKy&|3>1P8OzyM~kyJD)$wJDkm7UZ$SI{a1lP1=b!J zp<NKeuPe)Z<4vH)L6c1Ncwm?*R8dUtxiKSI~8sr6RsN2=2 zIG4>+XytOHbXrdXxQGA1cSuhIY+vBX=JF*~^EpiHBV7$v-dA#6R_|1NTGW?4W6R=O zQ&)Bef{#9b=i-_=F3i3{)xen6cs~FPjl|v-O2b2t=z7=-IRucmiQfn4as)SMH zu4ZORz|sAx^gNnR^7>XiKs2mYM< z0x&;+l38GRVW8FlqQ-a4F3K0um{a2FCo$VHR$51MU;teLMY0)0kZNyWl?tgSyYAX3 z!+{gl(716?w@p9z>Ye!_XWnfO2vtwS<8`;YeKsl?evdPoxFML2D-}?>?_PROemYO8 zpNf&bRg>jdX6(VKt8T(`jin!Ok8=xrPHX18Oa%0F2KfJ_#NKeCx69t#19!mSh*Ou2 z_(g7QM>w~Z!C99hO!plVOaIKhmi-^FgMY<27#oahRyD4^^^eQn8CQN2#)aoN-zNK^ zr(X)znaQelcf9l(ndJ;?wz=eC2z|8NZQM_RKA+>9%RiFoql_oI@$m$D8&7_DLZ*)$ zc6N>~`mmyQ#dz4xc-S=p1g;(e1cW|CnLbZ(`sM%aq7N(jHa;F_Z{r~~%$obaAO8cl z2Yp|xWp4LJIm4cOmF05w$j?|qeSq|9`3U=8WIP{f$4}1O6|Aie zRpUu-d_3Wvb%snIJ2ysjM*aoW8B?G$J|XLjDA5@^RpW_ld_11s#*+t~LFmJNp2l1W zeGb5QPVZ2Z#@vRUWXCMe{qwZ{Bboc^e=FPL-^wpry+QxLyb;E8s+%|X&fl{4*!QzD_djsa)8@WTJJ~gNUC(pBh0OgU zoSS*0lgyp+F!xQFhmC}X`+DQyU{5@={0HD+H`!Bsf&D7s;axDEygZ)dnZ_f}DJRd# z20rdhU30R+AiJMo?L5P(o>Oph6a|b&yIhjz^d!5{j`28y`=26LJCGD*LxzBID`riF-0Vt{16IllfCCK=@|*6V_=n6XC9nGz z!4?}=th;la>+Vzs(=5H%;;$^{uvQA~DEn?=M@wzHwGKN<@&Fc=OV~e}*uGa2+qYL` z`-Wewxy|-(=O?)Y;zxKCd4$k$)96;wBk#){q zqH`*$wI12HjQ8~><8z>MUQTrmyF_%({@!#>r1w4b5qVENN%qtg)gE?W<9pa-Z+qA| z*i%#bJjMQ&?5X$nw#WDOx~C3sx61ruCj3)_WUpyMR4>KSN{D9E~F%?5UG^Uytz)N+0U?|M4{XY~0V@ z9Qr&({QkGCpwHR({rMiplUfdFO|lMsjOfsT-gIcZHywI#S&O)*#P5Hc=+J|`jVIsR zc%tn*#iwbWB2(*$f6_g!*8%Xm9+&yYM#ghaPyEws+#w1++%;W3T&=hDO82&22f+3{ zF7uC%@XtBDjVIY7|9}s7O_vW>>&=cvdh?kMfDcFM^Au+xcJ!Ry#uMsoJke!~Odkt3 zO>Ao9_0_~ z9PZG(mDpQ9^GTE0cmp{@T8m4M$Tb5?}eoe?8Cn&`!ziAYldIQ ze2?Ydf?q?=&pyXCiC=S`$}U;f9b5RG99vi-v4u{(XmGt}GLFsJ(kpX1AfFNamW=1$ z&MHpvJ=woviGMZxLgt+;KLGv}U8kqm67jFjQ^hH?>xxs%EI-Q~rE)odlF(?cQur(+ zA=Z;zmX?3VeoK~1x?es2g&K`an*eu|`y!D`6Oqe?N-nD#m&;gh{(Wg#%YI9i%fBUZ zdA@2q1Ap@I5c+g@hx?EAYUS3uTB;1`LXW(o?dBcs7cbOk2=BZM?A?D;+FXa6Jfg}* z**GWLdZNt@AXi`493-@Ph`Ap|bHT>#ovK#e-79T?Z~j}hcQztdBPu=)Y@Cm6z47r@ z;GM5?uOM>udLmaBY&bT0KG=r;mSfmU#5Rnmbg^?ix_J2q%SCw{Pq8l}`uqabGra54 z=UbO8@;EGDqk>)IfRV3fF3V3W{Xiba7ub8rzEn+*_`2xv*m6Mg8Zr(OcZ{rYQ&p=l zvi@3y@y@2O(qox4*>i&*@ByMj|C0SbveszaiyNq+VC4DbeSb?*DvvPGVgg}a>aPV+46-QcFhN2Zs4AkXOw zoP+S;g(^Nwtcwq^7f(%dJ?P4<7PiFJ-AwQ0HGw=s-%7l|wUA9pXI@z}<5V7rbOdW-8^v-~^FQ4&}9Fn1Ff&qb>G zjdj}IVfC?bZ?T^aeg43`{xtgh>Cf;w^!W()+SBN>&NI9&`sg=-J~a1gsZF1rup)}R z#xg05X#IPKhc;gSKDAku>mAR~=AE70wj9vzlJ)ev ziJl%)>BYW3`B~>R%UaD*`K)Ry(bE^5#dwA`>+Eb9c4r!ks%CV&r<&1hPx~Vi*yUMy z@AyxIcP?&^CVCd5$@RuND%$+KO&cohsk75S1HEHGA&rj6_(ETA(}qXrFk9D<~xKold6;db$Ts! zby2Rq2YGP9S{J!r0Bt_X{tcncF;!mJnMOnXR2}T`f7O*QH>uJ$v5o6LZ*Tg~34UsX z{SV@&euL=0W2*7=|Hz($=^(ubMDP_wqWWCe!&zF8r@j%%3Eq z{tgX(r1=ay`vc6EnPnGw_Qqm@R6l|5*wIh-p2c~}CNZm`pNRjc=%@Fq##7k%c=~$Q zPa41WG9t_0WB$cO`dP>{uANbqJL~k1l?T5UX& ztBz-qj%RX(PC1{*-!OB1ci$1s=ZO6Im>XTB|A;zYZIku>v)ThdlP}3K{Z8g5@;c|l zxo(=wb!alTLZ&~Uc^{GK2bf>TCr>{5q_<9@9E*Otn_Q~E!#&|$xfH6 z{!PFF*(3XRG~TkSEfc9T`ge?~U(od+n=ltaule?E%8V?}udP^>wkjzzvQo$4^cj^_ zol%L-sDw{rG-N*4aGzxYFuw`r(@e{Q*rX2HVKRk%z#{Qef>bjvw#r(jC?()U5MH#j z8rsK?6(|V;h|~xI zvBCK%rz;lkuaZtcV-CT&U|^iCVeH~r*1`{lnqo~5`#Qb%B7zi4Hwgl4gF?U>R=4TLmu2gzLrFS>vF-16)f)$LC2Gj16U&&>J~1urLPc>`~EdaV5H zmUJj4=twKc_uO;Uty6=eg^6sZ|0(LVrpf^7})4NTo$bLArNgr2@r?m0$Y=TYdr#6Xw2eARAHjRtxj1yeH{5$psvK_gV zJmWX*XJprFN0xq1aTb6smk_#?UQpj*H;jj3HoSLv4;jzi4cBttvh;iGn}W|^^5hwH z)to$ka{ps5@ZNseANl|p&$+7c_%=QsS8wB?ePgIUbRprJdRtGX&cYwcZbH4!wO#S9 zb2sb{(K;S#8(&X!|06xw#@Hs*`s^pV|A|#%RKwll8Sac{xZ5@sJ4ZePtBUfHD zJjJ$c?9gYC9XyRb8@G+IO<41LRP>?oF2zpOyT?=SjHj-$jX0+-Q`@K+Cbsbr<=HD@ zR8O?Oe<`tzk5JplT2;33Offd5J?`!p)e{@GjYL0D+bHX&M^ySCwQ*Y%+XVe2+eWIN zo=}Y^v+?mHde={vYn~yp{1|hgOV2jDV;q|V^`fljhc$bgS#}inQOuo}UakI1jF|5n zDwbFOOZip*Ql9>$Jo;5#b6R9Rd&W8GH+4?iX4allrRO=R?8wSFscb}TQ|6?y5jeLs z{#K<&o}lykKFsUe%wI7#pFXdkIu>Btgn3O9eR3yrpFFSIe_r0*lu8(f%-=fd`QlIuN7 z9arnI-gFDn=bN%^`y#Oe)bVdVh1K|1VfmQ$3 z0R3A7f|3*0nU`YUo^M|IO`X>^=GD(LuaQldm)gdynAhRXymoHNyi~l3^Hcw=J)OTb zyeWM6Rbt~l%N#p>Ui&+LYo@Me@9EmwRWf)5h&o%V2Ld4t4l9yKLOJ zN@tF*Q)h0Hpi&*K@yj-j=x{bVR^)BpRrT4k&!wqZ*R(G&=&Y;Kc*raP! z0y|l4VTW_sT$#<07GiK0UccPPmW&Obemi%^geyK|{DUFl3_67K?g<%E2EBXAwDfV) zm|HN!4W?ApAPCpRz5e{i?0;W~ac@p%^;~G_Hy^w*rqN}y8qQ{SUGkZ1^6i~YR}aOK zZ+%fM*#=XDinnB~7QCM!~sY z^#^i&_yw0BCYz$$DMqk)c6PW?^J2@i#_%9g$B-Io_`FUZQZh%+K!B8X)<8PnxkzU` zN;^AO3^|UMyuMsrC;Cl(M!hm2Qq@Avb$Ov{e*eT=+;0+bBC+X6L~m# z!WpGCULYHBIX+4Kn~Af?pV&k^2=KQW)Zb#p$#{-->&;EfgQjvwZBLHr&Js_YMVzkE zn|&gD+p2xTxXn)&I!*gC+NB5)yj-maYy$Pc66Swqx;;l+}Xd5tv;jjsxvCn z8I_53r*e4}_gRq3z08+am&-BKcX%Et&A|uT@$|9@FKT#txrWT{Lzxw8H5A*0z4Yu- zCB6GmdiM&>mb-7RNe& zjL1|Z*1U-SV?`~VDlc$W#-J@qI=0AE2ez;YL&e4Z&h_-U=gPm;7B=)-&CiwJKFq#} zy_owtV`F>_E858swhorq=w6f@OkF7Au)tR&Mi0@slTa;GEX@i$hWH)E6pd#*2scwHB|zDby-r=F~!( z3PGBe3~X^hpbZ%7AP4CTnDbl-_}3ta#ij^SVT>k;0pluQ;PgVYh}>@xL?fDf+U#?Z zB`5XB!`L#|fSo|W#={NHkecLxm+c&|_UkQ4Ti-S>tJPYk@r`BpHhg@)HN74J||2Q@M4}b2> z&%sSM(qMM^b=&~ZU?1i?L{LkB+>h5K&b%l#YobsQ3w6m2Z*nzO++PuOr=+T|IKQo` zGZv*?!lJmVB5i|zs(dHYVLn7YjSGv?0icd<7ia*j;NHF)X|PQYy-hLbT(H@PhPU9I zsvr$a0`20?`TlfsoM;VhAN)oKUm(8`1j$foqTcwF&F)L3OVnEs13*j^e6Md9)WxKx zfh0tl`Uc_suy2^q62E~RCv)y7tM9sjO;&UIEK-_Hjk#0S3sNkn)oL9!uQqd$HAn7n ztj0W(^XoN%gg$cwZ`#hon_8_erfJ_`wVW2dmksE3bMVvaF5tDE>ZFIyh5Aie9^Tov zHy!;N)*G;nY;%x1#!@iPdm7t}3*vKMsnU>p@u za|-($OFSI{_P9lrjEN`?_WfnE*%r5Y@>;v=M)o^@+2@NGoe7&U7J4_er|?{^%Ke(p zYTg2W%>dVLk-zt9Cd1y$egpoxS49I>G*=`G`9qB?b{*A&WA|#i=O6ty+H{rh&s^>= zcs}ZNwy0h`3eVW3dWLT0GiWbfpVz@2CBJ_iJZY5t{tNIVe8%!^%m2=7 zqSsc@tU1=lKEVD@|B}JNeJuG$gky$%$hEAA{WkX@#=!)b8K$Mvf%WxaBi#zNie^D# zP~-C89rL{80f{jJ8AI@|hX=i4)1e;mIpL*|Av=aarNcO?hlaa`IXp=_d#$&8sB!L2 zdcAFGzy<%${(1GHL-q5A$<^4r{iQ|tACBoFmIsQzhjGD}zQMFKFeZ_!!vIP^wZD)S z?8N?ymYV3Sh=#i4F)m74cddrw#8Kh4sC4pMTS!A$u51^XlakN>oKAGB8vSbEzVW2w zwPUAWooM9ewMLDrIB&qKDDd-6!3%Faczv>R$9H)6l|^*(^8vTdRcyhv(|nov6k`;; zzJStY*~V}htpVH$x2Ju#yVJ63xKY>CaUTS1k%HCT!loMaM#|1!^w;|@ZjP8o%v!f! z_piEqKx_W+^ldp#|04E{|FC13DOSClCKS?e-fHnfhCgEn{~U+)`&XbyEZWUF4_m3-f9&G@=dkDdli}@C)!CTqZ;ZBCqhm|-B{S#LD36|iIers( zG|u!h_scxW!}P4+A&TLOlm>n+R2IA>8IBc8WNryy*#s};U`_!r?*U#kVal708Uo-Y z6Sa|L_(CoLhLCrMT{u;n(9+qx=r#tNq6H?6ora|Vu(#+HL|0SdF)PkQC*C0D66Tl$ zHxT{0dRx1dIiH&n1s%Q<<0F-A(*q{1uUX%I{77YM%5l5j70G!5ku>|R z=?42m9EH z!CRgQ_h~f~!!Mf(z9-HbxX}}q;i+wr%S+kZ%&lWppBc6pg#S*#+W3J3OUyf%mKn!X zgcb3EM4AXIW>Jxp$*Rapkw$Od04rpG)pOu2DGK9t!KW@>wBe_HaJ#P}*Wh3Id4v6(Q}bpeS{GiDG|b^^SDr1VP31@1zgS|XemQeUag@rJEYhjgGaVP z4R?E$Ajzb*2wjwiR)(MIyiuVP=qCc!#BviyOimk_%dS$;iR!+Xr#%Dv^E!o8cx zy*t|9)533WB==s_zQ@A%u4O~;ytlRQ>EL^>BKO|jzGs7bFD8HY(e}Lt-1~F#y?1o| z_HOdMced}@;oe>3-n-~Mkgu)FzvCX^J`7$B@Nxm8a!Dg-8eBFPyl`1zy{25eskp$f z1*;8Q%DTiD7sYUGL9Zh>e050=H#}gJDiyK+loWF=iZLFw>q3^UWR^!yWWhl-P!$$4 z)(?u6GiXumWI*w{yq;WvEGCnLPck{|b1qq3u&{O_wy@O%voWcGbv2}rcMV`u^yDIE z*4ByB4l=#fQ_&hn+%;F@&|SOFola)MV=tNgj{9p`(-%CSww4;hd(+wC;I8_QHLSB7 zjFg8i*i-C(`26uxWqV(Fc4~NN`q;a|?q|XYhS4&msarA@B-@PfC6Pyak`iTNs4<11F^bd_Q~= zemw863*a5_cm=&R9}I-yZ3wU8AU|Il9DuiVyo#gz{K#kn-Zt^tf**Dq2T)ioxQ(wy znk{$;z6v#4@JoDEYcf*;FZcsNSm+VEBNQH}HAl-U|Bsz=^MVh*H8}Kq-;>=BaMFN* zxTZ9#gDs5NGdVqjDl#ufao8YAM~ZMavvc3!W2jblr$C!--G;{F*kO1%yPKwPQ|;*i ztpS@F*KigC!>)Q`QcFId$_3R4Y+y7g_|L9|d%8x#kW+d74L53|Np5Hm&8D3zO-Bk| zpDX5ZTTJ^5dUwtI)z4{0>_RwNitV3LeR#!%U(;?=?rS&;tF?Uh*#7#=vHgS7hqX?J zKg}EDf37$;h-oP4tJtsl+P z+f%&gKPgpX&xzTST6j0_oAQIp+xYR1zD8W$DnFmAW?e76!QBpvx8TRYtKGMa!Hk}^sSKx!W-3O1H&aShQz^>XVesvW;2~jzUZWUGL*7(!3x=D3 zS?gvt_{#C^cO2iE;n;}to=`Ymz9F^rIjzZFFINw1C^Y_Pu}Jen$8u=h$m$IoqL{}2yWz1sg@+n0dHaaVcP(f3)^xB9+Y z-Reu-Qn&85ZdtYz$98PT2FG?tZ0Euxu|p0LW&MG4CNRvo>`|6&e!e&q8psw92wk)21aPLRs`X{YKKvjlP3 zR+^QvLNS&tmzSJ+stV$wjpj=ru1H^kB%TM8%9bEg7Q3o&6Gzg7C9}6OI2U(=Cz~hv zq(`Z=+A+GcuGIB*^oM#27V3;1r$) zyWl6LIB^s{vSeAQmqw9V$^o@fs*jfNYIFd^dK;!GEJ#2!2C^_Z1!r+03!D{Bw~Pb& z6fdT*OXIXP#%dFjXxwP5dV$C6k2qrpBkuqhow5FErJqL_>Hg{%Jxcc#=>9USfFT2W z<^(xVZiEz;M?)5K63YGbJzjk>=GPbt|CYD;V@W-IU%;xhM*lj<^{LCcpzi62U1tft z;5Td4@96t8wT@3QW2a6Pv6iWgUZ;8!upk$?8E8vpLhJ@+_wJN;^v zXZ1y!g;DwaYSv_OG~V_oNj z)G~Z-gJo>?9{dPF0~eZpFgfyv7#k{bsaPPmn^*4U;DU>`TdpeCh*ZO{Tn&@u2w5KZ z*iX`AImR^-v6SSniK`a-dUbGCTK5?hLU|i*r-9#1?ij+1i5ziRqdqziU!U~ zYeICj)3mXqE1~pn!Hj`hUT5cu-G8Cids(w3s-@%F5x2_rzLphhco@ggD?=9FfbL~& zg7fgHo1T8Vb+2O4K9--Qwfpvb$L$33lhiN)vBPGqF8@>X+5a&aVqsCmc)Y`ZzuLI} z5ygN>^|cetm)IAWFK{XLL-f0`-p78F{y(d~3@>ejktbW z^Ci_;vi@O~0eXtMgZ?!B3-{kl>VtQ%c;7qVa~_jF=RKsZc#8g!^f?;o@5ijIKisi? zl573^)AIU#OisPg{pJ`ub z|I&c#cfePe&=1adDFVarOBgEEBiLQcLY|Q& zg|BQ%F9%^}2V^HkEJ~E>Mv}rAOJMbS!LyAPg!ox8!>@>A>%%4$Cuo<&eu(`0z?}WV zzkWh8XC*LaN=Y+zt=(C*@yvy*R4UI~R zrtM!}J4XzS8FC6UhoU8SF7{T|k`~+A>5iUwB9lqPE%Lv|MsnFuFiWSTf8lrUqwb;~pihEKYq3Kj zNi`8@6l`5vdqmXZZ^g1J1L?oq0!=}_w9igc_8;14%68X|9gm~vgARQf|7IJrWYf^E z5Z%GUYxHaIdni7_N9fm9P53`q`x@h*cdCf4Jq zjw7IgRn$c-oM@}9B6QuMmC}DyQ8TtPi)Abo2<1}UkK2?dkvFpiVf?HZa;}JTvO@mt zt5*;OD}#c8BI)ht1WQ|n-pvVVNYJ@+kjxJlNvys&vOsiU|G!o62GOrdnXkL*W?Q9S ztg5B7DLW|$Tj{bEa$xkbv_r~xA>XAB#yu`R#F;g>UvAl>GPpARm-TJ!yMeo2ecgKo z2EvgyJ$a~*D85Ub_r?32hEt}S4oBXyXJ8BSB_bpZ#^CvzVU-ZTnKJ218#G4R;qCc z)v_2jtkf%r;0yw%2ZZ!92%H{)b0Tn_GVUXqKk< z5F1+-jdl|GwGdMaRiF`shRFz~v0=sI zGh=&SxrZ3Y3fJ&fx-bEq;2O1wF))>I-EIyIMy|^niRSVHW9>$eGn%aOLZvzYIl`vq zPwb5Y>^@8-21O@kn(h|tLAniiRtBE*c_H{}ZD>z|@g!3o0RILt0O$?8S{t^?;G06j zhsP27Lx=gc0i*BRJ$Yj3x0UT5Uv$AVqmr|$t-h*ceHvH${L)R`m^$jvNf zQ3AH@yJgSxFA5_m>nFC1{@x$FdvWZ;Cgwo3G#1T8m9@gX`0rHT9tO8)KY=B)DfdGC4BJsvB9zm0hTsT>&jwq;_5Y=!b0mR{v zb!dvt9GF(y049n-4?yYM49c~x4UO|T09OfsC8{iYI;4O%?4em^1BiPyl^^auUWxKf z4QsE=CJcuTpVC|(9xQFkk0)FnuSI9loz(EY+Yi?s=>X3AlZjj`##zk=9?coGtI_)_ z#YE5%AL62nGw4`7viiHUY-hg%cqPHk{)(zkqQ<();uto5h|N_@ZCo+69BQn+EP7j} zHXxbWaH*b$%cTKuije6I)2>@!(1Z} z_9IqH;7Q&7c8iOhQGX!Zi4r9ajDgCfFpD1)IWOR3+h}PklD=t)PPJRs3eiOgLBvlh zO=r2uWv8tj`zGqzXWoB5=+o9jn`!+vABh#G$NYgv)aU5(bH17{V|Terq1y5JXkg9U z{t6WBjX2S&kGBl$-}w^VrCKQF3FmFjx$Ca&y^MS4z&1+8?n{7Og_@#%O4ZYdR}y{X zAnKN)dwq(jbs=zFWibzAVq3QuB%6ymMiTh3vtk6iqnw$KExnp=*R5W_s@UcoGn~)^ z!Dj}8&-I$cQeQA~USFoC*t=#T4X8|=L`jh%Vqtl3yI(<_@)~7Z)6u z>Wyr0jg|75RaKi`ygz%T;ul{8tS0IBCVp{T0c(6yzu0nwZD36muw}6sN@IZ1=>HFo zxZV#M6+bvS){zcaJ3L{>;+h}KAkwwL|L6WtySXdWhlh@g%@r@|3ROAJl#F~k+Ns$~ z3K#H#E!ZhpFPXmrtWyxZ{+6l_pi1J)a}o;52?b^1_d+edmv8w!#JFC-lU$xmr)EiM zl@^8yf)D&3w;~R2?*F281oN5Eum5Jdgnj|gFD{E|0J(b;Ed_@ciFT)pojQu7LUEn5 z!xnhHAD!I*Viy|}vn3$)R{*)tALRa8_-H{d?Ue#uqrnljkX-Ng%0Jw9tQxa9)QqOv zGaWw}IkInH3;p{AgKtRpGtE(eujmSFzy0dXd|tKyc)a(WOq%Ya11VM$320XDE)1uv zkI8oPYXqNJ>St7a3boN!7HjxgBh<#taB68|NXBJpP;zn#Sc7Efc(5P6-CRN3y18!3 z=&b3ck9a|~=;euSZp7y)P%?ic+JR1&*QbyaCpRTyGFStB>K>mU`V_jDK508_<;8s6 z<{AYKuT5*1FJH{rtye1I@f5>(K7S|0mR|?lda18c^%!bZ03a(UXcaa%y0os{WR?mz zwYnKBS%9Ud&9OnW7Ta3t6-^ z=k+0zn=3g(mz+8px~a``ZRV}s_%LXJ?aW>DkK0U^?4M2pZ|A9>Q}sE8rE^N$KF0}J zjN7Z2e`k?gEdi%}Xupy`OZt$OjOcL$L72c>U9F66R0`sUO0=-8AjHm!LCcD`U54Uw zuX@^{m;orJ+cjheGz8M{Ax=zt&#B>59QB^tOijAe(=#1-bfwMgI zxfOGjYGZxBGUP&TtyHCftj)r8wFY3>+t)qM*ACS#&35^$_AZm#^4`$lUB$_i(`K_l z#IAk&KJy+EXDD@rOYWO%kM>TqVdeCeYxz*zHCK*%qrr4=GqZHzv| zAdcPb+K;a6(!FrH{{ZOa6i(^|yOQH^_a7i0ZQkr60&-DL*AkiS{LF2gF7F~j!wz1^ z8A@`Lbj`Q>#PdlKU0UxaiA_*xK(2PuVXEFu=9NIIb|_M{Ly@W-oY03-Qv-61OvzrdwqmTG&+(cW*8>gP>5fIkbeN(bDv2bB%DiMmq|796L1{U^J^vGo$^t+B zwoMHFMB?NhYhF^WZ5zG8`Glj{q|3~Y>F=^{UQ?Js1P*5ctHOFE!Ej8iVDD%x^DM)#k5Wd;NrAnypzYG@R|I(9df zss3trf0gjz3FZanGWI&Ei^@_snyNOe2sV^;ylf;NpGse z&0Nyvtta$+q!0*=PP=@71G#Wcjz-~vdC48hdT>{jt#u;x?Vo18&-AnRQD&U;Hx!mw zxgl>+_8V2@?X#r(^z;*P&h9N*hNcI0Y;nvD?HnilmO2xq|Bd-I$eNuh zQi8T1@MUZ|kb!FuGzY<)le!-Gy*TW8Xbhz5VQ+08PAVITll6?v%UAq|B9CY6` z-Rds9mp>NwO8+MC_wH)G#w;=#;70)YVM2cJV79t|9~e^xC4TUPA1>qvzaoZklot76 zBK+v$;Z#dW{J=d7(iVm)cFB<)N#w__?4GyG{yjO|=SgH|QueMm9zQqy{v+8h;^E$O z@75DDK0(r0yK)!riPJbJ$h$YO{Tdj^5LDk-}}AX18U1BYM9un(m-WBQaR2;5oGXeArxG$>n+6)_3_8aZNa!CW+0yVr*!I8IwV zf-^h7=0Kb%n4pJMXCz9zI8NM3fs^pWrS zYqh@W5&oyKpf54LI%TUKAIa^^1;aOlqM`iucSZY>T^v8*cXX>iNpNsC4>5g=mKvZw zO9_>NsDtOxRg~dtb79G&qpnc(G`h^3McPCWEQlGb>yQF?Fs>(?@8$i6jg*?w_2A|S zG?8W3icsc+9NH6~V@2>4#2m0=2)7ncWJ(*fj<-E!^917=d{M68Qe8dri-`e z#y$Nr(LlJ@t8>`>*;}qYcGJNf_kHZ9Yu*uxWb?K1ksT*2AxFr1T`khxH(;~Je7W8G z=EfIws_1Q3UArjFKXw5hdqAE|6i-q`_{$L9kNYV#F&8 zGFb&Sz*Z0pXK{QC#l7^6ACgxU2xf>FAd;X8=LEVvuTbR$11IV+?^bc56=!qxTtlr_ zLENCjBP=(J1}j`z@W@gP%F5AlwV6_>b$X-OB2(JJ1WD+meK@gdq*}JeG+np;^);uC z9IzfpoQ|&k{%~U}b2RkuKOSA39Y1qsoF2GIvg7#t3-J6Y>J|!=U|k79u#zGEFb>HT zmKFn zGk?jEs~$ad&B<^$=jj?NzV*$OsWA^dZZsV;I^NBckM243&IN+^0rKAIhp8adL)}2t z{qjUSP710qN>t;cTaBn3S@M`6du!TV>~fOL9y(MDvz6>A!(r|mEG0s?htlfu+i=vl z%gjq#ZLB!#PT`9d*8I|1r9-2YDvPZEK+yrM=D_0g;tg*;lJ`aQ&Y|LdALCt&?K|?m zTW`PqflQ{imP?jnz8_t4c6e%6DjZ3_<%72byRY7J^#gZzS7&bB3!jofY)=5THv_gl zYKQ`7xTVh(*loaP^pl|holEkkI*d|iAL=pf=GS)AXp{{#WUDNQ8fgKZ7^0UA z-p>sTo3wM61jmMQCQW%>_wUh|$wXiNsOictjs5wN;o->aVl8jd^j+t&+3ghWv6%x5 zjxisF*daiP-B{KatUwXxfe_1@X=uN*BgO@l_J3!(%0lO?-rP);c__`wl@Mc?JNNz$p2x7LJsK|3fUZP>)} z8;NR0NeG1#d1+qc-GiM9X-{d|Y_VjS?GEyy0O_$yxsctV<>LO!XPMD$GuOZG+8b|} zO5D7E->GMF=~BR*Oy(z&f$lDMB~82OiNjluz5nhL55IeUeu2I=Khm3eOSyK6*rEL( z6QlIYl$AOm#T9ic9yFNs8-W9OvZNwoymh077-XGZn*Gq7ZH4!IXVf83V20^sH5yur zU|9yKwqVRb(H3i4%;Cmdxf;>N}kLHkx{wu%M6!`RXKj&S& zL7MU7n`Y)NhPG*N@(#W)d1n}NkP3rL|Aeah(2qFE5DbE8DUqs%5HAx;6D!qCEZG6N zMCqt9JP(WI4kKwbg9T2mdkEa#sah6;wsS(D-Io~Uo@I=KhciP4YK9Ed9K$Bcz$+AK zqPV$+$8E&10$7XVS{<(2cYCVLZciYnOpvfDqlr*r@eREbN<)lz7qMk_rM6J1(RkA8 zi^NFAS;0+{+Us>cS0ChJ(YJ)UGVj02;tdQ2E_r)8ZVst#z5jS}(&Vcc>CYMIFGjrT z)juEkz}A6>OsnrG9I>4lD&6?c570~xdwV_)yuGgZ8v8WxwoFy2Z&UR$T8ntL47t2v zMRbM0Mfc%LHu^zK$k>g}RxU4TB;M+gw>;tPKmq?40P=S9%&(szyww8_4a*`6IXtuc z%;=YYQauX(T8tiM)G+QBhWtPIcAi-moiW#Dc3VnMluJ#q?cdfWNe@RGGXS4 z&kuny%$=g} ze9J~3w6V;>0>SnJ%nBP~KTkQRUJ8O)Vrz{y^fpEo?W zWbc$*P$2!B52S)K7C%?nT?-6dzisMr_R3hXXe;S$JOu7L_smLh_v65;Eo;1j+}Z|F zw+u)L65A!6#4CFnuMiAyW`mt@w7sb7@sxuPA9bJhy8li&V`uHX@spt$v(wZ%f#;4g z1Iz))?d|y7d_mgb$G3L)$+^9>R}Y@u*?Mk9dhWG7W6EPkXI(*Uw{Id63U8mBnqeND za#{>=LwtIYzhuw2QZs))_T#AqIzVmKfEUI&p@2?&2*^XEw=~qR@2PvS+>`)Xg6ywN zgyGhNT-6vsW@$4-}w--T%$Xig3BH}3N@}VR$G9}DLj(CNGe-fXjwxGmN`@1J=xK*+SK&I z#>#jAqGTZr!3ZgFdd}B6T;C^Y8<^=RYf1%hrM9`gtf>nPUp1cIYOfut?Z8%v!)5%K0pFNCKO!{vG6K5=Wqa}BHK{GnOH5Yfy^dtpzDD2874l|?29K9&+%FQVM#0;`bz8`=#7DbJOZO6h3TF!gxVbaX+=-iLzV=>-jJurKD-l$!DcVReX`NS=BFyL4{ zf{lC`H=I=~QD3L(A;hfE7%MSmlAGUg2$I$Y(6cq zNyp$qGoIDwX8Srj0_vPMTG@P>llzyBs(-Zv+?IzoC7XzUrDiX6n2xl~tz4#X_%g*f zUd9QNXz><-yf}&E#jUMAB4mnaw+^-}Vx)7lrDvaH8O5=kpgaYlJV&JNAt=w4n;XYn zVEGQWtByR@G7Pv3ZEX4M;u<@59fr$&cqCIU#i8L{hdakQ3qaesYv19`+Jp53j=JD` zNt79vgQP*|NgRl~&uE6pw$J&wdc+~VONws+dy5kBJ5 znKH)K%nP#}-#Kv zPOvVE$*444splF-J*g(+QAl!)Xfgtq2|Th?LvM{FrFZA*jTUPpnn<>rB)6YTcTw$g z%at|JS|5o?)8z+KPM6hZGwS;1!Bc3>k^Y^1>jJGq-NSw3qqWaEQ-S{IEA+KRZ*l8X zqAip<^h94aCDo_nGQa%P!;sGbzv>2L5bCMZfDCeSdg+e>;-nl64Dtbk0*Jk61_lK; zDG8~UMZfJF7Ec66wfk&3AtI4c4{RN6vsofr*znwj18)?Xs z3etI*693rwxbU&xF;A?2@;8p7Z95~+awe$(>UUJV%E*Jbo6W`Ztvw8Gba=T|C5gB` zF`FafGCi_J3>F0MS<%6*C~sW;!mGoCD_Bd?FN@*mx;f6gv_q+z$1TmR+l|t6yb(e} zIJSj`pVu40kyQ8EjwHR_U_{EgI*91-Vm#P~p01}?emk=mbhpPRQo?VS-@>tB_GROI z%b|qF&HEf?P2z~w*)w>cx;E9~o9KR9_~`DTE%Y0k%&sIO1HP}&--`^*m16SLN-qDo zRr~$#O3{_|11gk^51HkRQWMm-sCrG_zcAF=zYtb%3U9i9A%nHdK53S-Z99ro0h}y| zQ!+XSUwKSXYQwS^$lxnm&cADcdP;9_xc!0F>#*U9Y)$AaLG=wmoDmxt#kQOm;&Q<> zC~$n|?gV7~A3v+vhJZdYe5AHEra757N%+tF&x?#{%2=cqF754@(L^l1ao!otGxCgP zmO4Y#gQzVYfMPS_irRu@**MnCa|OkGuH$qngRc--Ga6wI)B@71bAof30=_z3;Yc#I z_TusN6p7Pu4>%K((dU<5t4W$&>t*}=lREA4?8;OxD{Vf5L-?vNE<8F@j&7W>0rsIS z{U!4<)8Cq%(H8K%qjfEVwRA1GLV;CgXQWrjb-wn3G=}w91EB{66)$K81=c30$*4mm ztc_KY5H9>OO3z27`5ETr2Oq@gnP#&YV4kCD?7f_pU0FRrNq?XDG|-+Tw4W)oZsz;c zC)xXe_I-usXI`Mb%3cSw?kOeytiIBG zw)si;yf>QO*ZqWcXVcmIdh=6oAJq)J-a}~V)u)@!H!p?zR-5MEzeH%4H}lPJG;ar5 zvl)CnOHuy`R$hFe004N}V_;-pU;yHtol9TE^V@u7kY|1Y6k#~)({d3;|Ks`B&ML@K z!obYH!N3Gk4FHQf4TpHzV_;-pVBYqhje&tx@E^~=!>ob~DGcHaNPzhd0D#E`F#vel zt(SRhl~o$X-*e7|DT)kB7;!-iC{)y1!3A)L7ARVlNNuHXDN7Y?sdNCVR67Hfw(0~V zDWyy>aVZ!S*NAb!sEJ5i$mk@a6Eks7T!QkCOb9NKd;GoUe&3~haIJsLO`bg8{g$)5 z@AEFlE|DjMpW82DW^?gAJY1%mw`G?tmTSON*CHG3_fjK=<#Dq}T7WZ$6Tp>V5?BB>M`Kom_xYAFZqjkUo#rk1hx@avvCV$J-6@5( zTUNNf@Lxa~_>li+OQC56?f#&BmU}a#(A_Vi?ALOZ{Yh5YF77Em4vwocZ%0(sc3 zmb=_mX|${T0mi$_)=MAuvB115Ti{ce|5o-Srb9YxrA%hrQuB_K*&4aZd?ID0+Hbcf z$xwT{Tx%+1xtZ;sw3B3pxmxO6r15 zJ=h=HhkG5e(=znz12lt!I19B(dFLY1I2CxRSV*AsA z-A@45?02g#f**Py_@M_}e<{lOA&Ggi30|qb=!xKq+ZpdR?5lP^0o+iTtiA|-=!puc z3%;lb*X6g6c8w4e%T(;`yb)Cu)}@A7T6zu=+=BlVJBF@peA{ zi6zx@j)^PPc3vjt(EX^u_0kah-26M3_zW?ECW1fWI3-q+Z04euZYd6$`gK7JP2Hunvh&+0Crse~4y`DZ5Ak>i99lD13O{_trK?%5!JT}ODArpy@2D6Ygu992KOc_bOTkh`7#v5xnNqu2z{Sn*B ze#S{H^A)IFY=3#$_V>Hs`KDNQSSLHkK`lV}Q_Z!e!|#O$f)~h59^OYjE`!&BJ=CFA z5l>ZnS@sjb#b78H3C`uiLY|KYE#PHP2AaSgK-J3}099Zd zSOpe?Vz31C2iq9uk8#c;*EZYBvb8DLy!B{3N|nmk)O6mdmS#5s9?g3@WWE~)s~?_# zwXW&+U;EE>ywr2OyxC;km%wo)glWnt{YvNKiBSioH; zYf`Cbo-Qd#)xy6phiX9m-xu3HLp`2>@6cUpuv}n1B8K9eSS4vYSqfN70s2Yjaw>H# zc>q%|I{+Oj&GL9%|R2J(NeoibaT0P37Ywe*jdCFb@(^R*>)lM>^n(^e6IB| zo4?CdkLHMl&RFIPd0jN`N~IpTUWdJaDLfNv(TAKl-7*>_sf z`o8W_?P`}w+KrK7yF_k`;v?<;6Y5slH8S1~_8RAQ?HjbNYYyti_%U~(>yxFQdlLKW z-m$&z-~Jfo>>6rwn^eZE+Q_Y8Kz2>!IPF`~Ay+5zLN0H_`GMSKzRc!0<#;UBOz>Nj zgM!x7P7&wJ>8c6!i)tv?Hp%gR(5Tu`wWR(;gJbOw{G(b_J;dwY8TL|o9QUk^HAib> zK0a}c^uI*^Q`-N99xP9dJicc7eWt=cpUc%r&eqDJW7+SEczcLH{Ga5!wKU7q^4k5V z{R=~n81pfC9s3{48+)m-4G~X;tH{Bh!BgRvqPj3G;rF)#(ZkX*!f7jfR(0$Raf>hKn=#bB_tvYs4XYW^+v z@ZKGL2Fb=;eXo;tuuzuzM(TMzSO6A-TCgd)t^)(XaMS6(fm6VMKHwB^d2~HM&!4GQ z^nRE;I!o50+hWcuEA`Bh`h+^0J-^I}xDqsin?M_=2Tfo_#Lp<}8A;=r-s26&)&y6-UI*g+v!z0HBXvqYJQvVX1(3^Zr{x}^f`XG-{1@Vnf?l2;~(+o`X*oO zr~5zo1)05>(#(d;l+4=9d71gY0rr0PHrB9;}%Ey*UrI=xHlv-PAE3z62+hCMRMYJg@LXD6SYJdH|f34#< zk9XetzV7on&-1$9_wh#j@h=(tKTr{o7DOD^Fyi=L5hpZ_s5~B4M4V{t#HkTg)SNUF zHbqp;fRXS_7Xrg!1vWRBRG+PkSd_zPFuPv)aw6fOf zKtwjJt?6$=SKEyd?aCuA(6>Er?P>1dwZo&J_l1=sI?|EjHHY7e>ADzaF1}0VL|n@6 zWy>NuJ9oMIF8p=X;|lv%=-b^|kA)FEXGC0y^C}vzmQ61`ded-C{fIvJ|6CYx?Q~cb zaox6v>*aI3ysqCG(U12V_3E!jf!YGKH_7NGbp!YvNYlU;V11xj+=BZST!Z)~d*KbD?x^o^t8VZFxFFrJnP?%4#q z6KQ>f*GXz8*`M4QGK(WBfes%;PjXzB6K)`f2K?ne7wwKcVlF@_W+z zr<|E?_S0#Y?%dNfKF#klGJ4kE&-!}?e>3!XPM_zUovD5%Pc!wJCC4InYPLDd(d%#b z0UvYS*}3lDJRI|I%rp1-de1kT`LcLHRxjdQAddy|c**QuGW(Zh{<3omW&027uULP@ z`m1L1Dou;@TV&R+@&20o`MSQZ^Z5pCZ{mGRzs1%TTU#vSCA=@ewM2ezTYHLf5Bnxnp1B`Dt4$ygk|ATTk z=)V8L^DjIf;^h#I3LF(UD)gwJ^)OwBc{+^mFuq^$9ii)p{i8G-b$5>8KPH#oc=^rU z{N3IBeQP8!6c$C2b_j zXBMwn`ZuJr;S9jtkk5u2p*)gCm7p%P0Qws7-Dog4(@392dm?G9Pvct96mo$7#&k5k z52k|rn(*4h`KCJ~IY<9y-JmbvYNoCkJuP@^X}uL+*)qz;eV)D6ytcOH`IEG119EAn zwjC|)X}B;Wl8!RUv38L>I?1k+ex3B|L`$xIx%}mtRqp&qE;Sd=pQJMnUF6escqCWw z;MtS(G{>I$T#4%{xLO{)@%QFG5AQXyxJE90P-TobV+@Z&C zUPh=L!S@JRj!<)FWuWUWcjRt*?lI?k?B6Tfd-c4(Fp^PnC^YK_&E+9y#?UsF?{V(H z!}1vK%y>CZ(0?MWk6N2#c2o6#42Ne$@+8jb?#46bIm7yM^v>jSmOP5}olW;_nawtr zIp#Ol?B?2^C&T%2c!7o&<@1vDzw@wApI2yHgzGh&uhI89Pye+3run_4=UY52c4o2l zw{iT-*>`v?;iE(rCFWXUt|jJL!c&Qw5_vCo&zDXu8u_k~(;C^V)pIRf>)g|I@+osC%4jK5x8B`fZ>}Gh z?}zf(z}p6Q^`mK#d~AOst)J5NxokJN2b*wiHrLJgzQFf|o?D#RqIRp?wz~6Q()y*G z|6_(on<&G}n8zN7bhy1qA$ zowV-6zYG5^{6EOx2ifg5yWR5NL)RWU_c*uLeD?D7qfCF4+fQoCoQ`teQTx>H z)B9(&Kl8a?2K!}yK%NKi9#ne}?=SK@ME4=OE9kDE`>;E6ST4Vs>#xrKO7{`-Kce=C z%#XU8M`d)BhGR4w!~2{4-`qvt+llY()c1Dkdpq^Lo%-HR(^}9Mc0_vI$Ve+yg6WYS zUmw){DF@0TJ)s}W0di?%-5ETb;oO;pk!DndS>W7R!y~QdXGT4}>TQfPlg3OnnLK9FQa=M0M%sYS2DlpF zI=c_>c{Yt%v}W1Q(yO8UM%6(Mjk94zq)p`21b5SlNY8mR(q?sG0npOiUUU4-X>C3~ z(iUw1|G9EGwJ_FQB2lGacm7K^_;jfMt<(G>?w_`>$AMHAQ z?q_%2y6fMa{_ec?;H5`HFc-gn(jIj6w11_{ubLX^)$Us_T)k<`Gow7d^4yI)oOw9& z_|8+C$44HYdFGsFc74q4TDVTWH{j^6zCXVHdU!6So=K_aQJQZq`84MHtmNa$rzzil zzWoCG1@;T<7dT%)^UX56*&GMRbpYN0dJph^AP;{r|3Pr8K11joisN>39Zsj;O6gtr z?>6guow;A1`%5Ez0M7$-drqaJ@E7V=NaJYdM?3$Zy)k@@g>mlAIBO5%ACF^#dpps& ziDvr<|C8iB3CAQEPIgx(`)o{>#}sF$xYJY3$nT=`F?y!a^921*;eQ&QF}G)Zrf2B= zygAO~qX2^DV9?){$gH>X)LCz7=JMx z#pW`*>VE;e4eZDO00001000CJ0BisS0Dk}m00ICR073v7000310tEmB00ns3%~Z{9 z(?AgZ8izKv_ZnB;cPD?vX6x9=eVu1i6WX%JRgNJ2Dkxo)nh-jn2qdU<=^|1C zN|6rIk)CiFE~cCIN!m!7@AmN#1L)7Z%q-GHV^?mkU4)n($F|@+ zp1*wAA%nTb7hjdvRc@%tL1kLb{P++Shg7$c(pzBLik(4TK@`u%A>~36N-?K;LvmBk zP@rW*eeXL!`Rz5o-M+0)wsNNf$XN4|3g@k$FH>!k%mB;bM{`<>JIXhGBv|i_R*oG0 z(L29hpp3ME)a*pxa2QH=>)Q?E`fOVVTpKhCst8DjfXDXisd>|*H zO+w%JHX8AQM3clbU$;2ahT4m_?y&)##qp%X>{e157FoT=I4|B%8y^B~dLNc$va-f0 zW?sO{?EYk0AZO)?Wor4?kLJS%-hVSBH<%86{9#_GAKDJze%|x|sXTPu#Z_< zT4-L%m{JTjNMfuxL#cX3=ngC#6_R)e5~G}@gh2O?A$DHNW#5)rESd#Jy$7L_iROda zpeuYe!#h~|4C_7*d9Utg-@P8}Kj@oxozgR&0)W!Xgx_dv!$*DAr3Kd(MYRiVm{UD# zcC1Y`GQ)Ke>UT$H99ZP{Xxhx~IB+z3x6uGshZBTCj>2lX-~W)bkmP@nWL99lr z8q3`vQlsgPRc?^1(cZ?=Hr)2q;K7PC0F#SG01qC=?WXC;B)-vx3cL8tM>mz!xVXjNnIn;{QSal!ix|@e(455Z|i;5=H-y|+H$YsD8rH&!u62M z5Q6*h+mw>IM}>F5Ss|4=9L5Ph-oJQM2IVdc&oyEsfUI<0xnA8dIGKR@)4_C3u;Km} z_;gmrgZw!Zec4!7pWPglIAlE?u379C3>G>a=q(NgOZ9!#JCJP?ml_y8U}zJl>jfQ% zwTabfbz=G3lxu@el>?@}RZH^Q+|grGS_cvA`(`fdy-M-hkSjp6+$s?Y){93w@bBU=iuN0IG7*5N=Dv5wq2 zygNm?Bi|dxLlNo7@y1(I6guAR;Z!J+9eI0rI0f2Kz>lM&+z!v?$7@q$!jT0y(M{&# zw1RKt6t3{M%Vj|X*m2}?$r0sFc)lHugCZQBV~01V$cMjM!6{NC!t++}K@>=Mff|mL zB6yaqhBulWf#au$p5;W~?I?<8{O6+)!~!bE`N%o3lUl&E z{HK7}Ro65v*Vj)c#Cu9Ltx65F26ecEi=BX$R&UdtobFiKK2E#tBy4HQ%GZW5}dP8NH=gw@(?lk*n30UCPCLmbzk^)-tdk3QV(J4VTJk{ zAz@)xw9YL{F3_rDn}_Ja@E>#cM23XsOafn{Wi`u&z;l*m!;-S<&xUI2^S(>Me@$#L z^_`I9n*hGpeC@TF9{u(0onQYSmjZ-yMB%!Y$0c^OjveA@arHVkhL`J8zk^QDXTFiV z06KKH?@L~>cr@NOmKUgv#`q@jf(Fq0zR^g4C>rgXh!iVFZ~7vTKxg!vZweB$fu{II z*#J1ueZC1cVp-@l-#8nfIeN-B*#4 zKFd7M$S`{(|DJii!a!L+FQBE#rMhYJ3SVWhe}iPH-nK02gJk*eHUsK?Z3$>w3{_QI zR=v%QDyuDZ-&RJ|)|PK?)1r#JN_e(KP?af|5pdPp`K^j-ndIv74iSI9rTfj3HU92P zTFp}>W#AevW^lDb05WA}#~=Q#P=%oJu0&WNC;^>bM{o0I^ENIFOYfwnpP@WFd&95yq4ZhQP+g<;da?>oJTUSruX@ zHO@#DXt$8U=#gdHZR*BBWHD5NSJ?s~FeKKi$a>R6`Q^>`J)3SJ`gPOp1SqOt7voM= zZnyOw=OK%S(?WV`hq22O^y+wm7V9Nr7l;h)w%Gzrt^pAkLO4SP^9 z?R;n%W>_%8aj1E0Yd4Waz8+>~hn*oahncQSG?V$l%vZ2SWSUcBwTV=>Ex z^kL^j9hv9!aVK_iY~0=`^L06^}tY6+wx zbR0^6vf>lGTsK`48nosG1O)^Iiv@}W^)%n6h_hKL)Y~{x1{ud;V_kWu)ZSEbvfmMYM@?-dyZV7?{Ul6meFMC9-%~e; zeTa|7?{mljqqQ>P8-8>2VMJ}Qpxt-=<)>fz^|igm>*X@^`_yJu*e_($NneSgR57t4 zl1L&R3~5@>$^KjZU(HLMJYWx(0(6u4NLva|hg(pe;D~R7EkA7TOqkArQ}(0|1J`*N z&0M)tLm3ByLbJV##3UA`T1Rds@`(PWOnZEg++L)A85j`g-Z8rbrl(}2jg?3jJT#jZAv3Xm_FIc;ZEuY_YkGKUyZTp}HH(uk z!Is78!R)Mg=38KZ8JW4S#&p|nr*163%>~Op)bRWdx-VCeh$OnS{RZjPs4B2Nh$C@{ znI>kT$yLu$&A4+$wq3IPa=?BPD%fP{dN$YNh8D3NXO@w;J`oRs#P!c7Rn5_B14Z;M z3X>Y_Zuek-QKR5-kDikJhpn^5+=~cLv_?;Z+d`MI^$_B{oiYt`A?{h%NMzo<&LkSm zn_P#i&sCpu4r_Z`NSCS#7r{{Yh)+{2DDfg=&**&9FqmA5m>rQs<@Q#&{&NBi4s zjE;%#owdTi&0})Q92%wdF^xf zO7L8Xv_C%9L%BJ6fL|3<>zrn(W%as5#&!J3M(jR)T0Smy*$Y)h>~3q8+1t70vMaf< zz5$|HS+;p+5@SNnW^2r=Hp)QV;NXtwFSh!61a#r%UdKI|R?6mM zc@}S)!>pg5b|>FwI|(dksB6R6`t;cq)13uYG!m@X6~X$_in%fp@^9C;?S@+{`$uHGei-kH zI4n4N60@uZ1sCyNLUY%xkr&{ zMLP5!$u&f}bW-e7Atu46ob)yJQtDmQ`*WNlsEaR;luVq zgk+F$p)=6i;_cHMZgDv}w^vs3o^_8!r}mZPF;is3hwLpf`iLUQao!I>S2)tIHx?>PMxn;%DLxf+ z$~opAnDg-SsQ%(if$BNwTnwcR3Qf8_PSQ0 zI%y*4$VwFh7sq~6xo=z$b8JI|{l7Ti2D(zC_-WK=!IBL>C{-x zm8h%4)SiDPD>0pP5v*r7sgTKyA}A~QMa9^EE4EEOApr)!-;kod{Lxd5ej`n z{I_K5!8Fyx{91tUZ&%u76jg9Z?Q%E+mHj7>Xo@TU524#ArhrzBIh>mc{^?4@;>!PB zaPAt5EV!sf6HZHI`pHFt2}4h!j2ZOob2VW>6ljV7bKx9}Bo zwf{?MI1~WgBAUdrs_}iwK?k9oCcTpc3O${21@nZ36M z%uvZY;mD}E$IsGN_$R{(%k|%9uD;biUCRIH@TlR(QO3c`6Dt(MfxC~pU3hrMOTI%! zQ@wbjqY{p36U?s*xn{I%NB}r*b2_dlGP6(z`!o;g%pdX&TvIHsJdW~vtkOVd6*--9 z)O44w*)w4O!w=80_O0P9e zFTa{v-)e_&CRd$zKxU;?sdsJpFe#dAlQ?3Et$m?ee3hUS3^qSyRzVH1{<50Ty()n} za)Cd;5B4`}rgY?6#%%=}1}s?bxmlKFu_aIUk#_=N-zWRLV7zs&+EKH0uigasR7o1n z^vxBuKoviyxX<|PSiq2#uVRX3E31bqL(cfKq)tPAwX1^XAwv+aFL(cT83&V6Ym)gf z e$4PBJjpjdeSl>yD=_jj9mjnLQV`M5{XdDd%$`gJ-|a7$!~ib*mCOZ5|iw} z-KZ4lAe|>``kXq%8?_mm6Im?!j7fycG-f}aE6PevUHbSLOZW5P(7|E5t8MT4+AD$b zYJBC@yhX8%e)`*^$8zr0okRu=z$M=KB2Jt8@bq|{M;|_%(v-t36@K^OOhhJ4E?oF8 D(%L$| literal 0 HcmV?d00001 diff --git a/docs/_spec/public/fonts/Heuristica-Regular.woff b/docs/_spec/public/fonts/Heuristica-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..f5c1f8b2dbc554962717e3b45cb9a9f24edf9e35 GIT binary patch literal 141416 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 )dvUAhF*A_%b_kOw19$Ro!rN>Y2LZ@;n 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 literal 0 HcmV?d00001 diff --git a/docs/_spec/public/fonts/Heuristica-RegularItalic.woff b/docs/_spec/public/fonts/Heuristica-RegularItalic.woff new file mode 100644 index 0000000000000000000000000000000000000000..d2c8664593dced0b39e0d3e0721613b5f28254d2 GIT binary patch literal 104700 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 TBzJ^0kbl+U47hQI0Kk6%XYVT3 literal 0 HcmV?d00001 diff --git a/docs/_spec/public/fonts/LuxiMono-Bold.woff b/docs/_spec/public/fonts/LuxiMono-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..8581bb5aa4584a8281f1ae761b5fe5da8352832c GIT binary patch literal 26560 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 literal 0 HcmV?d00001 diff --git a/docs/_spec/public/fonts/LuxiMono-RegularOblique.woff b/docs/_spec/public/fonts/LuxiMono-RegularOblique.woff new file mode 100644 index 0000000000000000000000000000000000000000..26999f990fa9f9302762b55318c27d4d24f26bf8 GIT binary patch literal 29300 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 literal 0 HcmV?d00001 diff --git a/docs/_spec/public/fonts/LuxiSans-Bold.woff b/docs/_spec/public/fonts/LuxiSans-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..162621568b5307556c0cf0539c7e4ee3b572564e GIT binary patch literal 13592 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 literal 0 HcmV?d00001 diff --git a/docs/_spec/public/images/classhierarchy.pdf b/docs/_spec/public/images/classhierarchy.pdf new file mode 100644 index 0000000000000000000000000000000000000000..58e050174b65669c9d5d12cfd5f0420e14265e24 GIT binary patch literal 84078 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

auKIU$nHF%T}-@XFY!Z2Q^}R6X2S;g zW*$#2to)>xpcsQ+CpY0Y;JP9zIsKMTq1&lR073oH{G$^i>5dR1s5A%mboni%oZeyY z^zucddtJ!S1~qM{+tW{mUNQXzczZg^S&~>@iQGI+L~yvXVgw%vHYGT`Ry(Ab_KB@G zdI6utdE`z+f((P74w^V?3ihy&&K-fb2R+B64C^6+ON+-4?WONxkY}T=94Wxz4e}v; z!w%gvm{E$jvrz;~$g?=MH&M;BiJPH()F_gM6ogV_B`!!{^1`owBKeY4{b(jRY_OpH z5(iOy#<3~<%M#IixX82l1W;}yrw~5xb42_4LevzbbSS*Nv`seoteturEoL_nt+UVA z4DqZWB0RMJg-vR;PwpVHSsaM-w~A;Mw~gS-o;FU2nnnhfQm#jF@b5+PDSrY0cC4|X zn8yroP+A_lh-Qr^bbD1NFupI%q=F<_*n}MT`co6^EKWL~6j@RYHnbmyUV= z0<%d{s!jxWzUm{79>qBC3DrkD#XhC9co(Pm&MqcO38G@LMDQMxM?$=*HBh_>aU&t1 zfKnV`fsz#L2z8buG!2yUP1s0f$u2mw;zZoYnsW3=NTGKrPMr(^&lQC{EiQ6oJ^|X! z0&e7TH!+&QDQ={b*MKCgzAgemN$i*$?Tw)f?agYURN1yVa%9asdL)KWzSJb~029a@gm76JheqN{Jw(X&)B&` z#^aQ~kImLy2YS!K0p9di$x~bDuTO91Aw-W$eo9F^es;=TG`!`{jFQRJz%TkZC&jDc zkB1K?8DVd67Wnr1Gjn}G=@H>;ja@dlxss+@wa4EwUz3Tt{cSi--@OpLt+eCn5y;G= z^RB;>4uh1AZjb$wk&aF|7yWgW7FnbGVQC&8;+KNyYx2e)uV*PasX5G32MLc)SbLSD z@KV|wj4OnsSoEK<%TvYJzAoz9=TC&M!r}Q4eX1fq;>ohm{vs=~D^4{$W;XQck7l$J z2tFmMXo~uiWVW*QBKj(AuL9n2Mp<0ZTroWT4LR1Yl?{|1#SIj71AYOSn2-9qFt9@z z7dJ-+jI6i*>8Fv*RQv%ff6Yq#&!2>qwK#IfVIG;9`^D*X>?nrAtZHS;>7gn&7ruRa z%+nkJw<)l47!EjM5DZ3 zftAVxP`(VlBQjy&SN5Y`NvS6@{9?}}Z;(Rw9Xbwi_)`Z*9yW3tA)=YFXd5+vLL7$%YYF{@lk(k)!ps*ZsK4HLDkIsoJG8 zV!k#POQ-){nrn2GsH6omyr3$ly02U2GYwg0d{K$WW~x>nQS6eQie8^%_q9xn7^L@? z9#V&qV`dhhVn@kM`ckHcO@;FTu$)=!W*@3p3(FAo$*bnL@uY5WR}Ci= z*j&{E|1?loG;pk3x0ESmkxJm%iDZQar=r&QK-c@$FTXdv7*+@)KP5e`B~}Kv^BrIB z5}`ti-C=H0by?!No9Jd-$twkR)ryxbsO5x?r!$;4&BLej1NYbHc<(C=SWCpP;_?Cz zc53@*nIys-VN8=AW$0Nd2kN`Yjjios{_ z-(;@_7)Op7pj<-Z%;uttI0;l<>QwN{=1Ru7kR{(g==;B4*K~);1i16BCM z&xu1g4~1zMP#x2>q+>hyFovU|#nEq=&!?dvho8921dhxWD0zQ37ox?29Z_vC}f zt!x`aHL5&(|BSzrV;$MF^tXdYd8X9BMmP`dBeIG%wJ6~M^TafR%^EewFKefYgCCod zYrHZSE9^<%{CNbdY~A^2cTza-okXZ; z7WAzmcn!!L?I{)1*JV_w>fd+(5axdGz2MfKyZ&fuGuNkcdci$$SKt$wlmZwJy393f zYTC>YsHxWg-7j6{3q^J2keAgH1m;%Z{?QLrS?giK=2=%1z+MM!X5|R8?s?SHv4oQd z1BbYi2wDFv^@94*+IK9!1okzUV?4d!22SO?r0l0_RkLG$0h6dX(`ByD{32{l1dixT zRRkc&Vt}c3Y68}?CR?GZFweJD_>1V*OVz3{r1PkMjn$diJ2wFQ)-=_Vh*;2~Q9*qS z)jTR$k;j*b3e_L#fR8#gON9I7rT-&oo(@dPOr1F<=>#E&y#il9r&d*8rWar-g?bXP zP~|(18ebt<(D!>8K&wBMECAt>KWj2~h0_BLuW6k}Rdwro0{X^?Vgx5Nd&ML6|MWCUb`cB)-*f~e<@mgD!gfvqX|Gq#Ljof_B2NpUT0j1Np zUkPe!zn_xhUfFN9mhG^a0t+&Qz(}Gi7q9-Wu2j+cE3deg_WN2=ueStDm(RW8rcDGr z+=BuKMuyYP92-ffa(6l@r0K`B-<35h9|=1H@YvDwS&uMp!J!DjSn2Yd+rNB8#r8V~ zjYWU&x z(X4O-^_J@`_V0?INYgaFk0TT2Is06B_hZp7CwLmX*NUCt9QPJcS~weZ%x|^hb*qYTo(3ugnv>Bod!u&E>+@lxPv2!u|4XzJjj zRgvSZ#eIsmgwhaQi-awBHNB3k{flpM+2zsDbGm%t2j`BEVhe&gft_R8f-^M54`}>U zJiT9B3aPFFzN-G&(h?NCwK=l)`?DK1?8qzmZ2L~_@APK!ka_deoOCCdh}LU7P#(&^ zGi_-3m{!(rmYTpxT%10gg~F9$B>g5k6SZVJlFA31TF=N!{~vC4 z53>)AENa{vShvk|5@!zqo0#ffM%OlPm)pR2=K4>0LL0ZuTq$EWDbVk?w65y6 zHz_+~r9^C}NI-3$VD}hZEuSu#)q;aGK(;V8sCZzqd)turEs&D%o6?`fX09Xz!M5nv zk`#;b=!n;nhCoH^SU0N$p>l=h$r)MI2c=WcukahmpRvEw59M@T-p}=4ORhH61*Q0; z&PsEp8SN)%*VVuAt(q;}1-=zvBNCg>&q>#@@zhH=G7s0xkowFVZSZ4<+J1H7@p1*u z83O&Y@QMp1$A89chqH5aw5C*&aZ~NH+ELZ8kD=IZMbxj+<_OG>p~RrdO|J(f3|v6xHOZ( zW(+4||NSazj6^Iic9zHv8Z6S>5`{B^T1MqdL+ixfu4k@n4;ZgZ&*vM?R^sKj!&Q#Z z!`Pm*V{qPWvgv~+0%dYj<%yh4J-U0|T#abgv4-dIOC^T<`6%IyMLuQL-YSgAFVVOr zZ2cx&weW`mWy6lXHUD8(zPcbcNzeKUiJH4g(R0iGHk!y>u?8L6)rfCNgur$>&(B=} zt6wn^NN1^X=N8gFnrYggRH)}t(MFI>?D^IE+Bng$@+a+c4P!f=4vW8G&}r*)30W#w z*GNK^{6G)<=7tcu

YW0ILzD*0fH;ly4Vy3P{xI7M7PI^k?DnfP%~pqxN*!PS7I9 z!?KjNP=WJlvvh=B%eNO(UbxC=%h9{@rW!v~maPuuA~il}Zje5?OK(DKz*-halaBEk zb&Z%KQbM$+Y`+LuE_^k2zQ8Cf54fjtF2#!uN+D)&j=bMV8fJ~9T!GIo&6#hokFBag zxyuf8zAzdzu$}`FlefcKG}MF689&yRv;V=llnqOgr_%V&{3L8?l>GlEIzMbO|!9e}101sbn?1YaoseT~7j5onV;;=@cz}X^v&Na0d4{PBn|4IZN<8jorD+z@i>mvYb&SkKwg7!N z)s*;i^JaDjcl?T_o0L3L4kV;PoanDl>buCTasQ{OdIY3j`nP)HNG%!rfg}3c@pUJz zF}ie}-{C&E`>;d8s~~(Pumcx5vdR=p?dq*AWt{NAC-~)^Xp1TpSVpU)=m9fm`~21( zn6lKTi(*9Wl9eheHFM}cK3PFCW)at@JVVi~e3n?pL`zq<@snN0ZC*R&BI{u|Y}&%n zwTT53ICw7P$w&E-ZfTL8=@<+8H}W2Ykc65s{<=l#@C?HV*yIkH66rds`mkT9T=ivq zp)#7{*zDeObSzme7^70=rtH>Zq*G41+4}@_0qYp?Zibh!#x4!k<95s0Tl%p>R3xM6 zNbaTOIgsRD-~4#*FP((?4tSfj&-F!cf*^Iv6Geec{?lJ~n$*yD;_rHuM=fBQY0IpzjcN}raXtz5&-_D|&unZMh5hZF*x1gpm_AbGHWB-c@ z*t`Ufd}|oM8*J-2>OR@qXPcMCe-H~3LvPfGYi8BY##P| z&q9Ts|HZE7Ywe@WU9F>H6}7L?Wh=&3*H|;LGg}>__Gz_Q+46y!j&IBq{!sZdqZ^JsU9duqGCNGTSI=jf|`u@+e)t;n@D-8 zTG_R3iql%oP!v(%&c~oSLAbnMf1B9D-R(>B!PD=v!a1?*ZMJ<-pR91LU*WBHR*W?md*?YGL(t^s+G_ z%dI?OC~eUOrhUr_qJ2v_@vIERzqg0At-g|mnI7L6P!6m$Edu?fK?|i_F%98s-j3pH=9V)2HT@438$6ha zVxM`!7R|@Z4;5ks4_4Dd8~nNcv4XMJx!goB(!qd8lQE5k^4%Cl@ZGFp+UJMC&N{FX zL%Bb1quamzSH={@9$ZUClbFLw58b(jodpde&sMp+ID-cfgj1rh;!ir6cglmM*XW=Nsp2%X-d|}j>2Yam?;c_8TRx)C zI!qHoLxK09rIfU_t(Q`U3rw66hPB?3hPAhmeC*dS_SqZAvkry0vmjq!vWwd&_HW;D zL4_JdHGyJod zhGoNc_RP0dEdynHT7!rw?wa8A3br$vUU z?y9tK)(JZmS}9-lm1Rp>2kR#&9RBLd1~h%Ubj* zL;LJ**V#s8DU#E&zHwELZ>m4ONE`TDYV; zPz0z3<*(`SM*^hNd_b_HRY4!=Rlu%=_VXQO4P+~Uz~(02 zs`6;1y%TJax3xEdn%QfpMp@)9CQariwq%3=604D z1KT6`pFz0{CYmI_K8F!33N@IZc~~f!t16-mR+kbC|L%r@+F6iUF%}O1!s(A3kuwf~ zO6C|>fFS8+l_SzCGEqn~TmGl8rap5Q1#3kl4ye@ z)T}j16o9&j=|}3o4@nKQQ-A3|C@A|*mbC`RQ9!`73pS@qCRh~Mvj(^FbFpIFa75m| z7;BQSA0-hi`X_0U6f_-l=y9@Q(6YL)V(66+AeHvBMBX|VH-4`Fzj~pgV0lO(9x2o~2o6wD!iV>L;RjL-({`OxudH2OUBnpa`m%PzR4< z6Zo%$CQ{itqsfJSvg)OP!wdIdWt%>u0(5F655|8`?vSo;cLawX9L0kfv&haCSi>-q z&0Jk_#v5p(KWTp!HB`-h0tpHECiI6Xw9<%vGP@z-;Yc={HqQ-0im5BHLf=W8h|F|~TV{x-0YFA>mkQu{vJ1{14j;BuKXuenvb^W&@6*f!#4FgN_wEy8 zyv}yeGE4B4&<+j#C}~SkP}ZoK=X4aWT-eE>&*Jx*gurQIn*yEcslOOb2Z@h`b;-7Y z0Rx{!QNF4AAUvt)a^pGnw1Cralns1oxQT*W8n19J%ZX6G`extHYU>sXiH3=-eS-t$ zDkkkMXg4#l?LKspO1Q}N(BsdXZ%)#7oR)(8I2U1S$B8#dzwDYe`xf0HCpT=H6&Vs0 znEQQ6>F2VLn1W-Du1Z{o_4n2gXWKBijmFyPgWt>BkZ+QeRQ;Qs7FE}4N7<>@?nbPA-LT0pD6X>MC;a#kbn%`Xn1_D`MJ*b*)0Y@AI1(xs7qTYEOP^!5KN zy@VIsVtX&bi%64=_f2KLcr-O>xO(#g${*>WzL6=p|4+$e$vM$CMWTCYVSDdmWm~#& z=F|*u3vO(>?4KG&79oGPoD*2j8-F$dh=EcIR{m@GHwm%&rWsD}s7=8(Kvaa|eraQi z@`+@5WorKGKcSFF-JJ7@?achNxbpK^bY)Rs_TviB@DAAGziqo5C1 zJph2c!Fkt!?8n6ax4QB_G}v<=SIR4kOv-|Y0CoVU|D_C=A_7PP)Bvb|4E}c)umG&( z+@KkiH2|^LaUH}~WK0g|Jdntqa%S0U{g9;&qaqVTIw6bK|4D`@wFBX396Mp|VTsD#R%+%K#w& z?YBPlALKQK;UjGZaTwj7($kTGGMe=b1y&eRkwvTw;y>Q{x(y!=sq!#2vW=2>Jm(1K zN^Vz)NGt$7ygt6sQyBg+7(mB6x_o$l9^yRdoPv`*S^mZ{@v=88@rd*Te5=qS=gzCx zz;O-r>qZ9ZC3Mqu;v(@Oi2n0M;;UmCH=FQ2JA{Zu)_1Zawv^Yq?sXeZym^0Bt6h2f zQS`n9&2_tEVmvWQ%j-?VLNxI`bEWt-q%beUjv$y?Z?jv zmDWJavjS+`i;=dNI<3Y!W!4UZtUUDQy0zuoZm6x)4-PA34zxGzM_n-ri5RG&=wGy$ zs^Rf=_f&%7PK7>ei(0;kvPXrD z9Zkh7?Mt+lO6gk2T|j%bo%406Ga{V1^-Z26f2-kzrSKV_SAP&mSBEwObX!CL4AyEt>2uoS75##1cXJ3jxP87EFh@VlWP z>4E<)Q$D7{;t}uO9@L(^6SZ_mT~o2Bkhp8Cq#MaTk-3T}W1x=gwCd`{AI>Id2|gxnzK3)3r|B~2WG`b9!wfcD zVS+0q{u53Pjz1_I*RC`bXHnhsj?Z-P2OTYK5lHNk&ucZCOuw-53vmwv(&xGFIq@ON zl^#fTk0s0^9lYfk%ZwZgRb{lsOXgWZ9orWTy4`+$t$3<`3vYV!znBT|N##8@b0yMI z^_^VC7Na5@`s3*kdoM=m#OOC<-h!# z!i5TUAkAC8U@jB8&k7mx-7?tP>5wdm`I`UHn-+_SxCdfOut=6s$;B+zEAX__{SCNs z=Q62|RrS5R>D^}uA`$%;hU{N}BEV2H2MU+NxnWv|&guWTEuTZ!;nQ(<|8NGa#QPdV z`^OGjz?H)IbFPb;o3d@dU)l6$w6?rEF!`L(uFcpvql30~eP~%_8mIvOi**(Hh+`kB zkvEBaw6OUsqHyJf`xebtc+Q*{Q=Os9J{coU3r>H3F*CAZ1>3)()#;Rt4edtm{7e;& ztd%ahR#nZbRfP9P?7lO6Iwi(t&?W>-|GSE*$_M(_J~156r7pQhbCFePN0=H-41B}B z-?`sPQQk5pZD$VfW5>#*Pq`n_DeyOmI1Ur)qMB)6Ah`18tumDJ_Mat;>l5QyWJRi0I5jESdZ$HVK^qOrC~T1 zZ%P(WWKAls|D{2^ic1fa6r)Yr6okVu9=T%F-Mwa1(6w;3t77ntnPidI9YAn6G%Z8Z z`YG{|9Tm<@3Jb$XttA(WJKnn=HJ~CA>C(V`kV)&a%9~j=t$p;-c@@tO8opJYfdQn} zptexaudL@fEa{C+QkgD3Tcwq0K159FwJ()GZfev2f|pi}(YA`*F_6m0AWTC1GbV9NAIH`}Otd z@t|TWg06+KP+Xi1Jnu}DFGt1mmBgn^s^ZGo<#@{JL$fs9iB>XFsk(;9Z@*cqwi8tF zA}{Gt3j~T)OCV$^^W7zkYWa_|kUby=KM=SiTCxjE(enldOS#*nPjVB8GpbNUpdisf z>N{3@hM_>H>4LEZava(`!BE(^VukF%)Aq%d()H!=!eQ;Xn1+P&%k_mm7$Q)RWda*) zxDer`RQM!(atPR^ufLjpyWSrNr3#pY5md$na?h`rz;AmZvUv36>>=d?nLKP4$swMN zS8z!P$C!fksMsOlXREM~6k`z>)xo0dIHBp~f#)G9^@{38+tQ$JeB;L#R21h{)a%r|{R7o6B5go%F0;q2?r zL=gmqCIL>E1!^FB?7(1|;=&+rC4|gQsI zc|yvs)7pd=%d6^`#XK zW_rL0BN9~aD;1cAAawe3-+0w1`KD<^411Abre{0Q?$7(q+=MU~pwRBg~i?pgl zY&~;vW^kHcLjEs-4=+3QVIlEcwn{-Z5-#1j8bAB)o(9nbcWSMRsx&6ve+&7p4x=7A z4yi^7j`*ott0Wyrsrz?_JSgkwk3R;ikv9eleZPQE*}H5*5PqSs5BG2VCEKXRwQbrJ z0%mJ?ma09m1Fm{(S~!{o;qVZLj~#eeEoWbpdf-P)WYreJ9#7aq@9Q@f54&zwA?!lG z>}6(d$;vP$EWb3S{Ibj!A={UKgT6III(hYBXVdJ6ubrh0T$J#+}&hC^&KA6wKk zy~<AkF8zHK`*5DfCH<-t>7BMY-AKWh96*^gJ zwRqa7C@$;N)){#IT%j0}mGiHO353<1DD8-2E_2}i`;PC)M27~|W>5h8HxY!V4aRn6 zb?n-z?!+xug|V~v8Wp64@FJBz7zd*0GtZxRcw$Qrga-2H;nE>K@l#ARfQw6M(?i)4 zs!)93dLqMx9IDx_=wa-9K+!HkPd*?$0obqE!?xygLvye_Cp!kBq*V3~v3q7yj>xGc zHEg2U)!!yz^xL`rqA~`13pqXbNXPw2kQVYjN@*g+{yDE8t>N~mD4&D|LHRRjo--U% zh{HM^e)7+gC0h30*YCUmVC-1avxJy1K~}W|iDJrS&?SArVOCDnPNxx!2z~y<+xg1T zx(_N>h6McV9!9{NB@Ru_|jvc)Z!YHq&5_etF`UYW-HB2`Rec1qP%-pmAeT_0TR(UPZIR=0RQ@vD z=lf)tFIKehZg~3E2D-WXXp@6aiCNLGN4v@e1?NMPRnRsOp)Sh)Z^tg(=sG>69a!&_ z`F;6E*sHyVZ*iE79`1v2bABUu&ycN1d8??ySmm!BLoi79a*J>JkkkS`^;jw&Ot<4j zQgnw!)~`iV)jr1m=9<;oB}nq(+MN@OgrBP&8y9A$T zK&aZ1Bo6&>jgsU^2(yc#+U=@k5>miRB)*85yj_L=grZ8Iwtc~rvu@ebJb!Cb&zs*T zW{TY@0}Q~I?4iqFJ%?_M!`yx^JUuo>R=JN+^kGkv@nSLD{LBay);^W+6_4$WdO5lY zWa6iPlPH{}*2#);PLt=W$2z5KnZ#DY|Hp$cO{`gPKC%Rr32LJk7s9FSLB-%zoVe#G z{NpD%h%Lb;E4EWTtIW-=gmeD=ryQF{;7$y2+z{;Et7gcD5|=(is+V{#ix{n{8L2B5 zS^TNp5ZUwxX%3GDew7}}4$NwZ=^xrYK8p8CK4vkCbE`fY_+uxfUn)>k96*6Ykk1$X z?#Il=^Z%!{_W)~ZX|hfqTAB~vhsnHDXY~Z)o%=K5E9SS?qEOM*%)d7&1>QoX3Bt?%T#&W%%sru6i z&4>Ndx>&xlbt@LR#dll!?X?E&M;<)GChrpbB3f zJQ(P{C<~idIgz8uC;pUOY&|3FO>*rt^u@(HOPp*x(r#sA7BKJ!6@{nQzO;HB5E12N zt(|QN))1jOkeRk=e734XG6AA3(4%KY$kPm`X~`O*lRPV)wP7O>lenobtCXL!UYFw@ zjpMC4B!5IS`jKR-ZWMb#E;!BVh2lmVd&k`3&RN*-`NHF+pKg~4_KjiJzipszbNcFO z)|06Z2#t?Rb(*g~^JM#Csf{$~!+D3n&4ZE;oWM`LWxGv&{gCs=%1wKY%*XT^g97`Uiv%M&Ak$@27{AXGZ`dqou@Tpl$uXveQbU*<57e@0GS0z z7*;Yjklk$oN%&_&bbQ<#Gy1BZz0VMuPz68ZFuQ1H5}-3)PI|2lt_&?X6NUxfWDzWp zcvqvYm*uM$&q}TZ&PepuVlv~jnNMV0^-X4_Pf*w6g{bM7-xE5{YC%Y4m4~T;1&qTF-+dl#U1M^b*J<=T>=y8X`Y^3s4&J?fQwHL?K zJL`;f^1{?l=0AEF-e6|Mr!$0$XVr9#74$gEV>abp2ehX(bDxR=6-&^?#AnZ3?T>u4 zNg;tzY=D;7G(st;s!7Z)CSHA*k!X50BeCFR0xRqct(k2h$F=xCKb_XhIABf>jl+jo z1SzuCQdx8FYv}lloToP1Af&LKV~~*MfTl1_$m+BL0jMjsBxa;M!8-HK;m< zTXuM)ahv1>sms?>-02J4^BU^Gqu7k<^}vZ6){6({M_J`vFo%nq;m>eJ-5*R6m0!#s zp}<^27mlmjc+oiafEcI*x4ox@Ny%(GK(cJcCr;f)YqV50ei+g_dk8FWttcttC3(R$ z|4zHfgdX~bt|KP3u67dfl5Op}dL$9=4p@Pq0h(-X$zMI7?_5MxC^N@hR0d{D`7Xyh z0&j5Ig!J$niL0 zc3l&ytwA@f8Fp0D*;x6N$@4^rPHEYLNJ!#NMm+iJiq3aZ|6)+R1T>K;(tygHHwt8@1Fdemu#uM=~!9DAQr|tz#z|hJw4TT? zay@P%ap$`aXezF1OP{``3JPfcEJsRPx0`9M&07YRuiykP$J}f5^w~6I zsgPpqaqDxlm8-n0PJ2GaoVi?qqO-q1yVKSUDLLt5;(Uww5);UE?tw+w)dfNS^ceyd zr{H`q@8{>G1-+}Eo}j!GPB*fRk|Bmm1vSL==G424XQhlCnN+8@L9aVGk--ak3n7F+4R zdq|(Pa=4ham$SGTd+t`!(R4ZtJOp}I_M(uCRyFKxShP~StjX2dL2#CDQ%H4i_yz<^yZl_cW zA3Ks7(eb>R(^k{@eb>k5=B{KPxl-2YyiZDb_0fs-c zrjPT2Q<530_61)QDxyL~{>EoPzg2dpK-GrqdSz~wyvBTM!oOS3s+xM-3x*~ zxv^dm;`hY=-{_8%c9ka)+-|O) z1Qq&zYI(~ZVa@p>+ceX`Wb@3leL{d6{5TDVC4&o=x2N@?Tg8j@X7-2aa;dWsD8fjX z2Hs-ZtLQc8!)+!uMK#JTbq5oQie28* zB*?&X`L~8xm=17SsYK}ra+!I2+<4`%Y6xmhde*b?aX}@zwcC|ozgS=3rH9m5o0qrS zLZAMW8^~lTR!#Hm(peQy=tiR?4 z=UseDb;;vf8>F?6Bd?#SF&^P=yU3CxZ&m8LQSnWnY0Rs}WaTEKcZuY1XOt*H794z% zj?Ajd#ZPgA@($(VC7hTji+@IFFne1$UD}!tc=LMThK=k1AI}l$yCdz@hn(xkLu4K+ zbvlNVANO{Cpd}ZoqzTiY^{KqmM7MB!o^%yb`i0o#)2-;2Hob!q&&x+InO$rt8yFBM zV0O}a{I=7E!pr~a_HYCae&uwVdm9uZ0XBAKW<*WAL$c6G){089et8F=d z0DorC_Re$bKm5)8DG8P1kib!4tCfQR71|N13Ih*Cq^3@1HQ25(8TOPK#IhY5INEzD zLa!}YWn-a`829K=5_|gOW>H1rpah$#=D<~1;i=QPUo@xf#?@0As6V~kU_8!Vr~nzp zAK6atB#5sq;di>_lI+*knlD%{H;+!YRo{6-YanoSfQ?nQw~UsDBhrms<%Z9Y|I9SU z_Uj3L!-x4d`oQEn+T1s^FSp6}Oj}+MwW4wNdz=+C*2-5Asbl}dB^^-&$kbEI%YDD$ym%6LO!hV?&)T-+mVEbGw-kDdK!mjSVR@^d(wzXl#s^ltLMD zOpryG`-XigV-w@JLD^+B)g$>A+^vJE>L1^8XWc4_4bWFD4h?!ziHf{@R$;Wrx3x&_ z%OeBsJ2P~R?>H>RCR{%kkLJi77#pH!!kqECzW{ctGMY-z)X%d4NmRgCZR`yg(sQe+i_zJq=z9kQ zVN*pP1si>&D>lbkYmjinXj`vOkb|el5OziDGK7KLO=_2hms-uqYOKB1Qvf5;cS1xo zW!~|6W+{j2SMWf?n0R<>o$!E&>zdl<8Zr4V;w`~f-KPXM7oAnbQm|9DL3P^OTTbHF za;`GwiXq6xuH2hKr9>2#3?koT2<7w5;&vfPSi*G$H0_{m)#*V|mSs}pyh0rxYLNN@ zRa?l%#tiqE&#h+e^VLycCK2c;>trQeoR-OBwyD)5WxH{yQ?wWHw-)thjDlqx0S*2t zMSt=lm37|78v(mCVw?^ux9BJ(5=c~xuF~>04O+-NFtQ9MnOaqY9fll#aRS?sNi(c5 z$ylFTYeEQ+mt=EUu+b>FmY7}A(=Yw%zE4D%ocNt^5`mNp@s;sX6ken|DrYqHAD?)% zoT*eR9i-so0O9Mmh3mXKx%`4{f*0os{Hfrkw^JbM>URk{AZH zO&>l>N6<>vzI^ohqB49dPKAN%X$vOGnUq(LzoX`q_#2&sBqYLML~XNZ_%^K>GGrn? z$17htfp3D(1at|C5I4i3K&L`t%Z>IEIDVm&Vu{L)>fXV zpWPvKcvHU_Cs#JS75l(ux7ASZ#+u4&TU+&S@H_&(YUjG+*3hA)>_YP0s>_@e{E=GA zvZnc!+7u^}52#$$mrvh*KZVPgd47DEaARa=6+bzT4pG~oUGMcBLynCAF29M|>NTan zQ>72Wj1QumXWd}2Di3OJ}o};DJM=}G5?UdWa6h) z)}<4Nzs_|zr*GVmZ(;E|w7tx%TF`M?_mr0=Vs-towN+1wnDc^WDF<7j=mI#M>NOkh z3)#$F9G|uTL@2*A|ISK8s+q!B-9r{iN8VX*!b>Op+>Zr?(QX|vsy`+BAzP2Uoi;-D zY|YgU4D#*!QvL%8e7gg;p@RLfHTgx7@<+!{9qTWHKD`}z^Fvlzvt<|MfjNz#PHKLU zH#_ovYthT`tHBNqPfU@Jrn{9eLA&FY_%l!K858wF*OY1A#Fa5mDo)*n@V=*yQyw66 zgStAnPL)m+sUt@R4i)Gc4(QRHSjC?TI7)fR+fe=UN1itm)h9LIS$ik-W!WpgIV3+l zn}d5}$($*@5Gaz%SIp*N{Cc4EcA zznn7B;AD6kzi!(s6`1Y=MiGB-Sf$~DONk1nBj|9x=alN1HvuJV$4CP{?|QRzk6n`a z2G$U8E!bclvFAyuaql}Dq{#Iy5kviEIA}`pOt5bCD+Bx4^|AR2M}j6^<$1Ojn3_N6 zb~C*9_=VuhD5%AZ;h6OE*@s!NsnKC4Ch|UUBDu{DzJ8ue>3qS0;alUg{OO`u_Xz|^ z!j6aW$@34r!DD=_{t?v=D|^VpR*Gy8-C^x@dY;g0T|Fm-?6(>psTaZn|$SGMMs$4_?Q5imCQ! zI^;;_&4YPa18jbIo71LhFKE(V=v^ew4%+T!DAvv%jqMfQ65+v6A<$l>}Vw z&}zPb4EHt4o;iiRW-nq>ja%zwp7uH~QkRgW&??BX6;p4?c1amphP%1sEa>0HU#|Ng z_EyYkw#>MV=v2>y-rFfFLgqOG1MVBUWArl>?c1M&Q%@dyU7jfr61z>`m#o;A-Fnh^ zfv(mi8Te`npOT!jC zP&`_SY^1uanpULgmbN&k)SuF_-dWtH)#N5}>%=Dk38U8)!#0PcQk_bav#l&-Y9=J>Ei7#LVRolP1EXn)CmdtkmCdpFD;{33`F!p$9?&em~$G1@2 zqt{hz^qj>#FT_}`gJ3$v@B3m)Y91AQ5ps26X5*P$GS+%lLhk?m!N4M`%o|aso#)7|2n zXUjm^-B}Yhx>CeBFl4wf&hQS$#rwX>+TwIUJ9Az?x4fm_5pmHz#}+y3-XV4;5*sq@ zvKEt=$8j!wKw=wvl$jhz&eqAiLi>rE>u*~R4d@jOn`O>L8<YQ5|Ip4C&`}PxUEWl)@5fT z)9CaxzeNMm?B3W(ewyo)kQdJG(9OnakMiP+>7V~SLvk8l3UV>Ml5P- zqE{BZK47`;foJZTn)mRUvs!gEZ(~s^v*Xt#7R7bGC94P&&KC7wt72)F=C7#r?1#S@ zV3(es>0>)gv#8_9`8997(T4nd=Y+z1>P%*i$mZ^Va3uERy!+;Py5}@=r`P5(9>OEb zsRfwbJYC|v$1Z>124fbd&p>s}$8;Qn9_MQ>CzemXA;p=42ua+A4C0v=+iCf5_R>nsRU7E>>r`eYV-VppH9yH)b6&8FY)w&P(hgr&PvrJN}-VL62Ze8Zv4zVqi_i6oTMSwoIB<5dr zTDjqXyztFCu~kaUrv)TPTv9R{U752PH!GvuBIpY4xSk`ib!rG|e#9JC()U0s5IUND zn6s(1#;>0%Lay@3f`M1NFSoV1wk{ODP|3h49b$@ic15U`uK~P9>a4)8vrh z42d<$`+)9OIx_ZfNR&No+$}RL{HRge`UH6jN8#ebnCypX+E=&0tR{N24^3q5_d%r$ZDXF~Vuc)iM)KtDc=aVdlJd;j zT;=BK!!Hp`+>QqBt`=U)S@l}XZqr^j|EyB@IZ&|SHFxitkxxQdw6FqGqyOh(R4DgB zuB9{R^4k~@H21xX`rCZj4|t@rG@hT%NQIbnoG!8o<7Y5_qvzRkMpn)@>1({W>oE)& zst01tTf4iwQcrR99z$9}g>Kxb{4#47W||whVw5LkDOj$*KkPHs(1|S3zm)b;$ZU66 z$1#dBcV;bYu6e-JKlwn})D*2rqtOGVSk<>tsqVfV_@}9D&-tc4*?zifnNs*J$eP3G z*vG3^;Pl_NTP89(PIWyutGjA-N?DBkDPu?leMvaOi{(xu2D;FPXToG9dlm2VNNaFQ zU6asZw}PI#64o8W{?sRtAy&NGC{;o@t?80-^V-bC0rvOibMu-(1dRUsLjRW&dY)y` zC`#!{ktgLERytYteB2F9x<5%7nlX>Y4~M6Im_=hQfSu-|?z=0WGrXvTx#2x{oC3?P z?Isa-EGVUggN)Gp$~WkOGqY2S?K!qfwa+pNeH+|Ix!c=`^8WWEwi zltCu$A^Lb8I$UBxjxo7gX-5Y|R&EBt! z(eFZH%=0!#tj65rtGvLsawg7OuFm8;oU#_RdE&)r?>vXT{9X0S=sAT)$#qo33(gMulgYMjg(N12;T(L_dAAb%R^jC3R-PQeE zn4)&;c=o#?)JI4zsIT&Y(!p@Gc*midp66Y)emh*HO-8(VQoSwWh<-!}`K)w)>glpCvhUsN-O;~Gg2>!Y0ms@l&C%*`QB7>PgbL4G4i2Voqh7azr+c)5JcCg&jfYy>rv*z1&M?_Q$yOmB?NN!Teb z>}XHpvp3h9cb_)zLQZEKDE0_&55Wa{xcGyCT%hYwFbWET5>qq^fkFQO%I^b}l;kWT zgFNI+T)aHw3_aX^T+{+1pms2zS`i};MaiQbz(8fNM*t3r1b}8>IWv!tz|defj}V}* zNpPT>xd+Zp&O}2CDyQoYjG_jWv+#((0o~LC{Q`r{gIwG^pa}H$zM2s@ZF8Ip4uD|3 zL$m^ckr9e}1!ZMorvM!Aun?%i570gu#HSO{P*MUO08AOWH|G$joW75H2-FTt#K;Wn z00l+}1%`x!fzkH6!vE^J-&5TM=i(RW^<#+di2dE3IN9%y`c9m`W(}4zHZg?4m6i7g zCgMPBXeX!c;%BC<224&)+r{7C#SSiufx$4~UlM>MhAy~Zp9njctUN+d9t@L3Adv_l zfgxbT1c^XnfCPm`qJabshba&fMI;hPV2Vg$ouUE;7{>K+T{= z&{NPG&;V!@v;z7F`bGjFp(J4?ktPu&fsyEw940X&@g=b(@gq4+5&?XwNODPTk@Sk4LMlMAP0B&4MG7TVA`K+fBy}UbNa{;^inN_HleCWXGid|qdolsiNirHT zBQkn26d9fjL*_!( zBCjW3rSKsCKp{m@L?J-oM)98F2t__6FU4t!K}tJ{$CONzmne294JqGIqA5>O2~Y-8 zc2K!dR#H(>U8h{2(xzIZlAt<4El=e|)kz&gb)A}?x}9o{+LQ)DEkS*O#+KTTdW5Ew zx{5}aW`%l%#uuzcqexQ+K1YM6*#(c&JOS&_BEbycY}ypC6?mL>2wX%fM<)YbppB(V zqD9ko(GAfi(ecs4X?y7c=ugrK(6!P}0y$O&Wx6JMZ-$HX5c)=jb$S;D7KjD?ZHA+e z+YD3;j~H1Q>>xahIEETXDB~c63ev-*2ytYTW-5T(VN7EtVT3TwFncljFljKqWckXfFkpXny^dDg?sRLmQ!Wy~Hdc5JN7k6D`85?Dl7Mc9^DQdm#2JF?8OerA8k zs>f!{p~8BLt(BvOjfq{7Q-m#y{XAz5+Xx4Ui;i8L!;dSG{U*l{*9Hd*r#5#GM+|2@ z_dLf8mne@brzzKYo)ON6+*G{QToT-oyaQaoFT40mxygB)`MSA7cn0{5xhH`$wr(B^ z-WCB9o_0QrKp!ufuNr!U_a?stbcm0izgWpkf8|Y0VAR3B9{)l7uFSp ziU$aHh?Yu#M0CWYB{D@i#BNK9is~IulDsea;=p4mV=-fKBdIB|KJg*x=mS;~?lLR~ zMkJPHD#TqSV`VkP=cQ<6$0UNJF3Lqqe3O=daY`mi--q3iqLa~sn@e4g8G(P17LpA_ zWJ*`cks^^YhvagQ12P>j8ToKoD_ENXx9kkuMxjYA4E`DA2BSu#p=n@wNFj7JTpIZh zV+C)Pw^9Tl%;i@UZy;tB(hr&=V^Puv3Gytc&O_z$H_<*y)(Th*^m6uxm%4x`3R6#-Uo|y5%MZwW{@;O$gfd z`fR4{I$-@5W~X)T86=ro=z19*vf$O@FkH2m)_ZDHd8ArD!r0p~%0SXY#7fIx#AM8x z#W2IPzt61E(5p`iZ5^D3oWx*0=Tjknjxo8*WcFF3d{b6^UwYLL>hmp+zhnJq> zHnWa7UgWmdom{-e?7W?2yc_K$oWJ>8vj6Dv#5>FwE(X0S)bs5FA@DmRRf<#Hv2+?N~0=#M~}rvU-YXAwu?#gj}Jk| zMh2MSSmS&GMR1?-wt?%RJ$ORUi?Av@;aE}lSv(;)EFut32r-B>!4q)8QE=dUGny4o z2Z4NkPUzMB%d>gsAP zAs+7FJ)`J{Hi!Rh|NO1WVNfXaFJ+EI$r4RH;*Eqs;V=Z$9S#O^#G6_ffLsg$Pm#(5lvbE{`-0=po!?AfYth+ms0_~k6lq>yiXz}HffxU zrpMPfnS1Ga?||h!4c?|idYr)ZSDSeJ4q<(X5J))wQ6=dsHtDMYq&lv3!>w)n3ptHD z9ZQG8^$y>2OhL<0Gdtc<#7OdIg8cAP0CxMa z-T=-&F}MPeWP8{H1i=ugf%;ws3dGFs#6ayaw*uxr5Ciptw~KO(=;sOZyM@4=*1s^g zv$+V;V zE`H$o>%t=e7vMXdXeb;GMJp0f1u{e&;Y5}|q5ps@99VK-Bmb9u3`pFym zL3Omk&)oIbb_19T0ae%|I*=h^02Ka=hyp-u9iaL@AfflY(@f*!4CsQ3=Ae{D<|ucDLIQ5+)$LH~#$APs&ODCmE~5Dvv4_vFcUwgL+O zg5e%lVE~!=zl)Q7t`aNCPvx3|IZ-P?my`PY`)5tkRTG*RW5sqh1FaUe+6jcf4liwT zNHQdOGv+}5{Aws;1a=O(T8Jg+uC8q@5TZ5-qu;5r(_BSpTG+X@bE|&%tv&1xrybw9 z`ugF;uzM~+kD%BJPH|8?^`EKolkfjS%p!lG3P#~CwFxlncdG1j?!Qun$htZ}+y6in zwBr7{Um3(v-k@veghpV;sgn5_qks$A*2p?uGY5U2NIwT1HNG}#IIm)LZTEf7;@XED zr_E-k(dNw^eC$4pEHw~b?`&1=ysjkp`0qBB++8eLsP0<~dt^s1lgd1vGDOMeXF14e zXJ_r=l9EbGNeg{l@o!odkUYO}4IpEFlDa?d3xywA==%l-#Ph#!&E5vb{3j*!V}oCD z&X>n>w?^WqRj5^r`&V~VnnX#Ps0EUF=9>yj3G7pd5-kzp((hX$f6~1Qd%E|(q5hZdy>bQF$~t~Rb@}q%{)m}ln}crBG!^PL$BGf= z*EX97H|X6Q@OulpNFcZ)CGeG7uYE@w94gx!>h8fDP7aUy(#cf7svmWrHU5?Pf49Nl zs9(_jOBDk)wLBD17y#lxhKM*&_%rh(_tqQ@Y=Qq-WFr4wb7|pNhxv*U;*>oxy{8y`LZ|eIS*bD>SJ6x7CgTugkj+Gg(rS?xn_s*SvG(>~<&ZU2< z{mD$gg7=KApZe}OQ~Q0jeEe`8!E#!Dz+twAhg+b##}BI&fx!IblSSk^WWWR3V04<{ z1!`zm2_~47+&)uO{S@gUg?k!UUW1+0Yi`l^q`xUHf}DRtaTzkZFm3zg=JC6ClEZC7 zJ4I1Z(%tMj-MHtPT;*;I3wPJJJ~iDO-=0`_>LuDpAub`DR;>|bAyD=$SU8ll#ayqf z>@i*n+1Z}It3eUnVn`1jQ!3Xa$#;2I1j=&bGX?2aM6@F#z8-F{Lk7J)|se2C;BI;Fq~{r3}f;;BDaPBQ?g@CooDTDin3b#Iqo zVniVX3YeQNfX9m<@-Yx{Z~;~VLELY9c{p@WUhU=gT)*#dMd+R~BZ4td#NLQN7EN@M zzBfPthu`~I1t@%vMSuqKQ1~7b09n9^{P92p6tHIZp9h5#cRX=iU~do&B{LwlAV)-D z|2Y4<8r=JK*n_J9K@=c{A_Exea2SlZqhK(g#wR!gN5l~dlQVGH&%%*%RzB`H?+`oi z-k#jEr}uO&AaeJ_&)<+e@SeT0m;0p^u`}Sbn}@pMi18d^goNm{?sNSff%iFgFW&Qm z^l}6O zfC7=Feu1G;NZ?50pD+{};LU%uLlar|A219W;MQMZ7>xWs=Ym1PkpFxJ2Jt&?Xbc7o z@cFOfDZ+oBGZ2sZZGMUFGl{KGyq~^#2xlaI}8j#+<^ap$^W4*nz*TdZ3l47 zKk0&jBYvYP2ChI<5dY|l{taIYToF){|7eE*f^@&be(#Gw0v6*x`yz?f!jI?Tf?a(4 zJc9Q^nC3oFfJlTx<;(&DfoLUBssI7h0M9@uaU%i32Jp-6l+-lgidY4#mKFwqMWGeZ uS{f(?4FnJ%L}6iAjHbNu|91-qVjwgG=Ms$DV|ok{m?l_MRMS`s{Qm&X(?+rY literal 0 HcmV?d00001 diff --git a/docs/_spec/public/images/classhierarchy.png b/docs/_spec/public/images/classhierarchy.png new file mode 100644 index 0000000000000000000000000000000000000000..3da25ecbf2d579a8330754ff3d6173c4a6dcfa57 GIT binary patch literal 117555 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

2DhI`_^IAc^h42bKL{P~ zo0|t@w~L&NEbhFI+{d+L%RC1FO5PD_8`qhH&9kp!d*Aya8Kb=}LNs_wr8HD!j8Yf4 zOXikHuvQgHo_HHD?qeswafc#$8;abd$MTDPsFUC*C>2dRxgQjjU0S(;sqg7 zeSh<0`#BUKw{VCVe>3JHMRD?4>3SuW;m)KDAP<=Byvua7;Gv=XjP#mH)cz25g^X{f z^sOr2r@Ed-`nUv?h)0M}Db7`qhPVk_1=|$hu{a^_uWfd`Yi)YF+r9jo`3poz1ilgm zPE$+26#NdIRcC1k@1+*V++;KB2794FaduliAMs)-+C3Kabrz&O2Hou`z|q9V3% z=TObdA1CU>y<2sb7}3?x4CN}4j{Q?}eK_8*b+*8**vE#tbLC|}rqSL+&$z7wgWVJ< zEvKbl2b)ZMV=mm$yGF{D3cD@XQUr?mHVi7gcpvauQ20;+YHUUm@w*S@?Ga(oa!*{)g!a1tm}743k<$#On{QAv5Vb zoTk)76kM0S&9Arf^XAyFQn;Oxjx^u#HW#)}4Jx0MI8} zMmYuddDOmN;-8%WVork)jzA`4|MpXTrc`PX<^%jt({~;d2A|p>l8OWRuN*%*KQgC% zA0kM8y)Ml!=BgPBT*?5claZZ2A9M{mDjAyib^)KUr*v_@SK$XVP4A~GX*Y#dEuJ*D zQJ|kZ(&g<%06f{|e$YGz=KT8QYNZL>KyH)o!yGRP+N2+V+X{=3@YI@Vd7ob>?-3t- z1YP=K7MNdg{D@a7@Dv@g=T2v(SB5vH+d)+PqMLa?=ToLFdg?tJzTcc@nDjMv$YDjK z>42u9n_mb0F42p8d>pZFbd44pFQVA@3vuoH@_#=8z zuAcHDu4|HSrDO0b38^ku_V+c~V3j{xtg-bHmpG6QDGPkHb#FKaMYBdt=e-Lc8THrX z&0HvUu4>sFS7h3K$Reqn%3iG6xd(8sjmBe4c#=2di`O!kRSgg61CyNsznM4Qw4p=K zPL*zKQ=sEbtM9H;?K4T)UuRksn^86a^|#4=D9ci`HcjxJ=F&dEanWZvp+>Rs2He!E z>G5X0c)0v<^{yEJB$2;Rxp9!fo7t_lRmr5^FOo>G|0rjy{|QezLY+)Ksq`t}+jzhI z2CQfrmY@J5TY5ZH`t~HwSD8d7#PhU4aE)4!_-P_qXAbNdqP(g6C)_IuwYeY-e z*%+l6F6P!Fb^U&lPZP)&M9SOxri&7p!0dwVP!(_We3?s@(pD&pAeES}rXK*@w$!ML z88>Ua^BtQ>qOgrLV7va(QtPS8di`4qQJqgKeTkel7Ij+U>Y^TY!1B?R6wPvw-qxLT zW8oKt`>U#P8_p(X{oRAl&(F+wo6lX;l-jf$iZm~!6t5K_y5i{9socTSO~6tj*sUNz zEdsX)pF9|WJj&APd4-ve6i>2}UND%fu)b@Uu*p!J*cz7`QfqJIn|>ufhhIEUC9ygE z_wmo$qhv_*5~WJ=reIr8`a&L3L;UCGvCL>M-FUg9@a9TLzr&&EuEKT~JDyo#V zKN1NQU~m+AbQ^TyovjDYOh`R{YnWu7~lPUN&pQ*#m^OMcS5)S zD7P&gaZmfWaxh}Za~EFn48m>5BdJ7HP;U8$!b!3=+tCX9<4gMOC|$H?ZaW zR%AbOSqU={(u55^Qve%)=YG?(G7F3&jk~Kvu{*EimboK$yx6K=eWt9(zWu3fzQ_2} zmuezg^dHCBFW&dfn7ER0e*Ie%hEluJ*BESBUEj`794eb0bLXiqQTZ89$xs~Yi4L#q z|4@9M)->8WKI`MUsdY#RRy8=0E3E7e(gFD2#e8J8>+hSKFvwa)OoD-F(h|(Nt5kom zy5%V)_V&@5QlS>}ir2ySl^)L{BRGsm@EB;)ut?cY?%R&F0tC-u`Wc+dJ+2ESA|gw= z;E>|8w|2P;lEYW2f6hcs7v_p_jNMO<8XLkT)R5<=e;Ko^E=o8>*M)GSe1#upXL<)o zcB>e28^XJVLPB|0md~zXf0w>MXXG7t6r`G1&pcdCJH$4B==Gc=dwsEGhuAtJ&)YD-Ec_9yV@gCtZhBU8z^IYcADkbls~p|y!O>D ziE8isgKz#-z34TJPoUgIRF|}LC}cmVjN^9ic5yh#{$y!VX6GvRxXMpl(_`v1BB@}O z`hzdy(5Y|HsYc=_A&my^g~>)(U8|bQo$7?Y)Qt%owHaufMRo74hjCDq?scCoHH7)v zZgdJErOSJ$*4bj~c8&F8+bS1h++-rb3)9y{_jVEp`V!G=&SEv8#T>)WGlcfvVvcwt zrSA|k(w?UKC>|Nin&;(P64Q{XQgBGI5?aiumq72>YO<`TL__`O7d;b6crg)a?k>8V zgRbMJ-oH$YAV<~<)fF!moMyRwVW3gDu7G<<&O0@=$ox|%e5Se3 zDMpv0Jt?52=zRNWpe_zyy?Mdp0`p6`O$$`7+AG$zQwuT*<{(Bu2D=+m|qHLp>e9Urqw>3H%CTCLlI0ho7A zTi~dua4Bb`eSjSQCPY}Hhu>rTLlcZT_bZprGpuuIms8$-k!Z!sC`qUL=WaIkWialB z?Z1c7y&m{OIBjb*e$E;GG)lAgM!EH~R-WS0eFiiHd%AVM;Ib-eR%-sHgFi z(kdIMN*Qk%SHcMRx!g+Aei5Z1XlSc;tE46o?CwIQMXz1a`2NWw*QXRWzVw4PL9t_K zllnErZlpvbhmiRqj1rlKVQ6+1%qQ)2wrZA_WB9<+ab};&BSEr&a{cGD`jdlH^fa+L z;!V~bZa}BDbAV{#JmjV9Nj1Okj2=d%uZkUOXKKv zL)4?wXEVd)D0QiCSkH~Bj0bycvOtHUnf++@p2R*vcbV+?iP$KsPq>2D=~c zj^PCR^ESU1-%zUy)*3fb@w)dBE|*6b8sR&UDZyTO=-hLD^`2YjxwMRa3j(;^2hrbjt>YCq-eWA)pw0;*e$ydrr!#gK!}tu!bloc#m$ZCc@JwSL)Kdk%Ob=qKU3S<&dCgvQ`h4-4TJoMcT2 z!h_^Kx)`1bt>=D!BTB6QO2t;Oew0&;B+~}*(Ia@(GJpQ zW?*#V`+&?dBGfjT*$}_=Ml^-OgxHss?1vC#kU?ppKo&b8yV5p9_P)pfQvG zqrz8s?jL^|UXm&Ap1InI3InL}-kZGU;MU*G1JYWvR=W`2`(={^dB@MNo^MuQ9g^iI20T<4D{ z#YQUFsFJhCj5{VsvgpvZg^K%m5R%M*_tKS3IXoEC^V5h6a>C0=LermNjJf=N>Q=O~ zWrnvOdFvVTl#CrbWlRL}d%2Ow^qsdrW5RKpTE;=Mc^$OKtYf<(+d%uo)i-~}j@GD- z$pYe(%mx;ml0MW!zgVCCF%{(26plUVvQ52n%v!&OevxR`teQ#qPjnvH@w$3yUe~|* zJNp+KjNN`xvU!l-pg0uE{}Y;Uk`0gTsNkp$dpWu%y+V;1UpHhA8TzviIq1m>Is0Ya zI36M$2GV%{g6RC%cfe^|N(H|_9|O0;&#)!3NjyiSjCEE&ERk0guE#Wi4w9@B(C7VM zEr6ogRDRp#b`)_@ZI2IX#UXLX(*1 znuHqXzy);p-W!>z^m7G%){jgfI|VaG)({PtWA(hXvL41f%-yZx8p^)N|563r(-uuT zjLS`=Zu1xYj5<=*`7=jsMj^oZUA0R4u}3W!-ns_IWKMp?YRm5;9Fw?ax2OoB+KCe` z(IdaV?{4`cCZ8B}9)>0zK9a>AMBq^yMs5cd)XYzM#oYr@QzJ@=od*@i@yrY6n+YX7 z^)yAt{TeIe%$6DetnAR7KOnc;?u?kbaKJ5J@5y73*nsYijq=i!PXE8#>u{@6(Vf>H zPqECzCKp*wmml`^l+^=CENn>kS80N2&6Wyjo0KFHfYaFjHr1)*#vi3(*KY^nqZyja z%<(4ma1(1ZgdSBXi4IuXKs^jzOmMUtz&X}XEyh{nklGYdb39O%aTlazwQE*a+fq2s z7$TcclJuGt)Lskx`IfH{N;b(v2r_JpY?>9k_A7OF`*WqG9mDn&i`hxhMT8$@jE~cc zlx`F^xpd1)r8r%tnP`_tIB(EXHegG!qlEYrd+wD9Z+$cYW? z48AU^JH{gm4ewF`@qH((NRrS>u$V{EnHV8?yNxY4zAABnR1#qgFkct9R`Yl@`Hq5i!y_Ra6KeZn3kHzE#3F!V|g+GKdS);ZHu`4Wt zt}LEc(ViuQHqHLF>jJe>Imc`ZuA_2wU)GVU`eS=hcr7>kS2z{CNVNaVlXUeKSo!8RMfesU8r)>kj5wPq3 zciH>4d6vzIH@7`~NY|eOr3;buIPEeFl*`ptOQpndV33*5WGj_U#e--Y?m^4vkMM2o z--}pL*;R7frF#I+7FYg9UNV}z2_rlogNkzaYRz=l`7+>6;Omf06__Htsz-ulHGj=^ zr>s8|uMTw228hEgd!u1^YBM@W`-vVcF+(ud@BgSZdB{g`RKWt_DSwteelk2aIs6?c z;6CNQXIN(*aP@uj_$f%WtKY+}3x)e{rVB!=1cy(gCY)I-36ceWM! zIYE5q1+~*%*H9r*&6OFdpb568 z3h-Fxcu+g(6k|MT1{^Gq$#u8@Jf)erdlR$NDrQ6vd4#Ia}lGpT=8l z9($Jt`X#C-jl}#IO;NGP>a~WZKC5?)-aMGtYW1g7F>U2bC~)DRwDzKi0u&vW^}%wk zp^W!!Z=%KoK^Jct#dnRz$9ODjKSAlK&yU~1bceBne0i$2LvfBc@@FSjdewQ?p?Zk; z+9edNTE_LY1IrpTxvH^$;C51P@LRp0+U?H9H-(Wt2scL)QTN%8KRs>#B1P3IgKhTM zK_Cjk?`Yn<&t`lG91hVzTv~8^6kL42lChd`#dcjgs;`89C$f1#_aFkAzBE#2ciaTo zgXYIt=r1pd(7olI*Cou-ECn z>E&o2S%xoaBz|-SX#XWhKM28?zh2X)Kpbo|LiTK( z&U9{Je#Q%#4N0)tqEkZ*J_)7D*m&G;Rz(O$LifO(4aZ})`nc2-E#6q64WgxUmD{De zu?Ax!@=OU)W4sj``x7(Dl=IKiBIgd-HgrCp8`-$t?9LBnaNxLI+J_HdQa}JH^zMn? zN8Q#w29Ys=vE0BGnqF+Q;M~P>Z56HR>ltO&!0nFnm~q~LJ9h96?^jd0unLDC#tuZI(~Ss22lad$k5iNhex3Ik9B!A3bolL}lnA@jNLTDR9A%Ge?%cT>X!^-!D*VZ3 za&6_U#3)9Zow1aXObX7)V(=0_?_iK=@8Tc#9SpVa))rUmlLA$I`r3I<`63?HQk!_y z)|;4@J+P>=F=uP9D4K5^qfSl;(oZ#}6`^dmcfYwlLKQSj+>Q;1&wm6oqRbz4Rcg__$O&d|L#Sm%_A4?uLnVgxerS3=6|M6tNB*Y!=njp%zm~C zsvX;_4z~qIRTBzZ?$06@ZEwtB`DZq_k3elHFoi}K(uN+oG_(UQ7HV!5esb1R4(-Q_ z`)$Pu9?<@k<*OZhA7=^Lp~*_AldAfZe`aFYJ&W8GzoPHl@qa1ZbfY`IX41be$^L5gbd$hB48v zE^>L6jDGtk%2k@@D6$!;aTqM)1q;yV?%UfE-Dfb z21O;nem}>cY1S^XUDWdmMNNm*)IQ29@@O&95#KT??0!MHZ06Bc$|bcrm2c~metFMH znPX5ri^~Cy*uV&oTSM^yL$PMaxs%SG)1H&WQHh>?gsLO&-;2(=ySTZjf2wj^H;ija z7xnO|R5OF6Q{R3q*PFW}Hbq-jYZP}92&i_zf&Tlazh)rRgwh>TLybctJ}gY!M?;)< z-jDDNc8fTrhvxO0-WDX=PVDy!4c3hb3l4TaZ?G;~NnPmoG2B>5#*oIE*9B3$f#a{j z_lMk$!x+SbsDxh*&)dCBcdWnOd4H?lgjjTpvpcvpYMf2L9YMgz#m`3S)~I#hLpr!- z($;|>5Ph`v?uxIl{65OIey$vz9)bCO+4$}=d5w%Z!BlxF-Tm6f{vx&B|NRbX*6+Hi z(WG=JBh(SWQ@k+)X<5YjIq>Li3gTb~c9V|sMUr@r%p=nzhu%EN_<%+xhgkfor0e+I zeSKl5yC33vbSS;TZo-bK-^00R{17E!K_TVoMgG(~*7%NBH2u2vNz@DLh7d9gp(-Kx zP06;u?KAb|P-N=Pf#Zu1f9vyC_5W{@$^M-!}a2hGGu` zYB9ERML>cvo#&~7?!(a0`cL#NJRMIpZ!NT$;wKFG-7A-ZfxgMlET4qi42`VE2~s{b zT|fM?YRtq*Y}9SDADi<2Kc>Dr z9T0Vjg6K(Dz1LVh zETX=5^ZefT^ZIMuJ9qAxGiOfu&Y5$6%CG)fA4Fb@`xpLJNNiyWVk60Wu|_*E4&YmQI0^t-FYz=hAK)*94%=giCIXq$O+KDp=}%}8<6bgiGi zk={}bFASW|#^6!TM+>22+99FJGia(D#z8>*ylT7?A)&6#P=0Tg6rk8elC}Jl*W-ne zu?oV%++YKCB+Mj{b$5pk|mmP(UK_LiHxlnExKn{AsRJq|+Mz-2Jj zDEL5hxE8hNCY=syK!Un}3kF+fntsoD&fQEeJ#V7gry?PX_P1R;%5D6?B|s?|H`uE? zN%$ctqS#joMyI}w?3T*@0uC0RP(Zg;!5F0BQnO^a?`F6=(Wn#+u{Y;9(k|w~aMG_@ ze3mYMJQlalFFj(=xH?=ts1&0rll^#yZh&dFjrZ`*Ca1n0ka zkz&%R4Iol*)!!sjN}0^lKqJ$nPySk;`xl6U3~S$1f&WstXc_MA^~E~W(?iGC-g)S{ za*Z|7tvGQ5XGV2Q$`)sbp4Ft-<}^jZ8%7o&Ikj? zIz^BDKXr*T#94h`^gsU(&=`UfUH5)5^dH0k0PlBvRvei=ul;;^w-w7#mWH3+&oX%E z&u`@}gpdsiGrWwjP=x9eYTf)C<>syw3v65NT>nBk?uN2J*RRk7W|w((twRZ~kk`ec01%XNgDKle%75TX3kqe-`N6>lljwvLL*vKk zAJm{8eaBlK4+XQndi5WK#LWwf+zvVi_{KG$2)au)l$~R&i<9rt{)PVnk!0oDrbi%3 z_P@pwf2TT$I#xhZ>LWg$J^WDGo8mf#f$B_)1%imK00q0l?ojZ2wcokW*&7^RVCcR% zv@I-a9uSw8pKP%Xz-(;#X0LfodoqJCYJMaczxV|@5Q8UghBsJMSp)OgXR<&~j7vp| zMGTdWqU{n&$tDszCIHL4O_lUzagdTq6rd9WF_v_z;OQs1NxKw*7fmNs4{b+7cJ3F0 z(%p?0n1mQSc3o$?;Lc+C>VH_t9NMK5Ms{#T{|tR`Ms45R>q!3bJeuJKjQ3{W2-t=N zTnPW6Ds$+Rd9gQSI9I{kY6XG7EkO`909ngQ;X4-{q{RV&{l|ss9w?SGyh!#0$ZUpY zq*jw4B+t9|Pd$f+@@YEyyU0WD@G%L@zOS9Y`x8F7?~y6JHVXGgCR_pW7t*MIBjRp= z`s&|$NpFK=RNel7O&%&@Z&3SSe4YlN*=Meoa~vf-WTGHTxJAO0*g=2Rf{G$^dd62* zW*tYOs-NDWjj}=CHwyq2-@mx`N*fS;D<+*WZtV;cY58PHtmlTZu+Qj>kpaw;QHjF|}RWp72{8JFH_ znMDDfa)kmAuOR`xHs~?DL*51@3B`FAkP(jx=WK#$ioiy10;LN7fLW~#q*(d<0>$mm zEWavamVf=t5V_{N{_eSfFpm8Hjay2UR!0e^f2Svf{_N_R<7rYqBD;=xSMwf;8ZeMo zdW;^D2%`|-1{xC#4J8lX$Ubb5!u|QjYY))A*Ix#^peo> z1O;xNN$XO$NjLt30ez`#ZA7k5w^=8U?WCgw1d7e_%?@ZX=}6(`NO0WMoy!zglKxQO zU{+d8N+PtiwExBca>DKHQ1OK{a%v93-&k$?XXH zc_$Sf26qhc=y^$BP3^5)RTo>xL86c^941@o z*os6FH9{GaaKd2~;%ozNb(g`}RrRNNse9){_*n#HJvW){O%~P&I~DEn{$5tOa^N;Y zN9j!TJ*U2??-BdFxFX8z^S_g#!dvn|9Ri5WYnOvxZayWGzqb7KY5do}eqD=Z6hOV) zJS>ee)GzC8ppG}sxJD7#f)Id2l5Jvv_(ZuhjSAX>TfjR3%$k2MQ&4_9xUeY>y4iEm&e1N2=(VWW|EWiJ2{ zA#?(xs}x|p6Uyu%cOtHn3M^)*$v02xA8OqJ_HU*gx1?sm0pL&vW&&hNGgj;`S(kXy z^Qc#23Saor16zOIHqC&|kM9^BxKxy}Vv>JDz=;CtRUY1B!A)FrlN4xHsinI)MH=Bq z#3~=I$9GpgCH7^u?`QqXH@QLH#XjlN0FwNMzIVKQ{5Lhj+1Ix33!=>A)BcWy#DQyoBPfk$VYZJ8?X!g4@qg~fCKa6aMl$!7#U!0EimW7 z3d{tA4@z#|Ld1Ql04XI;{+>_)0Mk!+9O634C~HAO%hawC@SF@#iZ7hg1AP{tgz?KA zJ2Ie=Ew{e#v8neU8OYVnKyc}BsPUyNyrSzN144(lRLSd1$Z*5@A5!?Q*~FNEHYQ5l zy3H5}EwRZTlswY@N5MCPxtAaXj-4t+8rN>I-jSUI>9o|nJWCF2#j-o_uyDk;fUKG*<^UP6b}ZL-g^0lr%7u`eaLa^oyhV17s>1rVy-?tuJvqeZAAFv(zD zrk6yq*d;9%u*;b3%Tfy!m%_D}m%^~%!2TQUR+&dk=)NjYO34a#*_DZliV+9nzE@ zP|&}>&H~_`eCA1#13Z``vxV&V$@NYpV+^m882((~n!EzAl&A&red&gwzV@CF=(_^u zv!N#ElCIj7A8ORt)D0D!i)R7=!02{WjiB8#);*qW$(Tz0hdol@#oM3hHJ~14=|!O- zsxa1ntq?r=F8qP9&r{S)E^G*q+OUk>0KbU1Al}P+?=Hle)C%|G>xNTVvlcxN<4d_^ph8~M*v{i{LR|E?=6!nGK>dJ2R2BEoM*C;>JMiN=Z^E*SQRm(3~^YSj!r=1<-;LlLy=Fj7q|6T=b@fmohfLmJNWt_(q z73p|IBc2uxYEmnKTPnvZ3&{W7lz5w6HP8w9H;e=3qKD*0`8>>{x_g#fHzi+_nlHxJ zIlM7X|InbWkZ#8EkA&lM?zx(MEs};jH~tM|M$lW+kQl4BwCu7`7qX%ogq&_*mOolw zkx(6~Zvcli!+0_B);vXw@WrS@$B?OpHx|^@DVorFEC`u1r@2Z$-7$5RM?W_Tb8Wx8NX0Dx%cm1OdE<_`3=aAB>xZ4ZEXkho zhOj^G7WVm2lu+Rw#J*dC4GX(=mmPvWHDcO!c_qdlMbKEtU%{u(pc@5Y6gup{?a*E; zmV{gO5qR@5Ir%CcKN-&U4Q3XISRLx`2LZy2PSX4HTjBng4ENw9wlFMcS3_N|AFH)b zA8k0KSWE=*Yo1hHnW31(`&;&F+rxS^tk9~)1b2FCtiGHSFpS#DpphvN6^nri;! zJv&KXU;NR4a-BDw&8-yZp=~rR@h4OqgFBh~3l8r<7The2HBjGeR@j)4!BC3Sh19@r ztW;^tL-+Kg<${@QL>$HijbNj4Ps~IEq-o?Z+`Vhmxyu}luvvLk%@0Q2# z4Jb(-^B>D}lGOM^;rucDo06}!;YpKa#k@hA#1L;8$*|fwUv#fe-J?Ize>_>d>}Gax z3F_^pRE;Tb1h_HNv_3?|S_kdXZP1jcrkR9XJ44Rv<+!K5c;zkY9cjPlaB^mI($Ve3 ziLb*t;N!%r9T9?ibzD5_S}qI7#`uhyU*K2ECZ=5oV&1&BdLP$G?6;aT2VFb{==jZ*)TAf zI(@#U4-U6)K+*qz2Z_sQ10SuN{x+UQdZ595hZ(aNTwx!NxSUk|&yLbP#6n@;Qx?!S z81b8=87VvzJ1lf@^ctJ6|7x=AWrNIllqQ7O$#~_OIX{#cv~R`7ut6CAXSkIz2!?fa z@dgr&i18>(woX9Jz-#)Q9$x>aOX5$)+Jc&^JgUjnm~?EFC2ns%(qHC@M%=X$DHB>3 z-P9y#`hr3o>L@tIgL8_JU_nRAtol+a5z zgCx4^@4_|}1gho64LXohn<`_Y+8RjK`X#rV0o6K0e&wh7f-hdCoqk$WxBBl0PiaH% zdq=xXN|o;#VF?)uKMr3I2|*`sa&{+@ZAS_`&u)!q!>2h>0}0~AuirejA%g{!?5w%qhpCCIo?YJ16}y;P-M;}!d{1A zu5mK={!2e+O!GV46zA%&?rEh0M<3$H`02n7<-|6*@#3F}Sk9`pJjdGFuj{L>X87BK z&nIhYrh~8pYrgvem&}RKIr2a*Q=gsxF(CqU2)fyazQPwQ1of6b3Ea$P>ld5E?`ons zHG9V8-M9s^FTbBoD*9FVEj+g=cId|Uy*)j&xfe$6@~Benx(8x{6%JoS=dHq_i<8d? zil^QfdBtYTlobp7tI;Ui^9I!QEl>95HfPC%x-oUCEli;1S1yt^lLEb-XTa8qI_e2m zObhnNTNj4XK@;dT(5cwo%)S6cjp<-$!jyMz;zaR|{_)@J`2c4GYN8JHpipK@rq*!S zT}s)w@v4B2RBuleAr^{8pZ>L6flAR<)M0V5jdBjH z=vy1V(Rrr!-zvR-BLzBkYdFMCA%X%0QM3)S&?negkte-iL zjr(?RzMnKk$624-(j&>7c5U7ATQXeS0>LkIfS_GMRP+Xu2~wX{IG!qdrrZE~#v|;_ zMKe}U_T4J>Pi-}Va%|>lLVTua!Gn z&16JCFSI)Gq1JyNK}Y|NzExB9N=NiMN0 ze3V%qZRhv*5Ko3JmVvXMX0T z*TZR!MX_PaBTQ=@GCD>f@i}9KYrUhQ1tvZi@s9@i#xVST97p@R+8LSt-AYC2(xO8x z%H{DQT@9+`z>&<|y`pRW7Sv%fw{QjS2thv3bz!~lD^#V>U9;*Gmv>rz)_&SqKVjzN zUyU7C_J&>c>U%UP$bxya5VY>#x!98DS3zbGG71-J{u9_Hh=;5b-bFfsGjw3q^i=AR z3k-{V!Y=n@*l`kn@La{^m+7iNfTTerzg3m~a_MX7$e|h|-ijD^yn@Va&pIkhVwi{X zy;WLj&URepa3or08GFTt=v=EQ%MEBf*aKI;juish(7clBJw{Vay@3=pU*Aoi_lg-x zr2E3S@%1p}rCU&ksUG|hS;e+=aeNpjQr-u1)Qf9Cpmc%*Q&3PrpEh7=5%%3NveT7NKNqtLm2bT6o?CTQZ9|H2%-F#l+oBR&DGyRd zO;FAd0 z%5?;6yf)j_AVg4?7kj2#i~NMz3SuX!S@c3Kg~}h~nL*N&fuy(96Oe{DpP~m|U81UZ zCA4L}Mrv<}1@_QGN5*-g-}}Q_H(a~gIj`_^afe0ZH;?xEp1ge`*5u4Xp!fN4=a1qs zi=O$%9(6uy)3*82VHZ8UN>)X!q=YK%$2d#O_frW4-(sSk>FRoKP6b-|e1v-yAH@?* zeGt!qgQFti-SCJAKM;_ak$1;jlp~Vi_`XsvzpOF4>63OSpSZ0@eG)}oZ4PIEI_5~8 z2-Vj(f3oR)eejn|bi=_e*|ydKuHbTp=^68NaZ$tDtQm5;Xz$Erz1CDNKYj3Qo#N3t`;utc%=;eHn7ozZX$C)6%U!2DzQ#qF{KXNEjy}fcV-D%ZA**HIFFA>(F zIn6IW*$&-nvsaRZTHl4|Xsu?tn8D{h^z;X_eIJSL@XHP7^ zFVFt<^wDgqe+C>X-Fsgwe>1gt_dlEd&zxB<3Z&mD;4IdlfKoc|5mXb`&?Ji;+03+cD*t)wa({J_GfQ}o^qvCuaAa)l`eBIB z_zWL#EVkO!7(K*g3}TFpys&f{3t>`_rTdIcw~FZ%$^Qrc^^Nr0+^qQNZ83{(6o3s_ zF*}pmxY`U$c6Tc_Mfj{<+PF$`SPpsPUbcX@W>EJ$wPRC7jJl$G)|JLt!e+mTyOZo0 z0Blj&TRO>9$=MH?UtDA6Cb_<5ai? z#HtZC9FG&;oozPjtf8-^O^>#O)d*D|ZC$zKYgEh-e|1s99iM9qA~FCD;Uv=HYmpLL z-5_q*TJZtmzP*3^@RuBvDcRN-3Kg;Tc`)ng?xpF2FN|4XYl1qZ&VMG=;4wr;kAuh$qtFcyJc1K{%?@YLsGrcx47V7=H*DgCOuSw>WDL>#<1wSk%3L0kEaYdmSqE;WmO|Z3-MAFv8=;3*)Xq z>6E!&Q}45%fasb{se&B=yj^%O|2sW%q!zZJGi`*ZtH%)|=Ve|y$1P{nDo=FcAuNlv z&L%!lb$i*OUCf%plQQlQ?&T~^_karJ6$87?6=$mq{5f-*@%2Ny#c>VG6eP647L1s{ zzK!b4f=1z9(%PBDCa?I@Iq73e46~v684N%OU%kRq1df%_$gXgVNR?iz=x@+4Iaj&Ml4V-@j02{z4Boa~bxL3@HbWQ* z+sapB;xOxMKCz0tu=r^e4-gdqaNX`ih>sNdoZUQtnf^JN8p1A+C`#Zm8 z_cj)qt5#bFUDpo&rMdC?i)WMZFk{IR{pvATab-l*YSYS}H-iT7*P&H@>y==V*RPL} zb9QxOc$I%h4$%IYGzQG$9-TNDWRnrHLNSB^U0|YQqW1SNerY}KuO50RZeVjGZ>UZt zAU6X26(>CJ@oW{U0?DTyI!BqT@8a{M1FHS^6mq?uOC2;~X^!cyNa1qAgHXi!&{p{=?pWzLRnPQIcd6z}= z!-^@jj)byFE2sW#=wnldnFzUa7cV<&Jn;LuV=3h0#rq#LC7x{-goo3oi2Mx>y!$OqGL zm5L+)WQ&CET9olrt~#a})efl-5x%#dAt$T zt;V8;-kHI5`CyFoQD6^1dpxSd2jl+HyVG2w+~tqHt9uTEd3=0|nvE~0`S#xX>AxpT zZ+yMEo_(qcLxJZ2OY|XNsx{vRvd}!_3aN*KkXq!FeG6gjcCiA6!haJzr0iCF-PwkK zFe9#pxcaOZzc9b@L)*k*%4MeRB`m5B-tglywLQW1M7UN?dmZ_=eV)_}?yMU!+UUpD zH-&!yU@x4EIAMew=s7%_+(lr+zaHoBbwO%fm=T`t#5ME=myg%Y<#hPr<2vS{E8w0A zsNlgrt1dj-Bz{m#_g5)XIG3P*(VQft*n(b94J%cXfEumc*nKGs!|2sv52}ZS#^rq= z7-d$QjB3`emG(*Z z>OM@DWf5M?@GSK`nt5qt6I^UN`Pgd;i#jybrwSvA>Zj{8enw@)-D2oSM2$zLP?8wQ zZjNqDqqCIafFd8)w_o?Fw~9kLcs?KDM-9mh77$7{jL{pODfd0bHRVgjETVKxi_)UZ zUV@)H(8G>NK0DDk*?ca)1+-U|=_Hd!{z|$9GsA zcboGjY7yx?zTP_4VWAZdMcY;d{rYfpJZNS)zCKm%bX1^XH7;7haNoJk=B%q~zvD<< zhFGS;{2lTRjD-m8l8HVI%-I z^G>t1OH#Y3u735DqJUdD;D;^FxcJv_#t>*K9en)$X*_jz;`#)>iTXd>)Pn@Wf=Ho6 zADEFvQUd=hbDi2h+_qk8W6az-!L<9kck|c^f)ucI;gcjti*t(;*^SU&j}Afvbhb}G zk7OrU!a)63gL3VJQ2b~2g`(}S?r#W8(QNC0fT0Z9VhN z@xl2oVbgJ_GN%6w@h5_mq9@I$q~`U#V%~@}px(t5-)?j@ z`_R$zV1={~XzDKY=)a-9i~s9~f_NxDaeU=498w&u3_4#1Xm@f_hf~*k6{^=SeKLHo z6BTq)66ljv^%6$fM*{$fvItI7{3QG89#^!eY1B}G$bZ8)e(Uc6F@L|Z&Go9-!3$wt zC^7+3?r>e-y`A)!c{37Ic-1^GN09P-Niem?mUgYle^i>oP)oDNu4+CNnowoZF$2(1 zBDs*_3XaPjF(MaygMjxfKga;K)zf#ygI+i83xm7PApe9fWr7nUe%p;$s8$tW7B)<6 zdHrE61ErK%?!>{yFv#OX6hFu|OQXR3t=J9(RMXkl51@LUj(RdKNkn|8K3s_ifK zWX#z)k0eU8vvfpb{J=&jXR6uRJIWU(2fK7b4*%nuR}_gTN#YOW5VwyZN_*hiAKWU1 zI9-Bz@acUU^oMcftKUc*l;bJ7KnBn~xt&=ZC51`JlV{rg1JFIv3(3=wXB#Nbpc`xJ zrvOJt@;eW12Tsl|RjlFj817qbk(#-$B-_gUApBH%Jc0LFL_W`>2gJprB#-$5yqqHl z3xt$JYRijsdV8u_4u#kH&w-ryj8X=7+}Hu!r=k?jpZ$gA+9I%M@dXOHH}R2cqRMt{ z{mP^Pq`D)@E`ZGVIMjK3IlybVlOvMURaJIygE8pYI{(M>+rcP09xX zfA#4b@|Q$NH*w^dqZ<)+VOU}bCXdqjh`1_n^if>uo-@- zlerCh9Ij3CH2@q>xQfwLa)3Qzu%S#Ee-t>oYbkjs;Z5K3G-3?6>kDxnOtzm;WZ-tK<;7nyD*~84)uP?(o2WJty~45d zcF(B(6FRz+T$IEJ%HF;HYu;nwtimI5_P0;1yN#1liqAK2fZ8z2pAVK_1$%Poh#kbq z!=cwm{jZJMOGW;-7y3-yAA@vMJFTQQo;!TdFKoA}{&lX6jNMkWpddT#5g7N819WdZ z(mhR3gT_Kjzcl3L^&Ogx`)e3Vf-Hceh zYknp4*_MhM6Mx4q4FS+H0nMXN@bYON{i1m$Kd1>AhJ^K4tJs z#z%>(U$eHg+!0dQCCBw{v@@ngy@r_k@lMENWVvCqRchkj5Te zy_y(*fnRrmBcoVwuD5bygED#1b?xz2bD113kjJ=$S1D|Nmk|MOV}X@>+v{Nn)~P$tUF8M`UPV=+r`WQz@jCKeiJ6t znYVlOgu`25eUQ#x%(QmjpaggMRTCeK#og;#ZP)!j@7^9Vwfwmfcww=&e=xYtwgA7| z<(3|4ul%WduF2nlqMyU9j#BFbyQ)rh?+3=6Yy&7y zFf%b_Sq)6?Ec`8wqGO^OAGU5%%DlIbY+KAr8hd+3W#W0lj-vt;mC-uR2uvlQ90)7Q zfq=cwjb{%i8sGIsnImXSsITyE;Mr>`oSSvm)wqh?dDMZKp!3#XNi%5t^JVWoHg@7+mJNE#xnUYQjIY(pcfv<>$EZf#i-yjo*g(0%4lv3UMoV_Oe z1fpw2b~_`u`Y)YLSq7Wbm5HIhdNukIa(&1NKDoPoz3`A5|drQCPsR zn&VaRXPKcbEK-{$8oERwHa37=2b~RTj3&16Px;Yvgm%8XX7^@^H;DFQXP5I8*QKmL z_*CW){VNn8eod@6t)_gAo*H;F`@u=}!u0!&;PVH4qkk(M zh|6l>GHp9u_`rZIiS(K;UG18aI-VwEw(WPz{63+?%9d+TV-ZqOG0ah|B&&mz(VQva-UfQ;AX?9+%7^7VS$?nXu_z5BT+sPO*X z&oQo3>CVset6$<#MvfL8K^crBrqrxoPKi1*<_frA_@zCBGpH!#YU)()fTMxhNYjOo zwDpgvTunyk$7yfHtRC%i96(*FIL3HgEv93p90;ExQ<}RKoE#BFYgn&jL)ZF<^Jedq zb=n~w{$@hrjnNrXE6ABjoXksOnjH6=d;SxVDV((=F`Jc@g)mn-?0(mO6yEWi{@9D* zwdX^0%kRXLMoDhXhcm+J{qa&VX5&^zs8*t0Qae+i4B3q@@m3eyiQQXA zT=~q36c!J>vY;Ws47^9+ITM{J{lF<+!QR08D?e*8HKv{z{cwScp(yFjaFAu z0wRJ<0&=RVV^pGiw8ua28Mw4Cj(vgD&5#{`-l6;+BvG}H_I9&nJrTv1((E&XLa}Cn z)ZaOxG|Hh}mxt!D9@5yy1IpU(CH}Sy%xV7|;8glB_sYaeaSd`1p&MG~^1@;jf`}n5 zO-Fph%RZ@A7}53~8nR)ojL4+?@u|)bbiE;UAA-TU9< zxBr1ja1`p^Cumo*CYxx(fJj>iAmANATW7EF`6W{$ZG{2yuPs&}g2K|Uf%79C^)s=s zPA&JbsOAI#cSJcuZu%C|sX+=dn$~&q6sE^k9CZm`S=ud$=ZZN0uY%7M@t*mD()}rD z;N}AqFl@A-taF>REb1X+Ktw4ph9pX|%&KMXX#eN!Q?;gbA3a{0T~ zcdF(;Z3hM}BH%%XE3Q|X+&>rK9*H{8S_pioG@AUxLH^^7#;%Y%5nHg7nz^pJR}TPD z=8!nX%+Smabf;vx%(?s{3wn}X8#EFoq2}J-5WKLaNItoq1N$8?lH+VJ5$>KP64-;t zt2EbsQb!?5+K_56AXLq_NLNQgF-iZCve;>XV)t3lD^?9(GN63`#k))ML3MB>>M5fs zoXWD}^Aec?PqA`@^(9?F7z<=~=XtpMa!S@{cFi@iG$N9V?qvI#+>`p3s!@Sao=E-| zUi~w`mRN%c|7CC8TQHW+XANU!ROM%-0s=F@+#x~_UvY!b6deb>=1;J- zzQyBK0{+1fWszCzw)FjTT#A=fRdxW}a@kE8C-11F(a0T z`qfi+JN&1F4K7vE0^GtR3+{rbf5!uErlJkd!lugYR;&7f2WhhZ8iqL;v zvBLx?8KQY$wgO6>_@6tMH^0ye<3!#JQP9bL8_I+2t8{Z>aK8aV z+*^@)BV7b2lDim$u!j9ay&=*V4X2cI&ewAKN$BN)Iqs1jzgF`7V{wZ23^vN#@VS=S z{0&YZ=f2oo%O?`9U(l78(#i~#)N_z%v6HHRXxA=DQTs+c|916L%>9(ThnBk|zOZG} zQG<+adgorifAHB!C%g6Pyu+6##)aRm1s4iysR-WTSRgacoT$s53+FcYcG~C=iacD7 zQCuJ#BoW$wWQfxyf;2Mj60YlAE&P5li2S+KOCKZci&76zDy|gu#FZ<~%nMev$XoMR z8xT{JlO8vHWU8Hi-M*D}OT7engFxmkbw4u{ch#w5D7ygMY z_iE!+m(*}_@)xbN;(6vG)0xGTNyu$fc>qXrePMSGaE(4Y&p4zV0! z%UWyDP4ah494y7kw%EF?Ngyfc6b(OKlHPv`1_FCDf>c#Bc{V3nmtLrnp7;blQLXf0 zbB{(`wLWWT-ABWK&Ejb#t@y#yEYnD>T$l#cZv={u;$z?GD-%rqtx3{2&VIM~MEv@- z&;OPij#fvSfcS|C{jpZG(eUW?r6W&RcN)W45PFe}A9u zj2IB~nZ3T#2^moAzmS|p{_zbnJy!USg*##le+{fsKsYEmq=n^=)jT257kB9TZqV1Y z$f9WH)!Y@vTyN-l5{%hWp`k7rDR`5VTi*sxpK`??O}bL>PDmxvU;kbh?m=FmE!K{?P~n#5&L%t%wI`g+*ap(#@qVWRy5 zsro|*ci`_8cM2sH`v9w?kY}SFlTB3y+yEzjtH~eIV8*!RpBd`=A)Tu*%dXYo3HSiz zphpi))tgUrKZHTHB`whh+s;+r0Chw#kt0aEWGH(FqeS+K^Gk`<5`I7XJeYX;;pFl* zKq}dSaB~SPipQon3iGAyHV2WWX8Jc|9>KL?Uc{h0_~^mkr3Yc1gKet7bl)@bpDLtU z4!Pc5|ISE}feC-4e~_(HlZHd4}m3~55hkKEft{kx4%%u%xWfxQ?S}Vow zn%=S8ZrLprdJRwD2yiq#T;l(ufE@}H!$+MOlx$cWgeuBM$YH((o#3vbg6Fz0N$<#y zAz(Z`Ch-HD+UUZ;&rx|om;5DK{ur4;c(vlc^?Ag4_?GFjJ!o$oavAc6D578%znLu~ zd`lvF2fwf8Z@R32_}0#qF>YbRn=!Cp4Je7bMT1}S6;r=npvL|9wxO5V_2|8*r(d&0 zamEI-CBEZ?aQ@=>fVUe}DD@g4W=<9n^gkw35uVJwO(k9cr_qS-mB?Axy@N0V@P+es zuB9mAeq`Ru-}ZK+)`L_B09cghu@!sK|9y~QW7WCcB2>DlbWm4wSJ?qV-z3!to=bT6 zUU!eiXt@OKvz9VYcH;%h46izIZRl#VB{)YUE#P6<`T4zov(d9Mr!x`Q|#44Y?%XJsBOwVKe zGJxtoK&^NrCLGScXu4hwYYc9@1}Z{suRE?xpQy+yl5*ohW?;Uc0fwb~I z1lhWUw>-Ml=}<}gvKSW9aMfYwXm0C`h`!R%?tU%$S24J_4z!@XpX;t{@RDj@^v$9B zRPN5wDuNsuwLUplG!?WE2R~_ zjyd-UwR7=f1*-PU1`0As)nKH7%8}!vG-JTS5-6dX#x*lJhz^Qo4uGwbdm~7l&SMI^vU` zGRQnY2omFW9-8}x=9WgP(9b^nACpIou-W`3iyk+Z16zLy);rcBsdwL$*|VS=ZQlqF zSsbFG4`M`qiW&-I8xRrP zyLQLRD5UCayDZ%y$H|%5+3z#ZKm0Sj;iDA=`oP`(=W*qNJutRFr4cx>`2G50#y0P> z0by0+H{9GCgrcu|B@|rKR{7urhrGcTh7w&Av>qwDhFs=&quok>lW?|6INPUDS0r|K zWf}?e2yt_fS*|z{T{^$}Ka1?T0v?AgnSgl3-HvA1h~WMX;dlg|Ad(YEF3>P3`}LmX zlrGv2cH!l{g@oegkj~&QS-qdm@F@HldIzkS-c)A%Q1_^nA6%T>cFxt05ZKYp3=d=Q zY?lP_jFA)0;AMZZ+apLa#YKEpd$IMnQ&qRCxVxn(PjIa?Bj`0zrf{k6zgf>*6+^c} z+N6nM$NW)x`7<9>$i(j8EUr&FujhR?U^L1@ur#q0zo|j3eyI@^99tKeM_&43K)E{5 z)Y|>pSm4%BL&T!H?S`^YSwjL!M~`k6Jaq3CH-^8NAii=?mYwH?b zw!JcZ%5v7xi&C*dscVuSy%_7J{GDZI&}!f@N2KS@j@9U1;SYP~@x3wdqcid2m_QYb`k98vqbgA>(lQH*1Ay+5yZ%i3gAy-U0 zPoPK@_;);VsAUz3xfYqla{_BBYKlK-9H0xHOK>x*>zD^i8-eOE@+>kfZQmGlpifzw zn7;_4E-;mLSI31}5p^35`<2MX&#o4vYre8Izto~CaOJwErs$u;<#5jQ$wXc;LYiU>Tco3AsymUY zrF;g~JSfi8&bh;wp}&MBIf2Q>SOYB%ebNfmfgXK@r*w5suKJg5!?>p=pc}2GLu?fL znfmu8m+PFevcU*vUl4FKO^LO`%9IluF6{YHpCMU51<~jnDcgH{Og1QoqcOS@;JW9{ z;y$<@Jyg(J<)UU-76}&VC+gA4tZH=>L)p@oV1LkK-{9$)>p8bSJka=jQJ!JiUsXJN zgJ~wLL}*CsPk57WgioII=voZIUC8umPq1JSh2*@_Qd?ThpHJMEC$ zk#L+w50`eAtSp*On#Z^kljts*=EF~X$ZikAi$7P(2M^04M-TMTCTx-5kngD1pmydL z&Qk9v0ga$dY)k@`tv1H{s@dm&9+?D30Yn*w5_~2>o+#HKCM@C z>E`Ry$~0AU6}b;sb4=8tmeEk3Mn#FSY=LN>AuPg@^u%&Bcz_2?J&gf|4P0TgV zmCA6NrmP$Bq%qhi#&TXsJf2hnb99G9ZRCYrsc^k_5D+YisGdAEIN!LR_7bN2swP}n=_=aPe0sO+Jj0Fc_`EO6^H@9xblU%!iusotA`$0D^!!+8T7|2dtBZXGcWoRR$MU*;$WIP3_wjH z>W$&~yjQt0$xG1*Uxt7FC}gn3L(~gd5s96ETv35=UQ;6KCj=%8pBQtZc>+(DzIZk~ z)o|-pgrq6E$WuBp)%&XCL1)WOOi%T;86tM8`_e+{x>gMn%jxg(GN26h9buEw9rpV0 z^>==!7w}#QWm<=s4J?}@wf(&EwLQqScsG{tCh-uxv5`MCO!p1U z=uPVKqpa$3`W%X>mQZ+p-R!!|v*02$E2G0N`B_tIEpL91IR}{vi`^LEzKajvx(z;q@4CDeReDjN;C>eW)_Zeg}?-& zJ!JQrq%`jSvPzc_Kgy}<@Y4PpU;<`2`)l!z%R9ofO?gAk?gb}@yqH#-I|=%VaRG9C z3>fhE;H1SSv8&apQQYjN499k2^$3G?HFib+jphaXqN=%b3iGF?VJ!VVr?D#BN0r+e zfXxw79bs30cAmDn>0QJyt|Dx+!~J}Iog`<@R7%`WX}Y)mXfwSJsEU9R2UR=+%$l2G zP>zLirih<=4b1hPRKIDkJL310PQA%x`G$G~ea!tvtz7f`%<+-+oZs8hLNOVlJ7Xa( zx5>+OlK~vQ=5T2YkDq-+ye-Hy|IDm&L@?X>8XxAxmud+SN&+781eNu3e(T5gt|=MT z0wNq9lQuRqfG7wsds#CUHh&+re8;#^kujX$psR&hwc&{EW`}<1Y}aZM^=`F|@w}go zO(f#G?~%#pukik^|7}xa&2cZ3%Z=DeAV_vj_d%icQYUJA6nWP7IRB!N%!muClMtuB ze&XW1rL19nK%R}`-7eQ;JBZrg-OSqc6QSdQLMTu3slj1S;C$)S&|OB`&4}f!zFW}} zJDW1Px5~URV$k$`ReIHXC+8&vhV+c;kCt4w_s73TFW~Wht;kzVO*8dW@)vsQ*Fy^d zz@;7UBTtbeQ-~}fxK#%e3+vAZ%{weM`f{O)N}%avU8$@q9w}gU4b2X9ilXQ49n`P$ob{}r8^mTE0pfhX`<=zbA^%y(wi$@9%uwE#xSC z^k&~3>1U^DPwxbCTZv;Su*qP7JuS0)_Sdf;PX=gRZek2UANqqzu-kMuU^RO2`VTkl z80wel-aET{5>c;uqw78IApK3g`F=X7Jx#w%rnX7a>MJ!_%+1<`=Y7zsAeNMZy&f>l zVU=9Bu=YE8n-+mi$Drm0N#Ut?Ux*LHK2MWTZp>0WTRjq4v(|KBBb2Nu-m_LFS-n~N zDNdr9@VrO{A9NaDmi9jHYVPUX8y%$>AG=2n9F?NPY=ls<5zx+6rl>4lI--kUmr)wv zb#P~(OOSO>I!?xHTLNQ$>X`U7JxX?V#f#4kP`$)6rmpbt1oUMp%`NE#5p^_k9qO(k zl_OFMA65tux|5uUD`PR#;?2FMe!5AtqF-fqS9t(S#U5gQI_6tUD)TTQ*Dk`<2YH$T zFE4?$m}v1@ll#xQaVXhnsLIk_Mm{XPU)PBQ8Aoot&Gyi>->M>W_jLJ^(SsmahG^>E zmHdpTW0d~na+@U4;|Z)2GbKL;ow+Bse2plPT5gMzNfI^l8mT=FzJC&vdfboK8`<#d zt*HJeyV^q?75g0%hl6JS4kJ!^9fyW6OOuTuzhuk)Aai41r>WVjpR}`EdBfoxoBU9? zbijbfW5s49vL<`&vHda5D-0Vq$GglM=3W(>iw7Zp-f?+HcFrewzB=RO=IveMl8oCv z7`@<)3GW^s#B8n4Vto!D5)wHny`#9SDz*UwR6r}=PkuE$ws#LK>V9>afcp-Q1*gAN z=Ik2SEm1}$NqgYA z^|`;gRU_$>jUqcSlccZ>fTy+`Hivq$2E(MDj4<6W80^&pw~gh)ROQD`>m5wVFR|My zrt^DMXv0F!4e};Gx7<+~6l5g+l3h4RcSi#8)z^_@musQ405=m+sm~F+2 zbqXfeL;8VmuPHU9xaSi)$GgOc7?Q;a#0wmd=G(E>WdRSAqb>W*ile&D?|{t6o~ zT@PV3NM0JFTlZllt0Vv1y-DiR@-!vt1o})0?=M&E%=-IiBaWErs zINf-w)@`dXF&egJb-B(spLh|+5zs(ka`1OEfDha&^YMj*3wf92E2MjX28DmA1Cd&u z(IEz{9-}2_hnQ5uJbfv-kU)Cfznl+DbAP9qeT6X|{{(Qe3MXDhp$%E@$M?f6 zppVTy!1?lh#pb6E`ggb!KP}k|oVt)$X+znoSQ5!J*=3rT0 z7dr$;UlK~k?XHe|Qw!vk_%9`KT#+dx`E`jpzD;e0DlZ9*jOpz_x&uu(Xz=0YWnZ9f zf`wg%DnqH0jkBf1#H1!}iI=;hbvP(1%`*M?iynCx4)@!pC5QrJgRn-1D2{y?@#>?u zQ4qY?qDOmse}|>580hwRHr2tIBsMwv+d#mMGS-wL8yPv>XIMXK19|MU{T3ITN;aZ+ zVHoqZXAs0`IP#yD+hgTz|Hw5#`#nRX*AU-kb6yXE2n&;og*doVL%?Qh!vi<}UN&+V zySnQr=!IO;_;NyTMPPU=);aq0jgifP z>!Sn`0iIw`XZ@d9uIM{#wUIMqfWD6+o)Z|+y&{NmysD7e0IBZq>l(L5JS-BJu)PBu zfWO%QrRLCBX-cVO*M*O6xKD?+{s1RJPYq)*W5L~BxLQv?6R#!#+56{+^drbLQG2F2 z7Z(NJdMfJ|0GyS)VmDOX!#5NvdjuXIg-&A&;R`tcM}3GLKJjhf^m%tVD@e4PJVaR* z1rlx8g|!yGi5O}f>P#{=UH@wTund@!-tReqV_7!|ys&bDL0LL30XW~;j@_>XfN%^z z6x+Cj@AP{gR4srh_X3AQ9CkD6R6Eq)gLUaVc`>h!QhaNDr3C0a1%U=sXcQPbNZo_@ zmpCxUTf~sd>rIG2?w8n%QGWsVCvR)b$jB)Fx;RShJ4{`ovG!Tto2vs#Tn{4w2ENhp z3`_63KYZb%r?OLKn&sQ$&q|smru~6)Dxh9#(tPc{Phq;4r*9*LP%~k@i5_YumE-iGUN1_3g)6%}B7$O21}y;j zCRSYG$^uJDvPjemTr&bqoE~I0`tf#o1~IUUUW5*AivcgK3_(yCQ34=A1ai(gg%6~P96fEdqMO4L!qdw|yRKcTI zs{ZtXMUJBG`Egdj^Okk%eCWFK(rk#zJsKVVN&T4ydnQJ1xf)HZOX5K5^zdz`)v_ zQ>~&yCu4KsPUSdAE*x!D?Y*7fV&T3zakz?c(q-t{g2pQa(bA
  • ') + .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/docs/_spec/public/stylesheets/fonts.css b/docs/_spec/public/stylesheets/fonts.css new file mode 100644 index 000000000000..36efb2bbd5a0 --- /dev/null +++ b/docs/_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/docs/_spec/public/stylesheets/print.css b/docs/_spec/public/stylesheets/print.css new file mode 100644 index 000000000000..f0efff28b203 --- /dev/null +++ b/docs/_spec/public/stylesheets/print.css @@ -0,0 +1,42 @@ +/* This removes a few things from screen.css for printing */ + +body { + padding: 0px; + margin: 0px; +} + +.anchor, #navigation, .to_top, .version-notice, .hidden-print { + display: none !important; +} + +.print-only { + display: block; +} + +#content-container { + width: 100%; + float: none; +} + +/* no scrollbars, jump to next row.. */ +.highlight pre code { + overflow: hidden; + white-space: pre-wrap; +} + +main { + position: relative; + top: 32px; + margin: 0 0 0 0; + padding: 0px 32px; + max-width: none; + min-width: none; + min-height: none; + background-color: #FFF; +} + +/* Avoid clipped headings https://github.com/pdfkit/pdfkit/issues/113#issuecomment-7027798 */ +h2, h3, h4, h5, h6 { + padding: 0px; + margin: 0px; +} diff --git a/docs/_spec/public/stylesheets/screen-small.css b/docs/_spec/public/stylesheets/screen-small.css new file mode 100644 index 000000000000..674db7c49000 --- /dev/null +++ b/docs/_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/docs/_spec/public/stylesheets/screen-toc.css b/docs/_spec/public/stylesheets/screen-toc.css new file mode 100644 index 000000000000..7a04bd00f96c --- /dev/null +++ b/docs/_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/docs/_spec/public/stylesheets/screen.css b/docs/_spec/public/stylesheets/screen.css new file mode 100644 index 000000000000..2073613eaea7 --- /dev/null +++ b/docs/_spec/public/stylesheets/screen.css @@ -0,0 +1,521 @@ +/* from https://gist.github.com/andyferra/2554919 */ + +body { + font-family:Heuristica,Georgia,serif; + color: #222222; + line-height: 1.6; + + padding-bottom: 10px; + background-color: white; + padding-left: 30px; +} + +#content-container > *:first-child { + margin-top: 0 !important; +} +#content-container > *:last-child { + margin-bottom: 0 !important; +} + +a { + color: #08C; + text-decoration: none; +} +a:hover, a:focus { + +} +a.absent { + color: #cc0000; +} +a.anchor { + display: block; + margin-left: -35px; + padding-left: 10px; + cursor: pointer; + position: absolute; + top: 0; + left: 0; + bottom: 0; + color: black; + width: 35px; height: 100%; +} + +a.anchor span { + vertical-align: middle; +} + +h1, h2, h3, h4, h5, h6 { + 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; + pointer-events: none; +} + +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; +} + +h1:hover a.anchor span, h2:hover a.anchor span, h3:hover a.anchor span, h4:hover a.anchor span, h5:hover a.anchor span, h6:hover a.anchor span { + display: inline-block; +} + +h1 a.anchor span, h2 a.anchor span, h3 a.anchor span, h4 a.anchor span, h5 a.anchor span, h6 a.anchor span { + display: none; +} + +h1 a.anchor:hover span, h2 a.anchor:hover span, h3 a.anchor:hover span, h4 a.anchor:hover span, h5 a.anchor:hover span, h6 a.anchor:hover span { + display: inline-block; +} + +h1 tt, h1 code { + font-size: inherit; +} + +h2 tt, h2 code { + font-size: inherit; +} + +h3 tt, h3 code { + font-size: inherit; +} + +h4 tt, h4 code { + font-size: inherit; +} + +h5 tt, h5 code { + font-size: inherit; +} + +h6 tt, h6 code { + font-size: inherit; +} + +h1 { + font-size: 28px; + color: black; +} + +h2 { + font-size: 24px; + color: black; +} + +h3 { + font-size: 18px; +} + +h4 { + font-size: 16px; +} + +h5 { + font-size: 14px; +} + +h6 { + color: #777777; + font-size: 14px; +} + +p, blockquote, ul, ol, dl, li, table, pre { + margin: 5px 0 15px; + -moz-font-feature-settings: "onum"; + -ms-font-feature-settings: "onum"; + -webkit-font-feature-settings: "onum"; + font-feature-settings: "onum"; +} + +hr { + background: transparent repeat-x 0 0; + border: 0 none; + color: #cccccc; + height: 4px; + padding: 0; +} + +body > h2:first-child { + margin-top: 0; + padding-top: 0; +} +body > h1:first-child { + margin-top: 0; + padding-top: 0; +} +body > h1:first-child + h2 { + margin-top: 0; + padding-top: 0; +} +body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { + margin-top: 0; + padding-top: 0; +} + +a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { + margin-top: 0; + padding-top: 0; +} + +h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { + margin-top: 0; +} + +li p.first { + display: inline-block; +} + +ul, ol { + padding-left: 30px; +} + +ul :first-child, ol :first-child { + margin-top: 0; +} + +ul :last-child, ol :last-child { + margin-bottom: 0; +} + +dl { + padding: 0; +} +dl dt { + font-size: 14px; + font-weight: bold; + font-style: italic; + padding: 0; + margin: 15px 0 5px; +} +dl dt:first-child { + padding: 0; +} +dl dt > :first-child { + margin-top: 0; +} +dl dt > :last-child { + margin-bottom: 0; +} +dl dd { + margin: 0 0 15px; + padding: 0 15px; +} +dl dd > :first-child { + margin-top: 0; +} +dl dd > :last-child { + margin-bottom: 0; +} + +blockquote { + border-left: 4px solid #dddddd; + padding: 0 15px; + color: #222222; +} +blockquote > :first-child { + margin-top: 0; +} +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 { + background-color: white; +} +table tr:nth-child(2n) { + background-color: #f8f8f8; +} +table tr th { + background-color: #EAEAEA; + font-weight: bold; + text-align: left; + padding: 5px 13px; +} +table tr td { + text-align: left; + padding: 5px 13px; +} +table tr th :first-child, table tr td :first-child { + margin-top: 0; +} +table tr th :last-child, table tr td :last-child { + margin-bottom: 0; +} + +img { + max-width: 100%; +} + +span.frame { + display: block; + overflow: hidden; +} +span.frame > span { + border: 1px solid #dddddd; + display: block; + float: left; + overflow: hidden; + margin: 13px 0 0; + padding: 7px; + width: auto; +} +span.frame span img { + display: block; + float: left; +} +span.frame span span { + clear: both; + color: #333333; + display: block; + padding: 5px 0 0; +} +span.align-center { + display: block; + overflow: hidden; + clear: both; +} +span.align-center > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: center; +} +span.align-center span img { + margin: 0 auto; + text-align: center; +} +span.align-right { + display: block; + overflow: hidden; + clear: both; +} +span.align-right > span { + display: block; + overflow: hidden; + margin: 13px 0 0; + text-align: right; +} +span.align-right span img { + margin: 0; + text-align: right; +} +span.float-left { + display: block; + margin-right: 13px; + overflow: hidden; + float: left; +} +span.float-left span { + margin: 13px 0 0; +} +span.float-right { + display: block; + margin-left: 13px; + overflow: hidden; + float: right; +} +span.float-right > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: right; +} + +pre, code, tt { + font:14px "Luxi Mono", 'andale mono', 'lucida console', monospace; + line-height:1.5; +} + +.highlight pre { + background-color: #F8F8F8; + border-radius: 3px; + overflow: auto; + padding: 6px 10px; + white-space: nowrap; +} + +code { + background-color: transparent; + border: none; + margin: 0; + padding: 0; + white-space: pre; +} + +aside.left { + height: 100%; + position: fixed; + direction: rtl; + overflow: auto; + left: 0px; + width: 320px; + bottom: -32px; + font-family: "Luxi Sans", serif; + background-color: #073642; +} + +aside.left > nav { + direction: ltr; + top: 32px; + padding-bottom: 32px; +} + +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { + display: block; +} + +audio, canvas, img, svg, video { + vertical-align: middle; +} + +audio, canvas, progress, video { + display: inline-block; + vertical-align: baseline; +} + +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; +} + +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); +} + +#chapters a { + color: #FFFFFF; + text-decoration: none; + font-size: 0.63vw; + padding: 100% 5px; +} + +#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; +} + +#chapters a.chapter-active { + background: #72D0EB; +} + + +#toc ul { + margin: 0; + padding: 0; + list-style: none; +} + +#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; +} + +#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; } + +.version-notice { + background-color: #C93A3A; + color: #f2f2f2; + border:1px solid #ccc; + padding: 1em; + margin-bottom: 1em; +} +.version-notice a { + color: #f2f2f2; + font-weight: bold; + text-decoration: underline; +} + +.print-only { + display: none; +} diff --git a/docs/_spec/spec-toc.xslt b/docs/_spec/spec-toc.xslt new file mode 100644 index 000000000000..437b15e3e6f4 --- /dev/null +++ b/docs/_spec/spec-toc.xslt @@ -0,0 +1,64 @@ + + + + + + + Table of Contents + + + ./public/stylesheets/fonts.css + + + + +

      Table of Contents

      +
      + + +
      + +
    • + + + +
        + added to prevent self-closing tags in QtXmlPatterns + +
      +
    • + + From 34b836b463410ba2f7a44a0f3fe1c72385cf4f8f Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Wed, 12 Oct 2022 13:51:03 +0200 Subject: [PATCH 02/11] Add copy of reference as TODO reference taken from https://github.com/lampepfl/dotty/commit/7919cb375a3d1c931ed3841617774bdd8c49c62c --- .../changed-features/changed-features.md | 7 + .../changed-features/compiler-plugins.md | 128 +++ .../changed-features/eta-expansion-spec.md | 77 ++ .../changed-features/eta-expansion.md | 42 + .../implicit-conversions-spec.md | 117 +++ .../changed-features/implicit-conversions.md | 65 ++ .../changed-features/implicit-resolution.md | 169 ++++ .../TODOreference/changed-features/imports.md | 60 ++ .../changed-features/interpolation-escapes.md | 14 + .../changed-features/lazy-vals-init.md | 80 ++ .../changed-features/main-functions.md | 87 ++ .../changed-features/match-syntax.md | 56 ++ .../changed-features/numeric-literals.md | 7 + .../changed-features/operators.md | 173 ++++ .../changed-features/overload-resolution.md | 102 +++ .../changed-features/pattern-bindings.md | 59 ++ .../changed-features/pattern-matching.md | 243 ++++++ .../changed-features/structural-types-spec.md | 153 ++++ .../changed-features/structural-types.md | 191 ++++ .../changed-features/type-checking.md | 7 + .../changed-features/type-inference.md | 10 + .../changed-features/vararg-splices.md | 40 + .../changed-features/wildcards.md | 50 ++ .../contextual/by-name-context-parameters.md | 65 ++ .../contextual/context-bounds.md | 53 ++ .../contextual/context-functions-spec.md | 79 ++ .../contextual/context-functions.md | 154 ++++ .../TODOreference/contextual/contextual.md | 83 ++ .../TODOreference/contextual/conversions.md | 76 ++ .../contextual/derivation-macro.md | 205 +++++ .../TODOreference/contextual/derivation.md | 425 +++++++++ .../contextual/extension-methods.md | 306 +++++++ .../TODOreference/contextual/given-imports.md | 117 +++ docs/_spec/TODOreference/contextual/givens.md | 193 ++++ .../contextual/multiversal-equality.md | 227 +++++ .../contextual/relationship-implicits.md | 206 +++++ .../right-associative-extension-methods.md | 52 ++ .../TODOreference/contextual/type-classes.md | 282 ++++++ .../TODOreference/contextual/using-clauses.md | 153 ++++ .../dropped-features/auto-apply.md | 96 ++ .../dropped-features/class-shadowing-spec.md | 26 + .../dropped-features/class-shadowing.md | 33 + .../dropped-features/delayed-init.md | 32 + .../dropped-features/do-while.md | 41 + .../dropped-features/dropped-features.md | 7 + .../dropped-features/early-initializers.md | 16 + .../dropped-features/existential-types.md | 35 + .../TODOreference/dropped-features/limit22.md | 17 + .../TODOreference/dropped-features/macros.md | 16 + .../dropped-features/nonlocal-returns.md | 29 + .../dropped-features/package-objects.md | 48 + .../dropped-features/procedure-syntax.md | 19 + .../TODOreference/dropped-features/symlits.md | 24 + .../dropped-features/this-qualifier.md | 33 + .../dropped-features/type-projection.md | 18 + .../dropped-features/weak-conformance-spec.md | 54 ++ .../dropped-features/weak-conformance.md | 47 + .../dropped-features/wildcard-init.md | 23 + .../TODOreference/dropped-features/xml.md | 39 + docs/_spec/TODOreference/enums/adts.md | 173 ++++ .../_spec/TODOreference/enums/desugarEnums.md | 215 +++++ docs/_spec/TODOreference/enums/enums-index.md | 7 + docs/_spec/TODOreference/enums/enums.md | 222 +++++ .../TODOreference/experimental/canthrow.md | 281 ++++++ docs/_spec/TODOreference/experimental/cc.md | 738 ++++++++++++++++ .../experimental/erased-defs-spec.md | 64 ++ .../TODOreference/experimental/erased-defs.md | 231 +++++ .../experimental/explicit-nulls.md | 543 ++++++++++++ .../experimental/fewer-braces.md | 7 + .../experimental/main-annotation.md | 97 +++ .../experimental/named-typeargs-spec.md | 41 + .../experimental/named-typeargs.md | 34 + .../experimental/numeric-literals.md | 257 ++++++ .../TODOreference/experimental/overview.md | 29 + .../experimental/tupled-function.md | 82 ++ .../TODOreference/features-classification.md | 199 +++++ .../language-versions/binary-compatibility.md | 13 + .../language-versions/language-versions.md | 7 + .../language-versions/source-compatibility.md | 43 + .../metaprogramming/compiletime-ops.md | 294 +++++++ .../TODOreference/metaprogramming/inline.md | 390 +++++++++ .../metaprogramming/macros-spec.md | 254 ++++++ .../TODOreference/metaprogramming/macros.md | 823 ++++++++++++++++++ .../metaprogramming/metaprogramming.md | 47 + .../metaprogramming/reflection.md | 131 +++ .../metaprogramming/simple-smp.md | 232 +++++ .../TODOreference/metaprogramming/staging.md | 121 +++ .../metaprogramming/tasty-inspect.md | 57 ++ .../dependent-function-types-spec.md | 125 +++ .../new-types/dependent-function-types.md | 49 ++ .../new-types/intersection-types-spec.md | 108 +++ .../new-types/intersection-types.md | 68 ++ .../TODOreference/new-types/match-types.md | 247 ++++++ .../TODOreference/new-types/new-types.md | 7 + .../new-types/polymorphic-function-types.md | 94 ++ .../new-types/type-lambdas-spec.md | 116 +++ .../TODOreference/new-types/type-lambdas.md | 17 + .../new-types/union-types-spec.md | 172 ++++ .../TODOreference/new-types/union-types.md | 46 + .../other-new-features/control-syntax.md | 47 + .../creator-applications.md | 57 ++ .../other-new-features/experimental-defs.md | 318 +++++++ .../other-new-features/export.md | 234 +++++ .../other-new-features/indentation.md | 509 +++++++++++ .../other-new-features/kind-polymorphism.md | 47 + .../other-new-features/matchable.md | 141 +++ .../other-new-features/opaques-details.md | 126 +++ .../other-new-features/opaques.md | 179 ++++ .../other-new-features/open-classes.md | 80 ++ .../other-new-features/other-new-features.md | 7 + .../parameter-untupling-spec.md | 89 ++ .../other-new-features/parameter-untupling.md | 77 ++ .../other-new-features/safe-initialization.md | 343 ++++++++ .../other-new-features/targetName.md | 118 +++ .../threadUnsafe-annotation.md | 18 + .../other-new-features/trait-parameters.md | 88 ++ .../other-new-features/transparent-traits.md | 70 ++ .../other-new-features/type-test.md | 181 ++++ docs/_spec/TODOreference/overview.md | 155 ++++ docs/_spec/TODOreference/soft-modifier.md | 27 + docs/_spec/TODOreference/syntax.md | 472 ++++++++++ 121 files changed, 15330 insertions(+) create mode 100644 docs/_spec/TODOreference/changed-features/changed-features.md create mode 100644 docs/_spec/TODOreference/changed-features/compiler-plugins.md create mode 100644 docs/_spec/TODOreference/changed-features/eta-expansion-spec.md create mode 100644 docs/_spec/TODOreference/changed-features/eta-expansion.md create mode 100644 docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md create mode 100644 docs/_spec/TODOreference/changed-features/implicit-conversions.md create mode 100644 docs/_spec/TODOreference/changed-features/implicit-resolution.md create mode 100644 docs/_spec/TODOreference/changed-features/imports.md create mode 100644 docs/_spec/TODOreference/changed-features/interpolation-escapes.md create mode 100644 docs/_spec/TODOreference/changed-features/lazy-vals-init.md create mode 100644 docs/_spec/TODOreference/changed-features/main-functions.md create mode 100644 docs/_spec/TODOreference/changed-features/match-syntax.md create mode 100644 docs/_spec/TODOreference/changed-features/numeric-literals.md create mode 100644 docs/_spec/TODOreference/changed-features/operators.md create mode 100644 docs/_spec/TODOreference/changed-features/overload-resolution.md create mode 100644 docs/_spec/TODOreference/changed-features/pattern-bindings.md create mode 100644 docs/_spec/TODOreference/changed-features/pattern-matching.md create mode 100644 docs/_spec/TODOreference/changed-features/structural-types-spec.md create mode 100644 docs/_spec/TODOreference/changed-features/structural-types.md create mode 100644 docs/_spec/TODOreference/changed-features/type-checking.md create mode 100644 docs/_spec/TODOreference/changed-features/type-inference.md create mode 100644 docs/_spec/TODOreference/changed-features/vararg-splices.md create mode 100644 docs/_spec/TODOreference/changed-features/wildcards.md create mode 100644 docs/_spec/TODOreference/contextual/by-name-context-parameters.md create mode 100644 docs/_spec/TODOreference/contextual/context-bounds.md create mode 100644 docs/_spec/TODOreference/contextual/context-functions-spec.md create mode 100644 docs/_spec/TODOreference/contextual/context-functions.md create mode 100644 docs/_spec/TODOreference/contextual/contextual.md create mode 100644 docs/_spec/TODOreference/contextual/conversions.md create mode 100644 docs/_spec/TODOreference/contextual/derivation-macro.md create mode 100644 docs/_spec/TODOreference/contextual/derivation.md create mode 100644 docs/_spec/TODOreference/contextual/extension-methods.md create mode 100644 docs/_spec/TODOreference/contextual/given-imports.md create mode 100644 docs/_spec/TODOreference/contextual/givens.md create mode 100644 docs/_spec/TODOreference/contextual/multiversal-equality.md create mode 100644 docs/_spec/TODOreference/contextual/relationship-implicits.md create mode 100644 docs/_spec/TODOreference/contextual/right-associative-extension-methods.md create mode 100644 docs/_spec/TODOreference/contextual/type-classes.md create mode 100644 docs/_spec/TODOreference/contextual/using-clauses.md create mode 100644 docs/_spec/TODOreference/dropped-features/auto-apply.md create mode 100644 docs/_spec/TODOreference/dropped-features/class-shadowing-spec.md create mode 100644 docs/_spec/TODOreference/dropped-features/class-shadowing.md create mode 100644 docs/_spec/TODOreference/dropped-features/delayed-init.md create mode 100644 docs/_spec/TODOreference/dropped-features/do-while.md create mode 100644 docs/_spec/TODOreference/dropped-features/dropped-features.md create mode 100644 docs/_spec/TODOreference/dropped-features/early-initializers.md create mode 100644 docs/_spec/TODOreference/dropped-features/existential-types.md create mode 100644 docs/_spec/TODOreference/dropped-features/limit22.md create mode 100644 docs/_spec/TODOreference/dropped-features/macros.md create mode 100644 docs/_spec/TODOreference/dropped-features/nonlocal-returns.md create mode 100644 docs/_spec/TODOreference/dropped-features/package-objects.md create mode 100644 docs/_spec/TODOreference/dropped-features/procedure-syntax.md create mode 100644 docs/_spec/TODOreference/dropped-features/symlits.md create mode 100644 docs/_spec/TODOreference/dropped-features/this-qualifier.md create mode 100644 docs/_spec/TODOreference/dropped-features/type-projection.md create mode 100644 docs/_spec/TODOreference/dropped-features/weak-conformance-spec.md create mode 100644 docs/_spec/TODOreference/dropped-features/weak-conformance.md create mode 100644 docs/_spec/TODOreference/dropped-features/wildcard-init.md create mode 100644 docs/_spec/TODOreference/dropped-features/xml.md create mode 100644 docs/_spec/TODOreference/enums/adts.md create mode 100644 docs/_spec/TODOreference/enums/desugarEnums.md create mode 100644 docs/_spec/TODOreference/enums/enums-index.md create mode 100644 docs/_spec/TODOreference/enums/enums.md create mode 100644 docs/_spec/TODOreference/experimental/canthrow.md create mode 100644 docs/_spec/TODOreference/experimental/cc.md create mode 100644 docs/_spec/TODOreference/experimental/erased-defs-spec.md create mode 100644 docs/_spec/TODOreference/experimental/erased-defs.md create mode 100644 docs/_spec/TODOreference/experimental/explicit-nulls.md create mode 100644 docs/_spec/TODOreference/experimental/fewer-braces.md create mode 100644 docs/_spec/TODOreference/experimental/main-annotation.md create mode 100644 docs/_spec/TODOreference/experimental/named-typeargs-spec.md create mode 100644 docs/_spec/TODOreference/experimental/named-typeargs.md create mode 100644 docs/_spec/TODOreference/experimental/numeric-literals.md create mode 100644 docs/_spec/TODOreference/experimental/overview.md create mode 100644 docs/_spec/TODOreference/experimental/tupled-function.md create mode 100644 docs/_spec/TODOreference/features-classification.md create mode 100644 docs/_spec/TODOreference/language-versions/binary-compatibility.md create mode 100644 docs/_spec/TODOreference/language-versions/language-versions.md create mode 100644 docs/_spec/TODOreference/language-versions/source-compatibility.md create mode 100644 docs/_spec/TODOreference/metaprogramming/compiletime-ops.md create mode 100644 docs/_spec/TODOreference/metaprogramming/inline.md create mode 100644 docs/_spec/TODOreference/metaprogramming/macros-spec.md create mode 100644 docs/_spec/TODOreference/metaprogramming/macros.md create mode 100644 docs/_spec/TODOreference/metaprogramming/metaprogramming.md create mode 100644 docs/_spec/TODOreference/metaprogramming/reflection.md create mode 100644 docs/_spec/TODOreference/metaprogramming/simple-smp.md create mode 100644 docs/_spec/TODOreference/metaprogramming/staging.md create mode 100644 docs/_spec/TODOreference/metaprogramming/tasty-inspect.md create mode 100644 docs/_spec/TODOreference/new-types/dependent-function-types-spec.md create mode 100644 docs/_spec/TODOreference/new-types/dependent-function-types.md create mode 100644 docs/_spec/TODOreference/new-types/intersection-types-spec.md create mode 100644 docs/_spec/TODOreference/new-types/intersection-types.md create mode 100644 docs/_spec/TODOreference/new-types/match-types.md create mode 100644 docs/_spec/TODOreference/new-types/new-types.md create mode 100644 docs/_spec/TODOreference/new-types/polymorphic-function-types.md create mode 100644 docs/_spec/TODOreference/new-types/type-lambdas-spec.md create mode 100644 docs/_spec/TODOreference/new-types/type-lambdas.md create mode 100644 docs/_spec/TODOreference/new-types/union-types-spec.md create mode 100644 docs/_spec/TODOreference/new-types/union-types.md create mode 100644 docs/_spec/TODOreference/other-new-features/control-syntax.md create mode 100644 docs/_spec/TODOreference/other-new-features/creator-applications.md create mode 100644 docs/_spec/TODOreference/other-new-features/experimental-defs.md create mode 100644 docs/_spec/TODOreference/other-new-features/export.md create mode 100644 docs/_spec/TODOreference/other-new-features/indentation.md create mode 100644 docs/_spec/TODOreference/other-new-features/kind-polymorphism.md create mode 100644 docs/_spec/TODOreference/other-new-features/matchable.md create mode 100644 docs/_spec/TODOreference/other-new-features/opaques-details.md create mode 100644 docs/_spec/TODOreference/other-new-features/opaques.md create mode 100644 docs/_spec/TODOreference/other-new-features/open-classes.md create mode 100644 docs/_spec/TODOreference/other-new-features/other-new-features.md create mode 100644 docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md create mode 100644 docs/_spec/TODOreference/other-new-features/parameter-untupling.md create mode 100644 docs/_spec/TODOreference/other-new-features/safe-initialization.md create mode 100644 docs/_spec/TODOreference/other-new-features/targetName.md create mode 100644 docs/_spec/TODOreference/other-new-features/threadUnsafe-annotation.md create mode 100644 docs/_spec/TODOreference/other-new-features/trait-parameters.md create mode 100644 docs/_spec/TODOreference/other-new-features/transparent-traits.md create mode 100644 docs/_spec/TODOreference/other-new-features/type-test.md create mode 100644 docs/_spec/TODOreference/overview.md create mode 100644 docs/_spec/TODOreference/soft-modifier.md create mode 100644 docs/_spec/TODOreference/syntax.md diff --git a/docs/_spec/TODOreference/changed-features/changed-features.md b/docs/_spec/TODOreference/changed-features/changed-features.md new file mode 100644 index 000000000000..cacdc2598a02 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/changed-features.md @@ -0,0 +1,7 @@ +--- +layout: index +title: "Other Changed Features" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features.html +--- + +The following pages document the features that have changed in Scala 3, compared to Scala 2. diff --git a/docs/_spec/TODOreference/changed-features/compiler-plugins.md b/docs/_spec/TODOreference/changed-features/compiler-plugins.md new file mode 100644 index 000000000000..20bdb7f49836 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/compiler-plugins.md @@ -0,0 +1,128 @@ +--- +layout: doc-page +title: "Changes in Compiler Plugins" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/compiler-plugins.html +--- + +Compiler plugins are supported by Dotty (and Scala 3) since 0.9. There are two notable changes +compared to `scalac`: + +- No support for analyzer plugins +- Added support for research plugins + +[Analyzer plugins][1] in `scalac` run during type checking and may influence +normal type checking. This is a very powerful feature but for production usages, +a predictable and consistent type checker is more important. + +For experimentation and research, Scala 3 introduces _research plugin_. Research plugins +are more powerful than `scalac` analyzer plugins as they let plugin authors customize +the whole compiler pipeline. One can easily replace the standard typer by a custom one or +create a parser for a domain-specific language. However, research plugins are only +enabled for nightly or snaphot releases of Scala 3. + +Common plugins that add new phases to the compiler pipeline are called +_standard plugins_ in Scala 3. In terms of features, they are similar to +`scalac` plugins, despite minor changes in the API. + +## Using Compiler Plugins + +Both standard and research plugins can be used with `scalac` by adding the `-Xplugin:` option: + +```shell +scalac -Xplugin:pluginA.jar -Xplugin:pluginB.jar Test.scala +``` + +The compiler will examine the jar provided, and look for a property file named +`plugin.properties` in the root directory of the jar. The property file specifies +the fully qualified plugin class name. The format of a property file is as follows: + +```properties +pluginClass=dividezero.DivideZero +``` + +This is different from `scalac` plugins that required a `scalac-plugin.xml` file. + +Starting from 1.1.5, `sbt` also supports Scala 3 compiler plugins. Please refer to the +[`sbt` documentation][2] for more information. + +## Writing a Standard Compiler Plugin + +Here is the source code for a simple compiler plugin that reports integer divisions by +zero as errors. + +```scala +package dividezero + +import dotty.tools.dotc.ast.Trees.* +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Constants.Constant +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Decorators.* +import dotty.tools.dotc.core.StdNames.* +import dotty.tools.dotc.core.Symbols.* +import dotty.tools.dotc.plugins.{PluginPhase, StandardPlugin} +import dotty.tools.dotc.transform.{Pickler, Staging} + +class DivideZero extends StandardPlugin: + val name: String = "divideZero" + override val description: String = "divide zero check" + + def init(options: List[String]): List[PluginPhase] = + (new DivideZeroPhase) :: Nil + +class DivideZeroPhase extends PluginPhase: + import tpd.* + + val phaseName = "divideZero" + + override val runsAfter = Set(Pickler.name) + override val runsBefore = Set(Staging.name) + + override def transformApply(tree: Apply)(implicit ctx: Context): Tree = + tree match + case Apply(Select(rcvr, nme.DIV), List(Literal(Constant(0)))) + if rcvr.tpe <:< defn.IntType => + report.error("dividing by zero", tree.pos) + case _ => + () + tree +end DivideZeroPhase +``` + +The plugin main class (`DivideZero`) must extend the trait `StandardPlugin` +and implement the method `init` that takes the plugin's options as argument +and returns a list of `PluginPhase`s to be inserted into the compilation pipeline. + +Our plugin adds one compiler phase to the pipeline. A compiler phase must extend +the `PluginPhase` trait. In order to specify when the phase is executed, we also +need to specify a `runsBefore` and `runsAfter` constraints that are list of phase +names. + +We can now transform trees by overriding methods like `transformXXX`. + +## Writing a Research Compiler Plugin + +Here is a template for research plugins. + +```scala +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Phases.Phase +import dotty.tools.dotc.plugins.ResearchPlugin + +class DummyResearchPlugin extends ResearchPlugin: + val name: String = "dummy" + override val description: String = "dummy research plugin" + + def init(options: List[String], phases: List[List[Phase]])(implicit ctx: Context): List[List[Phase]] = + phases +end DummyResearchPlugin +``` + +A research plugin must extend the trait `ResearchPlugin` and implement the +method `init` that takes the plugin's options as argument as well as the compiler +pipeline in the form of a list of compiler phases. The method can replace, remove +or add any phases to the pipeline and return the updated pipeline. + + +[1]: https://github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala +[2]: https://www.scala-sbt.org/1.x/docs/Compiler-Plugins.html diff --git a/docs/_spec/TODOreference/changed-features/eta-expansion-spec.md b/docs/_spec/TODOreference/changed-features/eta-expansion-spec.md new file mode 100644 index 000000000000..a62d45df9e11 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/eta-expansion-spec.md @@ -0,0 +1,77 @@ +--- +layout: doc-page +title: "Automatic Eta Expansion - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/eta-expansion-spec.html +--- + +## Motivation + +Scala maintains a convenient distinction between _methods_ and _functions_. +Methods are part of the definition of a class that can be invoked in objects while functions are complete objects themselves, making them first-class entities. For example, they can be assigned to variables. +These two mechanisms are bridged in Scala by a mechanism called +[_eta-expansion_](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#eta-expansion-section) +(also called eta-abstraction), which converts a reference to a method into a function. Intuitively, a method `m` can be passed around by turning it into an object: the function `x => m(x)`. + +In this snippet which assigns a method to a `val`, the compiler will perform _automatic eta-expansion_, as shown in the comment: + +```scala +def m(x: Int, y: String) = ??? +val f = m // becomes: val f = (x: Int, y: String) => m(x, y) +``` + +In Scala 2, a method reference `m` is converted to a function value only if the expected type is a function type, which means the conversion in the example above would not have been triggered, because `val f` does not have a type ascription. To still get eta-expansion, a shortcut `m _` would force the conversion. + +For methods with one or more parameters like in the example above, this restriction has now been dropped. The syntax `m _` is no longer needed and will be deprecated in the future. + +## Automatic eta-expansion and partial application +In the following example `m` can be partially applied to the first two parameters. +Assigning `m` to `f1` will automatically eta-expand. + +```scala +def m(x: Boolean, y: String)(z: Int): List[Int] +val f1 = m +val f2 = m(true, "abc") +``` + +This creates two function values: + +```scala +f1: (Boolean, String) => Int => List[Int] +f2: Int => List[Int] +``` + +## Automatic eta-expansion and implicit parameter lists + +Methods with implicit parameter lists will always get applied to implicit arguments. + +```scala +def foo(x: Int)(implicit p: Double): Float = ??? +implicit val bla: Double = 1.0 + +val bar = foo // val bar: Int => Float = ... +``` + +## Automatic Eta-Expansion and query types + +A method with context parameters can be expanded to a value of a context type by writing the expected context type explicitly. + +```scala +def foo(x: Int)(using p: Double): Float = ??? +val bar: Double ?=> Float = foo(3) +``` + +## Rules + +- If `m` has an argument list with one or more parameters, we always eta-expand +- If `m` is has an empty argument list (i.e. has type `()R`): + 1. If the expected type is of the form `() => T`, we eta expand. + 2. If m is defined by Java, or overrides a Java defined method, we insert `()`. + 3. Otherwise we issue an error of the form: + +Thus, an unapplied method with an empty argument list is only converted to a function when a function type is expected. It is considered best practice to either explicitly apply the method to `()`, or convert it to a function with `() => m()`. + +The method value syntax `m _` is deprecated. + +## Reference + +For more information, see [PR #2701](https://github.com/lampepfl/dotty/pull/2701). diff --git a/docs/_spec/TODOreference/changed-features/eta-expansion.md b/docs/_spec/TODOreference/changed-features/eta-expansion.md new file mode 100644 index 000000000000..c05378135e54 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/eta-expansion.md @@ -0,0 +1,42 @@ +--- +layout: doc-page +title: "Automatic Eta Expansion" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/eta-expansion.html +--- + +The conversion of _methods_ into _functions_ has been improved and happens automatically for methods with one or more parameters. + +```scala +def m(x: Boolean, y: String)(z: Int): List[Int] +val f1 = m +val f2 = m(true, "abc") +``` + +This creates two function values: +```scala +f1: (Boolean, String) => Int => List[Int] +f2: Int => List[Int] +``` + +The syntax `m _` is no longer needed and will be deprecated in the future. + +## Automatic eta-expansion and nullary methods + +Automatic eta expansion does not apply to "nullary" methods that take an empty parameter list. + +```scala +def next(): T +``` + +Given a simple reference to `next` does not auto-convert to a function. +One has to write explicitly `() => next()` to achieve that. +Once again since the `_` is going to be deprecated it's better to write it this way +rather than `next _`. + +The reason for excluding nullary methods from automatic eta expansion +is that Scala implicitly inserts the `()` argument, which would +conflict with eta expansion. Automatic `()` insertion is +[limited](../dropped-features/auto-apply.md) in Scala 3, but the fundamental ambiguity +remains. + +[More details](eta-expansion-spec.md) diff --git a/docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md b/docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md new file mode 100644 index 000000000000..dc19e10c8b8f --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/implicit-conversions-spec.md @@ -0,0 +1,117 @@ +--- +layout: doc-page +title: "Implicit Conversions - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/implicit-conversions-spec.html +--- + +## Implementation + +An implicit conversion, or _view_, from type `S` to type `T` is +defined by either: + +- An `implicit def` which has type `S => T` or `(=> S) => T` +- An implicit value which has type `Conversion[S, T]` + +The standard library defines an abstract class [`Conversion`](https://scala-lang.org/api/3.x/scala/Conversion.html): + +```scala +package scala +@java.lang.FunctionalInterface +abstract class Conversion[-T, +U] extends Function1[T, U]: + def apply(x: T): U +``` + +Function literals are automatically converted to `Conversion` values. + +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 `pt`. In this case, an implicit `v` + which is applicable to `e` and whose result type conforms to `pt` + is searched. The search proceeds as in the case of implicit + parameters, where the implicit scope is the one of `T => 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` + which is applicable to `e` and whose result contains an accessible + member named `m` is searched. 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 an application `e.m(args)` with `e` of type `T`, if the selector + `m` denotes some accessible member(s) of `T`, but none of these + members is applicable to the arguments `args`. In this case, a view + `v` which is applicable to `e` and whose result contains a method + `m` which is applicable to `args` is searched. 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 application + `e.m(args)` is converted to `v(e).m(args)`. + +# Differences with Scala 2 implicit conversions + +In Scala 2, views whose parameters are passed by-value take precedence +over views whose parameters are passed by-name. This is no longer the +case in Scala 3. A type error reporting the ambiguous conversions will +be emitted in cases where this rule would be applied in Scala 2: + +```scala +implicit def conv1(x: Int): String = x.toString +implicit def conv2(x: => Int): String = x.toString + +val x: String = 0 // Compiles in Scala2 (uses `conv1`), + // type error in Scala 3 because of ambiguity. +``` + +In Scala 2, implicit values of a function type would be considered as +potential views. In Scala 3, these implicit value need to have type +`Conversion`: + +```scala +// Scala 2: +def foo(x: Int)(implicit conv: Int => String): String = x + +// Becomes with Scala 3: +def foo(x: Int)(implicit conv: Conversion[Int, String]): String = x + +// Call site is unchanged: +foo(4)(_.toString) + +// Scala 2: +implicit val myConverter: Int => String = _.toString + +// Becomes with Scala 3: +implicit val myConverter: Conversion[Int, String] = _.toString +``` + +Note that implicit conversions are also affected by the [changes to implicit resolution](implicit-resolution.md) between Scala 2 and Scala 3. + +## Motivation for the changes + +The introduction of [`scala.Conversion`](https://scala-lang.org/api/3.x/scala/Conversion.html) +in Scala 3 and the decision to restrict implicit values of this type to be +considered as potential views comes from the desire to remove surprising +behavior from the language: + +```scala +implicit val m: Map[Int, String] = Map(1 -> "abc") + +val x: String = 1 // Scala 2: assigns "abc" to x + // Scala 3: type error +``` + +This snippet contains a type error. The right-hand side of `val x` +does not conform to type `String`. In Scala 2, the compiler will use +`m` as an implicit conversion from `Int` to `String`, whereas Scala 3 +will report a type error, because `Map` isn't an instance of +[`Conversion`](https://scala-lang.org/api/3.x/scala/Conversion.html). + +## Migration path + +Implicit values that are used as views should see their type changed to `Conversion`. + +For the migration of implicit conversions that are affected by the +changes to implicit resolution, refer to the [Changes in Implicit Resolution](implicit-resolution.md) for more information. + +## Reference + +For more information about implicit resolution, see [Changes in Implicit Resolution](implicit-resolution.md). +Other details are available in [PR #2065](https://github.com/lampepfl/dotty/pull/2065). diff --git a/docs/_spec/TODOreference/changed-features/implicit-conversions.md b/docs/_spec/TODOreference/changed-features/implicit-conversions.md new file mode 100644 index 000000000000..eef236f39a07 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/implicit-conversions.md @@ -0,0 +1,65 @@ +--- +layout: doc-page +title: "Implicit Conversions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/implicit-conversions.html +--- + +An _implicit conversion_, also called _view_, is a conversion that +is applied by the compiler in several situations: + +1. When an expression `e` of type `T` is encountered, but the compiler + needs an expression of type `S`. +1. When an expression `e.m` where `e` has type `T` but `T` defines no + member `m` is encountered. + +In those cases, the compiler looks in the implicit scope for a +conversion that can convert an expression of type `T` to an expression +of type `S` (or to a type that defines a member `m` in the second +case). + +This conversion can be either: + +1. An `implicit def` of type `T => S` or `(=> T) => S` +1. An implicit value of type `scala.Conversion[T, S]` + +Defining an implicit conversion will emit a warning unless the import +`scala.language.implicitConversions` is in scope, or the flag +`-language:implicitConversions` is given to the compiler. + +## Examples + +The first example is taken from [`scala.Predef`](https://scala-lang.org/api/3.x/scala/Predef$.html). +Thanks to this implicit conversion, it is possible to pass a +[`scala.Int`](https://scala-lang.org/api/3.x/scala/Int.html) +to a Java method that expects a `java.lang.Integer` + +```scala +import scala.language.implicitConversions +implicit def int2Integer(x: Int): java.lang.Integer = + x.asInstanceOf[java.lang.Integer] +``` + +The second example shows how to use `Conversion` to define an +`Ordering` for an arbitrary type, given existing `Ordering`s for other +types: + +```scala +import scala.language.implicitConversions +implicit def ordT[T, S]( + implicit conv: Conversion[T, S], + ordS: Ordering[S] + ): Ordering[T] = + // `ordS` compares values of type `S`, but we can convert from `T` to `S` + (x: T, y: T) => ordS.compare(x, y) + +class A(val x: Int) // The type for which we want an `Ordering` + +// Convert `A` to a type for which an `Ordering` is available: +implicit val AToInt: Conversion[A, Int] = _.x + +implicitly[Ordering[Int]] // Ok, exists in the standard library +implicitly[Ordering[A]] // Ok, will use the implicit conversion from + // `A` to `Int` and the `Ordering` for `Int`. +``` + +[More details](implicit-conversions-spec.md) diff --git a/docs/_spec/TODOreference/changed-features/implicit-resolution.md b/docs/_spec/TODOreference/changed-features/implicit-resolution.md new file mode 100644 index 000000000000..bf15baa3299c --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/implicit-resolution.md @@ -0,0 +1,169 @@ +--- +layout: doc-page +title: "Changes in Implicit Resolution" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/implicit-resolution.html +--- + +This section describes changes to the implicit resolution that apply both to the new `given`s and to the old-style `implicit`s in Scala 3. +Implicit resolution uses a new algorithm which caches implicit results +more aggressively for performance. There are also some changes that +affect implicits on the language level. + +**1.** Types of implicit values and result types of implicit methods +must be explicitly declared. Excepted are only values in local blocks +where the type may still be inferred: +```scala + class C { + + val ctx: Context = ... // ok + + /*!*/ implicit val x = ... // error: type must be given explicitly + + /*!*/ implicit def y = ... // error: type must be given explicitly + } + val y = { + implicit val ctx = this.ctx // ok + ... + } +``` +**2.** Nesting is now taken into account for selecting an implicit. Consider for instance the following scenario: +```scala + def f(implicit i: C) = { + def g(implicit j: C) = { + implicitly[C] + } + } +``` +This will now resolve the `implicitly` call to `j`, because `j` is nested +more deeply than `i`. Previously, this would have resulted in an +ambiguity error. The previous possibility of an implicit search failure +due to _shadowing_ (where an implicit is hidden by a nested definition) +no longer applies. + +**3.** Package prefixes no longer contribute to the implicit search scope of a type. Example: +```scala + package p + + given a: A = A() + + object o: + given b: B = B() + type C +``` +Both `a` and `b` are visible as implicits at the point of the definition +of `type C`. However, a reference to `p.o.C` outside of package `p` will +have only `b` in its implicit search scope but not `a`. + +In more detail, here are the rules for what constitutes the implicit scope of +a type: + +**Definition:** A reference is an _anchor_ if it refers to an object, a class, a trait, an abstract type, an opaque type alias, or a match type alias. References to packages and package objects are anchors only under `-source:3.0-migration`. +Opaque type aliases count as anchors only outside the scope where their alias is visible. + +**Definition:** The _anchors_ of a type _T_ is a set of references defined as follows: + + 1. If _T_ is a reference to an anchor, _T_ itself plus, if _T_ is of the form _P#A_, the anchors of _P_. + 1. If _T_ is an alias of _U_, the anchors of _U_. + 1. If _T_ is a reference to a type parameter, the union of the anchors of both of its bounds. + 1. If _T_ is a singleton reference, the anchors of its underlying type, plus, + if _T_ is of the form _(P#x).type_, the anchors of _P_. + 1. If _T_ is the this-type _o.this_ of a static object _o_, the anchors of a term reference _o.type_ to that object. + 1. If _T_ is some other type, the union of the anchors of each constituent type of _T_. + + **Definition:** The _implicit scope_ of a type _T_ is the smallest set _S_ of term references such that + + 1. If _T_ is a reference to a class, _S_ includes a reference to the companion object + of the class, if it exists, as well as the implicit scopes of all of _T_'s parent classes. + 1. If _T_ is a reference to an object, _S_ includes _T_ itself as well as + the implicit scopes of all of _T_'s parent classes. + 1. If _T_ is a reference to an opaque type alias named _A_, _S_ includes + a reference to an object _A_ defined in the same scope as the type, if it exists, + as well as the implicit scope of _T_'s underlying type or bounds. + 1. If _T_ is a reference to an abstract type or match type alias + named _A_, _S_ includes a reference to an object _A_ defined in the same scope as the type, if it exists, as well as the implicit scopes of _T_'s given bounds. + 1. If _T_ is a reference to an anchor of the form _p.A_ then _S_ also includes + all term references on the path _p_. + 1. If _T_ is some other type, _S_ includes the implicit scopes of all anchors of _T_. + + +**4.** The treatment of ambiguity errors has changed. If an ambiguity is encountered in some recursive step of an implicit search, the ambiguity is propagated to the caller. + +Example: Say you have the following definitions: +```scala + class A + class B extends C + class C + implicit def a1: A + implicit def a2: A + implicit def b(implicit a: A): B + implicit def c: C +``` +and the query `implicitly[C]`. + +This query would now be classified as ambiguous. This makes sense, after all +there are two possible solutions, `b(a1)` and `b(a2)`, neither of which is better +than the other and both of which are better than the third solution, `c`. +By contrast, Scala 2 would have rejected the search for `A` as +ambiguous, and subsequently have classified the query `b(implicitly[A])` as a normal fail, +which means that the alternative `c` would be chosen as solution! + +Scala 2's somewhat puzzling behavior with respect to ambiguity has been exploited to implement +the analogue of a "negated" search in implicit resolution, where a query `Q1` fails if some +other query `Q2` succeeds and `Q1` succeeds if `Q2` fails. With the new cleaned up behavior +these techniques no longer work. But there is now a new special type [`scala.util.NotGiven`](https://scala-lang.org/api/3.x/scala/util/NotGiven.html) +which implements negation directly. For any query type `Q`, `NotGiven[Q]` succeeds if and only if +the implicit search for `Q` fails. + +**5.** The treatment of divergence errors has also changed. A divergent implicit is treated as a normal failure, after which alternatives are still tried. This also makes sense: Encountering a divergent implicit means that we assume that no finite solution can be found on the corresponding path, but another path can still be tried. By contrast, +most (but not all) divergence errors in Scala 2 would terminate the implicit search as a whole. + +**6.** Scala 2 gives a lower level of priority to implicit conversions with call-by-name parameters relative to implicit conversions with call-by-value parameters. Scala 3 drops this distinction. So the following code snippet would be ambiguous in Scala 3: + +```scala + implicit def conv1(x: Int): A = new A(x) + implicit def conv2(x: => Int): A = new A(x) + def buzz(y: A) = ??? + buzz(1) // error: ambiguous +``` +**7.** The rule for picking a _most specific_ alternative among a set of overloaded or implicit alternatives is refined to take context parameters into account. All else being equal, an alternative that takes some context parameters is taken to be less specific than an alternative that takes none. If both alternatives take context parameters, we try to choose between them as if they were methods with regular parameters. The following paragraph in the [SLS §6.26.3](https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#overloading-resolution) is affected by this change: + +_Original version:_ + +> An alternative A is _more specific_ than an alternative B if the relative weight of A over B is greater than the relative weight of B over A. + +_Modified version:_ + +An alternative A is _more specific_ than an alternative B if + + - the relative weight of A over B is greater than the relative weight of B over A, or + - the relative weights are the same, and A takes no implicit parameters but B does, or + - the relative weights are the same, both A and B take implicit parameters, and A is more specific than B if all implicit parameters in either alternative are replaced by regular parameters. + +**8.** The previous disambiguation of implicits based on inheritance depth is refined to make it transitive. Transitivity is important to guarantee that search outcomes are compilation-order independent. Here's a scenario where the previous rules violated transitivity: +```scala + class A extends B + object A { given a ... } + class B + object B extends C { given b ... } + class C { given c } +``` + Here `a` is more specific than `b` since the companion class `A` is a subclass of the companion class `B`. Also, `b` is more specific than `c` + since `object B` extends class `C`. But `a` is not more specific than `c`. This means if `a, b, c` are all applicable implicits, it makes + a difference in what order they are compared. If we compare `b` and `c` + first, we keep `b` and drop `c`. Then, comparing `a` with `b` we keep `a`. But if we compare `a` with `c` first, we fail with an ambiguity error. + +The new rules are as follows: An implicit `a` defined in `A` is more specific than an implicit `b` defined in `B` if + + - `A` extends `B`, or + - `A` is an object and the companion class of `A` extends `B`, or + - `A` and `B` are objects, + `B` does not inherit any implicit members from base classes (*), + and the companion class of `A` extends the companion class of `B`. + +Condition (*) is new. It is necessary to ensure that the defined relation is transitive. + + + + + +[//]: # todo: expand with precise rules diff --git a/docs/_spec/TODOreference/changed-features/imports.md b/docs/_spec/TODOreference/changed-features/imports.md new file mode 100644 index 000000000000..2058ef08b7db --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/imports.md @@ -0,0 +1,60 @@ +--- +layout: doc-page +title: "Imports" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/imports.html +--- + +The syntax of wildcard and renaming imports (and exports) has changed. + +## Wildcard Imports + +Wildcard imports are now expressed with `*` instead of underscore. Example: +```scala +import scala.annotation.* // imports everything in the annotation package +``` + +If you want to import a member named `*` specifically, you can use backticks around it. + +```scala +object A: + def * = ... + def min = ... + +object B: + import A.`*` // imports just `*` + +object C: + import A.* // imports everything in A +``` + +## Renaming Imports + +To rename or exclude an import, we now use `as` instead of `=>`. A single renaming import no longer needs to be enclosed in braces. Examples: + +```scala +import A.{min as minimum, `*` as multiply} +import Predef.{augmentString as _, *} // imports everything except augmentString +import scala.annotation as ann +import java as j +``` + +## Migration + +To support cross-building, Scala 3.0 supports the old import syntax with `_` for wildcards and `=>` for renamings in addition to the new one. The old syntax +will be dropped in a future versions. Automatic rewritings from old to new syntax +are offered under settings `-source 3.1-migration -rewrite`. + +## Syntax + +``` +Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} +ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec + | SimpleRef `as` id +ImportSpec ::= NamedSelector + | WildcardSelector + | ‘{’ ImportSelectors) ‘}’ +NamedSelector ::= id [‘as’ (id | ‘_’)] +WildCardSelector ::= ‘*' | ‘given’ [InfixType] +ImportSelectors ::= NamedSelector [‘,’ ImportSelectors] + | WildCardSelector {‘,’ WildCardSelector} +``` diff --git a/docs/_spec/TODOreference/changed-features/interpolation-escapes.md b/docs/_spec/TODOreference/changed-features/interpolation-escapes.md new file mode 100644 index 000000000000..594e7671c5ab --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/interpolation-escapes.md @@ -0,0 +1,14 @@ +--- +layout: doc-page +title: "Escapes in interpolations" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/interpolation-escapes.html +--- + +In Scala 2 there is no straightforward way to represent a single quote character `"` in a single quoted interpolation. A `\` character can't be used for that because interpolators themselves decide how to handle escaping, so the parser doesn't know whether the `"` character should be escaped or used as a terminator. + +In Scala 3, we can use the `$` meta character of interpolations to escape a `"` character. Example: + +```scala + val inventor = "Thomas Edison" + val interpolation = s"as $inventor said: $"The three great essentials to achieve anything worth while are: Hard work, Stick-to-itiveness, and Common sense.$"" +``` diff --git a/docs/_spec/TODOreference/changed-features/lazy-vals-init.md b/docs/_spec/TODOreference/changed-features/lazy-vals-init.md new file mode 100644 index 000000000000..131ac6ad7bb2 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/lazy-vals-init.md @@ -0,0 +1,80 @@ +--- +layout: doc-page +title: Lazy Vals Initialization +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/lazy-vals-init.html +--- + +Scala 3 implements [Version 6](https://docs.scala-lang.org/sips/improved-lazy-val-initialization.html#version-6---no-synchronization-on-this-and-concurrent-initialization-of-fields) +of the [SIP-20] improved lazy vals initialization proposal. + +## Motivation + +The newly proposed lazy val initialization mechanism aims to eliminate the acquisition of resources +during the execution of the lazy val initializer block, thus reducing the possibility of a deadlock. +The concrete deadlock scenarios that the new lazy val initialization scheme eliminates are +summarized in the [SIP-20] document. + +## Implementation + +Given a lazy field of the form: + +```scala +class Foo { + lazy val bar = +} +``` + +The Scala 3 compiler will generate code equivalent to: + +```scala +class Foo { + import scala.runtime.LazyVals + var value_0: Int = _ + var bitmap: Long = 0L + val bitmap_offset: Long = LazyVals.getOffset(classOf[LazyCell], "bitmap") + + def bar(): Int = { + while (true) { + val flag = LazyVals.get(this, bitmap_offset) + val state = LazyVals.STATE(flag, ) + + if (state == ) { + return value_0 + } else if (state == ) { + if (LazyVals.CAS(this, bitmap_offset, flag, , )) { + try { + val result = + value_0 = result + LazyVals.setFlag(this, bitmap_offset, , ) + return result + } + catch { + case ex => + LazyVals.setFlag(this, bitmap_offset, , ) + throw ex + } + } + } else /* if (state == || state == ) */ { + LazyVals.wait4Notification(this, bitmap_offset, flag, ) + } + } + } +} +``` + +The state of the lazy val `` is represented with 4 values: 0, 1, 2 and 3. The state 0 +represents a non-initialized lazy val. The state 1 represents a lazy val that is currently being +initialized by some thread. The state 2 denotes that there are concurrent readers of the lazy val. +The state 3 represents a lazy val that has been initialized. `` is the id of the lazy +val. This id grows with the number of volatile lazy vals defined in the class. + +## Note on recursive lazy vals + +Ideally recursive lazy vals should be flagged as an error. The current behavior for +recursive lazy vals is undefined (initialization may result in a deadlock). + +## Reference + +* [SIP-20] + +[SIP-20]: https://docs.scala-lang.org/sips/improved-lazy-val-initialization.html diff --git a/docs/_spec/TODOreference/changed-features/main-functions.md b/docs/_spec/TODOreference/changed-features/main-functions.md new file mode 100644 index 000000000000..4460300d003e --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/main-functions.md @@ -0,0 +1,87 @@ +--- +layout: doc-page +title: "Main Methods" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/main-functions.html +--- + +Scala 3 offers a new way to define programs that can be invoked from the command line: +A [`@main`](https://scala-lang.org/api/3.x/scala/main.html) annotation on a method turns this method into an executable program. +Example: + +```scala +@main def happyBirthday(age: Int, name: String, others: String*) = + val suffix = + age % 100 match + case 11 | 12 | 13 => "th" + case _ => + age % 10 match + case 1 => "st" + case 2 => "nd" + case 3 => "rd" + case _ => "th" + val bldr = new StringBuilder(s"Happy $age$suffix birthday, $name") + for other <- others do bldr.append(" and ").append(other) + bldr.toString +``` + +This would generate a main program `happyBirthday` that could be called like this + +``` +> scala happyBirthday 23 Lisa Peter +Happy 23rd birthday, Lisa and Peter +``` + +A [`@main`](https://scala-lang.org/api/3.x/scala/main.html) annotated method can be written either at the top-level or in a statically accessible object. The name of the program is in each case the name of the method, without any object prefixes. The [`@main`](https://scala-lang.org/api/3.x/scala/main.html) method can have an arbitrary number of parameters. +For each parameter type there must be an instance of the [`scala.util.CommandLineParser.FromString[T]`](https://scala-lang.org/api/3.x/scala/util/CommandLineParser$$FromString.html) type class that is used to convert an argument string to the required parameter type `T`. +The parameter list of a main method can end in a repeated parameter that then takes all remaining arguments given on the command line. + +The program implemented from a [`@main`](https://scala-lang.org/api/3.x/scala/main.html) method checks that there are enough arguments on +the command line to fill in all parameters, and that argument strings are convertible to +the required types. If a check fails, the program is terminated with an error message. + +Examples: + +``` +> scala happyBirthday 22 +Illegal command line after first argument: more arguments expected + +> scala happyBirthday sixty Fred +Illegal command line: java.lang.NumberFormatException: For input string: "sixty" +``` + +The Scala compiler generates a program from a [`@main`](https://scala-lang.org/api/3.x/scala/main.html) method `f` as follows: + + - It creates a class named `f` in the package where the [`@main`](https://scala-lang.org/api/3.x/scala/main.html) method was found + - The class has a static method `main` with the usual signature. It takes an `Array[String]` + as argument and returns [`Unit`](https://scala-lang.org/api/3.x/scala/Unit.html). + - The generated `main` method calls method `f` with arguments converted using + methods in the [`scala.util.CommandLineParser`](https://scala-lang.org/api/3.x/scala/util/CommandLineParser$.html) object. + +For instance, the `happyBirthDay` method above would generate additional code equivalent to the following class: + +```scala +final class happyBirthday: + import scala.util.CommandLineParser as CLP + def main(args: Array[String]): Unit = + try + happyBirthday( + CLP.parseArgument[Int](args, 0), + CLP.parseArgument[String](args, 1), + CLP.parseRemainingArguments[String](args, 2)) + catch + case error: CLP.ParseError => CLP.showError(error) +``` + +**Note**: The `` modifier above expresses that the `main` method is generated +as a static method of class `happyBirthDay`. It is not available for user programs in Scala. Regular "static" members are generated in Scala using objects instead. + +[`@main`](https://scala-lang.org/api/3.x/scala/main.html) methods are the recommended scheme to generate programs that can be invoked from the command line in Scala 3. They replace the previous scheme to write program as objects with a special `App` parent class. In Scala 2, `happyBirthday` could be written also like this: + +```scala +object happyBirthday extends App: + // needs by-hand parsing of arguments vector + ... +``` + +The previous functionality of [`App`](https://www.scala-lang.org/api/3.x/scala/App.html), which relied on the "magic" [`DelayedInit`](../dropped-features/delayed-init.md) trait, is no longer available. [`App`](https://scala-lang.org/api/3.x/scala/App.html) still exists in limited form for now, but it does not support command line arguments and will be deprecated in the future. If programs need to cross-build +between Scala 2 and Scala 3, it is recommended to use an explicit `main` method with an `Array[String]` argument instead. diff --git a/docs/_spec/TODOreference/changed-features/match-syntax.md b/docs/_spec/TODOreference/changed-features/match-syntax.md new file mode 100644 index 000000000000..dba50e9beb6a --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/match-syntax.md @@ -0,0 +1,56 @@ +--- +layout: doc-page +title: "Match Expressions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/match-syntax.html +--- + +The syntactical precedence of match expressions has been changed. +`match` is still a keyword, but it is used like an alphabetical operator. This has several consequences: + + 1. `match` expressions can be chained: + + ```scala + xs match { + case Nil => "empty" + case _ => "nonempty" + } match { + case "empty" => 0 + case "nonempty" => 1 + } + ``` + + (or, dropping the optional braces) + + ```scala + xs match + case Nil => "empty" + case _ => "nonempty" + match + case "empty" => 0 + case "nonempty" => 1 + ``` + + 2. `match` may follow a period: + + ```scala + if xs.match + case Nil => false + case _ => true + then "nonempty" + else "empty" + ``` + + 3. The scrutinee of a match expression must be an `InfixExpr`. Previously the scrutinee could be followed by a type ascription `: T`, but this is no longer supported. So `x : T match { ... }` now has to be + written `(x: T) match { ... }`. + +## Syntax + +The new syntax of match expressions is as follows. + +``` +InfixExpr ::= ... + | InfixExpr MatchClause +SimpleExpr ::= ... + | SimpleExpr ‘.’ MatchClause +MatchClause ::= ‘match’ ‘{’ CaseClauses ‘}’ +``` diff --git a/docs/_spec/TODOreference/changed-features/numeric-literals.md b/docs/_spec/TODOreference/changed-features/numeric-literals.md new file mode 100644 index 000000000000..bba837dbf67d --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/numeric-literals.md @@ -0,0 +1,7 @@ +--- +layout: doc-page +title: "Numeric Literals" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/numeric-literals.html +--- + +[Document was moved](../experimental/numeric-literals.md) diff --git a/docs/_spec/TODOreference/changed-features/operators.md b/docs/_spec/TODOreference/changed-features/operators.md new file mode 100644 index 000000000000..0cf25d77bc11 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/operators.md @@ -0,0 +1,173 @@ +--- +layout: doc-page +title: "Rules for Operators" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/operators.html +--- + +The rules for infix operators have changed in some parts: + +First, an alphanumeric method can be used as an infix operator only if its definition carries an `infix` modifier. + +Second, it is recommended (but not enforced) to augment definitions of symbolic operators +with [`@targetName` annotations](../other-new-features/targetName.md). + +Finally, a syntax change allows infix operators to be written on the left in a multi-line expression. + +## The `infix` Modifier + +An `infix` modifier on a method definition allows using the method as an infix operation. Example: + +```scala +import scala.annotation.targetName + +trait MultiSet[T]: + + infix def union(other: MultiSet[T]): MultiSet[T] + + def difference(other: MultiSet[T]): MultiSet[T] + + @targetName("intersection") + def *(other: MultiSet[T]): MultiSet[T] + +end MultiSet + +val s1, s2: MultiSet[Int] + +s1 union s2 // OK +s1 `union` s2 // also OK but unusual +s1.union(s2) // also OK + +s1.difference(s2) // OK +s1 `difference` s2 // OK +s1 difference s2 // gives a deprecation warning + +s1 * s2 // OK +s1 `*` s2 // also OK, but unusual +s1.*(s2) // also OK, but unusual +``` + +Infix operations involving alphanumeric operators are deprecated, unless +one of the following conditions holds: + + - the operator definition carries an `infix` modifier, or + - the operator was compiled with Scala 2, or + - the operator is followed by an opening brace. + +An alphanumeric operator is an operator consisting entirely of letters, digits, the `$` and `_` characters, or +any Unicode character `c` for which `java.lang.Character.isIdentifierPart(c)` returns `true`. + +Infix operations involving symbolic operators are always allowed, so `infix` is redundant for methods with symbolic names. + +The `infix` modifier can also be given to a type: + +```scala +infix type or[X, Y] +val x: String or Int = ... +``` + +### Motivation + +The purpose of the `infix` modifier is to achieve consistency across a code base in how a method or type is applied. The idea is that the author of a method decides whether that method should be applied as an infix operator or in a regular application. Use sites then implement that decision consistently. + +### Details + + 1. `infix` is a soft modifier. It is treated as a normal identifier except when in modifier position. + + 2. If a method overrides another, their infix annotations must agree. Either both are annotated with `infix`, or none of them are. + + 3. `infix` modifiers can be given to method definitions. The first non-receiver parameter list of an `infix` method must define exactly one parameter. Examples: + + ```scala + infix def op1(x: S): R // ok + infix def op2[T](x: T)(y: S): R // ok + infix def op3[T](x: T, y: S): R // error: two parameters + + extension (x: A) + infix def op4(y: B): R // ok + infix def op5(y1: B, y2: B): R // error: two parameters + ``` + + 4. `infix` modifiers can also be given to type, trait or class definitions that have exactly two type parameters. An infix type like + + ```scala + infix type op[X, Y] + ``` + + can be applied using infix syntax, i.e. `A op B`. + + 5. To smooth migration to Scala 3.0, alphanumeric operators will only be deprecated from Scala 3.1 onwards, +or if the `-source future` option is given in Dotty/Scala 3. + +## The `@targetName` Annotation + +It is recommended that definitions of symbolic operators carry a [`@targetName` annotation](../other-new-features/targetName.md) that provides an encoding of the operator with an alphanumeric name. This has several benefits: + + - It helps interoperability between Scala and other languages. One can call + a Scala-defined symbolic operator from another language using its target name, + which avoids having to remember the low-level encoding of the symbolic name. + - It helps legibility of stacktraces and other runtime diagnostics, where the + user-defined alphanumeric name will be shown instead of the low-level encoding. + - It serves as a documentation tool by providing an alternative regular name + as an alias of a symbolic operator. This makes the definition also easier + to find in a search. + +## Syntax Change + +Infix operators can now appear at the start of lines in a multi-line expression. Examples: + +```scala +val str = "hello" + ++ " world" + ++ "!" + +def condition = + x > 0 + || + xs.exists(_ > 0) + || xs.isEmpty +``` + +Previously, those expressions would have been rejected, since the compiler's semicolon inference +would have treated the continuations `++ " world"` or `|| xs.isEmpty` as separate statements. + +To make this syntax work, the rules are modified to not infer semicolons in front of leading infix operators. +A _leading infix operator_ is + - a symbolic identifier such as `+`, or `approx_==`, or an identifier in backticks that + - starts a new line, and + - is not following a blank line, and + - is followed by at least one whitespace character and a token that can start an expression. + - Furthermore, if the operator appears on its own line, the next line must have at least + the same indentation width as the operator. + +Example: + +```scala + freezing + | boiling +``` + +This is recognized as a single infix operation. Compare with: + +```scala + freezing + !boiling +``` + +This is seen as two statements, `freezing` and `!boiling`. The difference is that only the operator in the first example +is followed by a space. + +Another example: + +```scala + println("hello") + ??? + ??? match { case 0 => 1 } +``` + +This code is recognized as three different statements. `???` is syntactically a symbolic identifier, but +neither of its occurrences is followed by a space and a token that can start an expression. + +## Unary operators + +A unary operator must not have explicit parameter lists even if they are empty. +A unary operator is a method named "unary_`op`" where `op` is one of `+`, `-`, `!`, or `~`. diff --git a/docs/_spec/TODOreference/changed-features/overload-resolution.md b/docs/_spec/TODOreference/changed-features/overload-resolution.md new file mode 100644 index 000000000000..bd7782ded520 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/overload-resolution.md @@ -0,0 +1,102 @@ +--- +layout: doc-page +title: "Changes in Overload Resolution" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/overload-resolution.html +--- + +Overload resolution in Scala 3 improves on Scala 2 in three ways. +First, it takes all argument lists into account instead of +just the first argument list. +Second, it can infer parameter types of function values even if they +are in the first argument list. +Third, default arguments are no longer relevant for prioritization. + +## Looking Beyond the First Argument List + +Overloading resolution now can take argument lists into account when +choosing among a set of overloaded alternatives. +For example, the following code compiles in Scala 3, while it results in an +ambiguous overload error in Scala 2: + +```scala +def f(x: Int)(y: String): Int = 0 +def f(x: Int)(y: Int): Int = 0 + +f(3)("") // ok +``` + +The following code compiles as well: + +```scala +def g(x: Int)(y: Int)(z: Int): Int = 0 +def g(x: Int)(y: Int)(z: String): Int = 0 + +g(2)(3)(4) // ok +g(2)(3)("") // ok +``` + +To make this work, the rules for overloading resolution in [SLS §6.26.3](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#overloading-resolution) are augmented +as follows: + +> In a situation where a function is applied to more than one argument list, if overloading +resolution yields several competing alternatives when `n >= 1` parameter lists are taken +into account, then resolution re-tried using `n + 1` argument lists. + +This change is motivated by the new language feature +[extension methods](../contextual/extension-methods.md), where emerges the need to do +overload resolution based on additional argument blocks. + +## Parameter Types of Function Values + +The handling of function values with missing parameter types has been improved. We can now +pass such values in the first argument list of an overloaded application, provided +that the remaining parameters suffice for picking a variant of the overloaded function. +For example, the following code compiles in Scala 3, while it results in a +missing parameter type error in Scala2: + +```scala +def f(x: Int, f2: Int => Int) = f2(x) +def f(x: String, f2: String => String) = f2(x) +f("a", _.toUpperCase) +f(2, _ * 2) +``` + +To make this work, the rules for overloading resolution in [SLS §6.26.3](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#overloading-resolution) are modified +as follows: + +Replace the sentence + +> Otherwise, let `S1,…,Sm` be the vector of types obtained by typing each argument with an undefined expected type. + +with the following paragraph: + +> Otherwise, let `S1,…,Sm` be the vector of known types of all argument types, where the _known type_ of an argument `E` +is determined as followed: + + - If `E` is a function value `(p_1, ..., p_n) => B` that misses some parameter types, the known type + of `E` is `(S_1, ..., S_n) => ?`, where each `S_i` is the type of parameter `p_i` if it is given, or `?` + otherwise. Here `?` stands for a _wildcard type_ that is compatible with every other type. + - Otherwise the known type of `E` is the result of typing `E` with an undefined expected type. + +A pattern matching closure + +```scala +{ case P1 => B1 ... case P_n => B_n } +```` + +is treated as if it was expanded to the function value + +```scala +x => x match { case P1 => B1 ... case P_n => B_n } +``` + +and is therefore also approximated with a `? => ?` type. + +## Default Arguments Are No longer Relevant for Prioritization + +In Scala 2 if among several applicative alternatives one alternative had default arguments, that alternative was dropped from consideration. This has the unfortunate +side effect that adding a default to a parameter of a method can render this method +invisible in overloaded calls. + +Scala 3 drops this distinction. Methods with default parameters are not treated +to have lower priority than other methods. diff --git a/docs/_spec/TODOreference/changed-features/pattern-bindings.md b/docs/_spec/TODOreference/changed-features/pattern-bindings.md new file mode 100644 index 000000000000..2de338fc1dde --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/pattern-bindings.md @@ -0,0 +1,59 @@ +--- +layout: doc-page +title: "Pattern Bindings" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html +--- + +In Scala 2, pattern bindings in `val` definitions and `for` expressions are +loosely typed. Potentially failing matches are still accepted at compile-time, +but may influence the program's runtime behavior. +From Scala 3.2 on, type checking rules will be tightened so that warnings are reported at compile-time instead. + +## Bindings in Pattern Definitions + +```scala +val xs: List[Any] = List(1, 2, 3) +val (x: String) :: _ = xs // error: pattern's type String is more specialized + // than the right-hand side expression's type Any +``` +This code gives a compile-time warning in Scala 3.2 (and also earlier Scala 3.x under the `-source future` setting) whereas it will fail at runtime with a `ClassCastException` in Scala 2. In Scala 3.2, a pattern binding is only allowed if the pattern is _irrefutable_, that is, if the right-hand side's type conforms to the pattern's type. For instance, the following is OK: +```scala +val pair = (1, true) +val (x, y) = pair +``` +Sometimes one wants to decompose data anyway, even though the pattern is refutable. For instance, if at some point one knows that a list `elems` is non-empty one might want to decompose it like this: +```scala +val first :: rest = elems // error +``` +This works in Scala 2. In fact it is a typical use case for Scala 2's rules. But in Scala 3.2 it will give a warning. One can avoid the warning by marking the right-hand side with an [`@unchecked`](https://scala-lang.org/api/3.x/scala/unchecked.html) annotation: +```scala +val first :: rest = elems: @unchecked // OK +``` +This will make the compiler accept the pattern binding. It might give an error at runtime instead, if the underlying assumption that `elems` can never be empty is wrong. + +## Pattern Bindings in `for` Expressions + +Analogous changes apply to patterns in `for` expressions. For instance: + +```scala +val elems: List[Any] = List((1, 2), "hello", (3, 4)) +for (x, y) <- elems yield (y, x) // error: pattern's type (Any, Any) is more specialized + // than the right-hand side expression's type Any +``` +This code gives a compile-time warning in Scala 3.2 whereas in Scala 2 the list `elems` +is filtered to retain only the elements of tuple type that match the pattern `(x, y)`. +The filtering functionality can be obtained in Scala 3 by prefixing the pattern with `case`: +```scala +for case (x, y) <- elems yield (y, x) // returns List((2, 1), (4, 3)) +``` + +## Syntax Changes + +Generators in for expressions may be prefixed with `case`. +``` +Generator ::= [‘case’] Pattern1 ‘<-’ Expr +``` + +## Migration + +The new syntax is supported in Scala 3.0. However, to enable smooth cross compilation between Scala 2 and Scala 3, the changed behavior and additional type checks are only enabled under the `-source future` setting. They will be enabled by default in version 3.2 of the language. diff --git a/docs/_spec/TODOreference/changed-features/pattern-matching.md b/docs/_spec/TODOreference/changed-features/pattern-matching.md new file mode 100644 index 000000000000..30ae5d9dc104 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/pattern-matching.md @@ -0,0 +1,243 @@ +--- +layout: doc-page +title: "Option-less pattern matching" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/pattern-matching.html +--- + +The implementation of pattern matching in Scala 3 was greatly simplified compared to Scala 2. From a user perspective, this means that Scala 3 generated patterns are a _lot_ easier to debug, as variables all show up in debug modes and positions are correctly preserved. + +Scala 3 supports a superset of Scala 2 [extractors](https://www.scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#extractor-patterns). + +## Extractors + +Extractors are objects that expose a method `unapply` or `unapplySeq`: + +```scala +def unapply[A](x: T)(implicit x: B): U +def unapplySeq[A](x: T)(implicit x: B): U +``` + +Extractors that expose the method `unapply` are called fixed-arity extractors, which +work with patterns of fixed arity. Extractors that expose the method `unapplySeq` are +called variadic extractors, which enables variadic patterns. + +### Fixed-Arity Extractors + +Fixed-arity extractors expose the following signature: + +```scala +def unapply[A](x: T)(implicit x: B): U +``` + +The type `U` conforms to one of the following matches: + +- Boolean match +- Product match + +Or `U` conforms to the type `R`: + +```scala +type R = { + def isEmpty: Boolean + def get: S +} +``` + +and `S` conforms to one of the following matches: + +- single match +- name-based match + +The former form of `unapply` has higher precedence, and _single match_ has higher +precedence over _name-based match_. + +A usage of a fixed-arity extractor is irrefutable if one of the following condition holds: + +- `U = true` +- the extractor is used as a product match +- `U = Some[T]` (for Scala 2 compatibility) +- `U <: R` and `U <: { def isEmpty: false }` + +### Variadic Extractors + +Variadic extractors expose the following signature: + +```scala +def unapplySeq[A](x: T)(implicit x: B): U +``` + +The type `U` conforms to one of the following matches: + +- sequence match +- product-sequence match + +Or `U` conforms to the type `R`: + +```scala +type R = { + def isEmpty: Boolean + def get: S +} +``` + +and `S` conforms to one of the two matches above. + +The former form of `unapplySeq` has higher priority, and _sequence match_ has higher +precedence over _product-sequence match_. + +A usage of a variadic extractor is irrefutable if one of the following conditions holds: + +- the extractor is used directly as a sequence match or product-sequence match +- `U = Some[T]` (for Scala 2 compatibility) +- `U <: R` and `U <: { def isEmpty: false }` + +## Boolean Match + +- `U =:= Boolean` +- Pattern-matching on exactly `0` patterns + +For example: + + + +```scala +object Even: + def unapply(s: String): Boolean = s.size % 2 == 0 + +"even" match + case s @ Even() => println(s"$s has an even number of characters") + case s => println(s"$s has an odd number of characters") + +// even has an even number of characters +``` + +## Product Match + +- `U <: Product` +- `N > 0` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1` ... `_N: PN` members in `U` +- Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN` + +For example: + + + +```scala +class FirstChars(s: String) extends Product: + def _1 = s.charAt(0) + def _2 = s.charAt(1) + + // Not used by pattern matching: Product is only used as a marker trait. + def canEqual(that: Any): Boolean = ??? + def productArity: Int = ??? + def productElement(n: Int): Any = ??? + +object FirstChars: + def unapply(s: String): FirstChars = new FirstChars(s) + +"Hi!" match + case FirstChars(char1, char2) => + println(s"First: $char1; Second: $char2") + +// First: H; Second: i +``` + +## Single Match + +- If there is exactly `1` pattern, pattern-matching on `1` pattern with type `U` + + + +```scala +class Nat(val x: Int): + def get: Int = x + def isEmpty = x < 0 + +object Nat: + def unapply(x: Int): Nat = new Nat(x) + +5 match + case Nat(n) => println(s"$n is a natural number") + case _ => () + +// 5 is a natural number +``` + +## Name-based Match + +- `N > 1` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1 ... _N: PN` members in `U` +- Pattern-matching on exactly `N` patterns with types `P1, P2, ..., PN` + +```scala +object ProdEmpty: + def _1: Int = ??? + def _2: String = ??? + def isEmpty = true + def unapply(s: String): this.type = this + def get = this + +"" match + case ProdEmpty(_, _) => ??? + case _ => () +``` + +## Sequence Match + +- `U <: X`, `T2` and `T3` conform to `T1` + +```scala +type X = { + def lengthCompare(len: Int): Int // or, `def length: Int` + def apply(i: Int): T1 + def drop(n: Int): scala.Seq[T2] + def toSeq: scala.Seq[T3] +} +``` + +- Pattern-matching on _exactly_ `N` simple patterns with types `T1, T1, ..., T1`, where `N` is the runtime size of the sequence, or +- Pattern-matching on `>= N` simple patterns and _a vararg pattern_ (e.g., `xs: _*`) with types `T1, T1, ..., T1, Seq[T1]`, where `N` is the minimum size of the sequence. + + + +```scala +object CharList: + def unapplySeq(s: String): Option[Seq[Char]] = Some(s.toList) + +"example" match + case CharList(c1, c2, c3, c4, _, _, _) => + println(s"$c1,$c2,$c3,$c4") + case _ => + println("Expected *exactly* 7 characters!") + +// e,x,a,m +``` + +## Product-Sequence Match + +- `U <: Product` +- `N > 0` is the maximum number of consecutive (parameterless `def` or `val`) `_1: P1` ... `_N: PN` members in `U` +- `PN` conforms to the signature `X` defined in Seq Pattern +- Pattern-matching on exactly `>= N` patterns, the first `N - 1` patterns have types `P1, P2, ... P(N-1)`, + the type of the remaining patterns are determined as in Seq Pattern. + +```scala +class Foo(val name: String, val children: Int*) +object Foo: + def unapplySeq(f: Foo): Option[(String, Seq[Int])] = + Some((f.name, f.children)) + +def foo(f: Foo) = f match + case Foo(name, x, y, ns*) => ">= two children." + case Foo(name, ns*) => => "< two children." +``` + +There are plans for further simplification, in particular to factor out _product match_ +and _name-based match_ into a single type of extractor. + +## Type testing + +Abstract type testing with `ClassTag` is replaced with `TypeTest` or the alias `Typeable`. + +- pattern `_: X` for an abstract type requires a `TypeTest` in scope +- pattern `x @ X()` for an unapply that takes an abstract type requires a `TypeTest` in scope + +[More details on `TypeTest`](../other-new-features/type-test.md) diff --git a/docs/_spec/TODOreference/changed-features/structural-types-spec.md b/docs/_spec/TODOreference/changed-features/structural-types-spec.md new file mode 100644 index 000000000000..d456932649fb --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/structural-types-spec.md @@ -0,0 +1,153 @@ +--- +layout: doc-page +title: "Programmatic Structural Types - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/structural-types-spec.html +--- + +## Syntax + +``` +SimpleType ::= ... | Refinement +Refinement ::= ‘{’ RefineStatSeq ‘}’ +RefineStatSeq ::= RefineStat {semi RefineStat} +RefineStat ::= ‘val’ VarDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl +``` + +## Implementation of Structural Types + +The standard library defines a universal marker trait +[`scala.Selectable`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/Selectable.scala): + +```scala +trait Selectable extends Any +``` + +An implementation of `Selectable` that relies on [Java reflection](https://www.oracle.com/technical-resources/articles/java/javareflection.html) is +available in the standard library: `scala.reflect.Selectable`. Other +implementations can be envisioned for platforms where Java reflection +is not available. + +Implementations of `Selectable` have to make available one or both of +the methods `selectDynamic` and `applyDynamic`. The methods could be members of the `Selectable` implementation or they could be extension methods. + +The `selectDynamic` method takes a field name and returns the value associated with that name in the `Selectable`. +It should have a signature of the form: + +```scala +def selectDynamic(name: String): T +``` + +Often, the return type `T` is `Any`. + +Unlike `scala.Dynamic`, there is no special meaning for an `updateDynamic` method. +However, we reserve the right to give it meaning in the future. +Consequently, it is recommended not to define any member called `updateDynamic` in `Selectable`s. + +The `applyDynamic` method is used for selections that are applied to arguments. It takes a method name and possibly `Class`es representing its parameters types as well as the arguments to pass to the function. +Its signature should be of one of the two following forms: + +```scala +def applyDynamic(name: String)(args: Any*): T +def applyDynamic(name: String, ctags: Class[?]*)(args: Any*): T +``` + +Both versions are passed the actual arguments in the `args` parameter. The second version takes in addition a vararg argument of `java.lang.Class`es that identify the method's parameter classes. Such an argument is needed +if `applyDynamic` is implemented using Java reflection, but it could be +useful in other cases as well. `selectDynamic` and `applyDynamic` can also take additional context parameters in using clauses. These are resolved in the normal way at the callsite. + +Given a value `v` of type `C { Rs }`, where `C` is a class reference +and `Rs` are structural refinement declarations, and given `v.a` of type `U`, we consider three distinct cases: + +- If `U` is a value type, we map `v.a` to: + ```scala + v.selectDynamic("a").asInstanceOf[U] + ``` + +- If `U` is a method type `(T11, ..., T1n)...(TN1, ..., TNn): R` and it is not a dependent method type, we map `v.a(a11, ..., a1n)...(aN1, ..., aNn)` to: + ```scala + v.applyDynamic("a")(a11, ..., a1n, ..., aN1, ..., aNn) + .asInstanceOf[R] + ``` + If this call resolves to an `applyDynamic` method of the second form that takes a `Class[?]*` argument, we further rewrite this call to + ```scala + v.applyDynamic("a", c11, ..., c1n, ..., cN1, ... cNn)( + a11, ..., a1n, ..., aN1, ..., aNn) + .asInstanceOf[R] + ``` + where each `c_ij` is the literal `java.lang.Class[?]` of the type of the formal parameter `Tij`, i.e., `classOf[Tij]`. + +- If `U` is neither a value nor a method type, or a dependent method + type, an error is emitted. + +Note that `v`'s static type does not necessarily have to conform to `Selectable`, nor does it need to have `selectDynamic` and `applyDynamic` as members. It suffices that there is an implicit +conversion that can turn `v` into a `Selectable`, and the selection methods could also be available as +[extension methods](../contextual/extension-methods.md). + +## Limitations of Structural Types + +- Dependent methods cannot be called via structural call. + +- Refinements may not introduce overloads: If a refinement specifies the signature + of a method `m`, and `m` is also defined in the parent type of the refinement, then + the new signature must properly override the existing one. + +- Subtyping of structural refinements must preserve erased parameter types: Assume + we want to prove `S <: T { def m(x: A): B }`. Then, as usual, `S` must have a member method `m` that can take an argument of type `A`. Furthermore, if `m` is not a member of `T` (i.e. the refinement is structural), an additional condition applies. In this case, the member _definition_ `m` of `S` will have a parameter + with type `A'` say. The additional condition is that the erasure of `A'` and `A` is the same. Here is an example: + + ```scala + class Sink[A] { def put(x: A): Unit = {} } + val a = Sink[String]() + val b: { def put(x: String): Unit } = a // error + b.put("abc") // looks for a method with a `String` parameter + ``` + The second to last line is not well-typed, + since the erasure of the parameter type of `put` in class `Sink` is `Object`, + but the erasure of `put`'s parameter in the type of `b` is `String`. + This additional condition is necessary, since we will have to resort + to some (as yet unknown) form of reflection to call a structural member + like `put` in the type of `b` above. The condition ensures that the statically + known parameter types of the refinement correspond up to erasure to the + parameter types of the selected call target at runtime. + + Most reflection dispatch algorithms need to know exact erased parameter types. For instance, if the example above would typecheck, the call + `b.put("abc")` on the last line would look for a method `put` in the runtime type of `b` that takes a `String` parameter. But the `put` method is the one from class `Sink`, which takes an `Object` parameter. Hence the call would fail at runtime with a `NoSuchMethodException`. + + One might hope for a "more intelligent" reflexive dispatch algorithm that does not require exact parameter type matching. Unfortunately, this can always run into ambiguities, as long as overloading is a possibility. For instance, continuing the example above, we might introduce a new subclass `Sink1` of `Sink` and change the definition of `a` as follows: + + ```scala + class Sink1[A] extends Sink[A] { def put(x: "123") = ??? } + val a: Sink[String] = Sink1[String]() + ``` + + Now there are two `put` methods in the runtime type of `b` with erased parameter + types `Object` and `String`, respectively. Yet dynamic dispatch still needs to go + to the first `put` method, even though the second looks like a better match. + + For the cases where we can in fact implement reflection without knowing precise parameter types (for instance if static overloading is replaced by dynamically dispatched multi-methods), there is an escape hatch. For types that extend `scala.Selectable.WithoutPreciseParameterTypes` the signature check is omitted. Example: + + ```scala + trait MultiMethodSelectable extends Selectable.WithoutPreciseParameterTypes: + // Assume this version of `applyDynamic` can be implemented without knowing + // precise parameter types `paramTypes`: + def applyDynamic(name: String, paramTypes: Class[_]*)(args: Any*): Any = ??? + + class Sink[A] extends MultiMethodSelectable: + def put(x: A): Unit = {} + + val a = new Sink[String] + val b: MultiMethodSelectable { def put(x: String): Unit } = a // OK + ``` +## Differences with Scala 2 Structural Types + +- Scala 2 supports structural types by means of Java reflection. Unlike + Scala 3, structural calls do not rely on a mechanism such as + `Selectable`, and reflection cannot be avoided. +- In Scala 2, refinements can introduce overloads. +- In Scala 2, mutable `var`s are allowed in refinements. In Scala 3, + they are no longer allowed. +- Scala 2 does not impose the "same-erasure" restriction on subtyping of structural types. It allows some calls to fail at runtime instead. + +## Context + +For more information, see [Rethink Structural Types](https://github.com/lampepfl/dotty/issues/1886). diff --git a/docs/_spec/TODOreference/changed-features/structural-types.md b/docs/_spec/TODOreference/changed-features/structural-types.md new file mode 100644 index 000000000000..37e583332cf1 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/structural-types.md @@ -0,0 +1,191 @@ +--- +layout: doc-page +title: "Programmatic Structural Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/structural-types.html +--- + +## Motivation + +Some usecases, such as modelling database access, are more awkward in +statically typed languages than in dynamically typed languages: With +dynamically typed languages, it's quite natural to model a row as a +record or object, and to select entries with simple dot notation (e.g. +`row.columnName`). + +Achieving the same experience in statically typed +language requires defining a class for every possible row arising from +database manipulation (including rows arising from joins and +projections) and setting up a scheme to map between a row and the +class representing it. + +This requires a large amount of boilerplate, which leads developers to +trade the advantages of static typing for simpler schemes where colum +names are represented as strings and passed to other operators (e.g. +`row.select("columnName")`). This approach forgoes the advantages of +static typing, and is still not as natural as the dynamically typed +version. + +Structural types help in situations where we would like to support +simple dot notation in dynamic contexts without losing the advantages +of static typing. They allow developers to use dot notation and +configure how fields and methods should be resolved. + +## Example + +Here's an example of a structural type `Person`: + +```scala + class Record(elems: (String, Any)*) extends Selectable: + private val fields = elems.toMap + def selectDynamic(name: String): Any = fields(name) + + type Person = Record { val name: String; val age: Int } + ``` + +The type `Person` adds a _refinement_ to its parent type `Record` that defines the two fields `name` and `age`. We say the refinement is _structural_ since `name` and `age` are not defined in the parent type. But they exist nevertheless as members of class `Person`. For instance, the following +program would print "Emma is 42 years old.": + +```scala + val person = Record("name" -> "Emma", "age" -> 42).asInstanceOf[Person] + println(s"${person.name} is ${person.age} years old.") +``` + +The parent type `Record` in this example is a generic class that can represent arbitrary records in its `elems` argument. This argument is a +sequence of pairs of labels of type `String` and values of type `Any`. +When we create a `Person` as a `Record` we have to assert with a typecast +that the record defines the right fields of the right types. `Record` +itself is too weakly typed so the compiler cannot know this without +help from the user. In practice, the connection between a structural type +and its underlying generic representation would most likely be done by +a database layer, and therefore would not be a concern of the end user. + +`Record` extends the marker trait [`scala.Selectable`](https://scala-lang.org/api/3.x/scala/Selectable.html) and defines +a method `selectDynamic`, which maps a field name to its value. +Selecting a structural type member is done by calling this method. +The `person.name` and `person.age` selections are translated by +the Scala compiler to: + +```scala + person.selectDynamic("name").asInstanceOf[String] + person.selectDynamic("age").asInstanceOf[Int] +``` + +Besides `selectDynamic`, a `Selectable` class sometimes also defines a method `applyDynamic`. This can then be used to translate function calls of structural members. So, if `a` is an instance of `Selectable`, a structural call like `a.f(b, c)` would translate to + +```scala + a.applyDynamic("f")(b, c) +``` + +## Using Java Reflection + +Structural types can also be accessed using [Java reflection](https://www.oracle.com/technical-resources/articles/java/javareflection.html). Example: + +```scala + type Closeable = { def close(): Unit } + + class FileInputStream: + def close(): Unit + + class Channel: + def close(): Unit +``` + +Here, we define a structural type `Closeable` that defines a `close` method. There are various classes that have `close` methods, we just list [`FileInputStream`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/FileInputStream.html#%3Cinit%3E(java.io.File)) and [`Channel`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/channels/Channel.html) as two examples. It would be easiest if the two classes shared a common interface that factors out the `close` method. But such factorings are often not possible if different libraries are combined in one application. Yet, we can still have methods that work on +all classes with a `close` method by using the `Closeable` type. For instance, + +```scala + import scala.reflect.Selectable.reflectiveSelectable + + def autoClose(f: Closeable)(op: Closeable => Unit): Unit = + try op(f) finally f.close() +``` + +The call `f.close()` has to use Java reflection to identify and call the `close` method in the receiver `f`. This needs to be enabled by an import +of `reflectiveSelectable` shown above. What happens "under the hood" is then the following: + + - The import makes available an implicit conversion that turns any type into a + `Selectable`. `f` is wrapped in this conversion. + + - The compiler then transforms the `close` call on the wrapped `f` + to an `applyDynamic` call. The end result is: + + ```scala + reflectiveSelectable(f).applyDynamic("close")() + ``` + - The implementation of `applyDynamic` in `reflectiveSelectable`'s result +uses Java reflection to find and call a method `close` with zero parameters in the value referenced by `f` at runtime. + +Structural calls like this tend to be much slower than normal method calls. The mandatory import of `reflectiveSelectable` serves as a signpost that something inefficient is going on. + +**Note:** In Scala 2, Java reflection is the only mechanism available for structural types and it is automatically enabled without needing the +`reflectiveSelectable` conversion. However, to warn against inefficient +dispatch, Scala 2 requires a language import `import scala.language.reflectiveCalls`. + +Before resorting to structural calls with Java reflection one should consider alternatives. For instance, sometimes a more modular _and_ efficient architecture can be obtained using type classes. + +## Extensibility + +New instances of `Selectable` can be defined to support means of +access other than Java reflection, which would enable usages such as +the database access example given at the beginning of this document. + +## Local Selectable Instances + +Local and anonymous classes that extend `Selectable` get more refined types +than other classes. Here is an example: + +```scala +trait Vehicle extends reflect.Selectable: + val wheels: Int + +val i3 = new Vehicle: // i3: Vehicle { val range: Int } + val wheels = 4 + val range = 240 + +i3.range +``` + +The type of `i3` in this example is `Vehicle { val range: Int }`. Hence, +`i3.range` is well-formed. Since the base class `Vehicle` does not define a `range` field or method, we need structural dispatch to access the `range` field of the anonymous class that initializes `id3`. Structural dispatch +is implemented by the base trait [`reflect.Selectable`](https://scala-lang.org/api/3.x/scala/reflect/Selectable.html) of `Vehicle`, which defines the necessary `selectDynamic` member. + +`Vehicle` could also extend some other subclass of [`scala.Selectable`](https://scala-lang.org/api/3.x/scala/Selectable.html) that implements `selectDynamic` and `applyDynamic` differently. But if it does not extend a `Selectable` at all, the code would no longer typecheck: + +```scala +trait Vehicle: + val wheels: Int + +val i3 = new Vehicle: // i3: Vehicle + val wheels = 4 + val range = 240 + +i3.range // error: range is not a member of `Vehicle` +``` + +The difference is that the type of an anonymous class that does not extend `Selectable` is just formed from the parent type(s) of the class, without +adding any refinements. Hence, `i3` now has just type `Vehicle` and the selection `i3.range` gives a "member not found" error. + +Note that in Scala 2 all local and anonymous classes could produce values with refined types. But +members defined by such refinements could be selected only with the language import +[`reflectiveCalls`](https://scala-lang.org/api/3.x/scala/languageFeature$$reflectiveCalls$.html). + +## Relation with `scala.Dynamic` + +There are clearly some connections with [`scala.Dynamic`](https://scala-lang.org/api/3.x/scala/Dynamic.html) here, since +both select members programmatically. But there are also some +differences. + +- Fully dynamic selection is not typesafe, but structural selection + is, as long as the correspondence of the structural type with the + underlying value is as stated. + +- [`Dynamic`](https://scala-lang.org/api/3.x/scala/Dynamic.html) is just a marker trait, which gives more leeway where and + how to define reflective access operations. By contrast + `Selectable` is a trait which declares the access operations. + +- Two access operations, `selectDynamic` and `applyDynamic` are shared + between both approaches. In `Selectable`, `applyDynamic` also may also take + [`java.lang.Class`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html) arguments indicating the method's formal parameter types. + [`Dynamic`](https://scala-lang.org/api/3.x/scala/Dynamic.html) comes with `updateDynamic`. + +[More details](structural-types-spec.md) diff --git a/docs/_spec/TODOreference/changed-features/type-checking.md b/docs/_spec/TODOreference/changed-features/type-checking.md new file mode 100644 index 000000000000..6f59b1a1c1c6 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/type-checking.md @@ -0,0 +1,7 @@ +--- +layout: doc-page +title: "Changes in Type Checking" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/type-checking.html +--- + +*** **TO BE FILLED IN** *** diff --git a/docs/_spec/TODOreference/changed-features/type-inference.md b/docs/_spec/TODOreference/changed-features/type-inference.md new file mode 100644 index 000000000000..00d0e959f5ed --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/type-inference.md @@ -0,0 +1,10 @@ +--- +layout: doc-page +title: "Changes in Type Inference" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/type-inference.html +--- + +For more information, see the two presentations + +* [Scala 3, Type inference and You!](https://www.youtube.com/watch?v=lMvOykNQ4zs) by Guillaume Martres (September 2019) +* [GADTs in Dotty](https://www.youtube.com/watch?v=VV9lPg3fNl8) by Aleksander Boruch-Gruszecki (July 2019). diff --git a/docs/_spec/TODOreference/changed-features/vararg-splices.md b/docs/_spec/TODOreference/changed-features/vararg-splices.md new file mode 100644 index 000000000000..43c4acc5f880 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/vararg-splices.md @@ -0,0 +1,40 @@ +--- +layout: doc-page +title: "Vararg Splices" +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/vararg-splices.html +--- + +The syntax of vararg splices in patterns and function arguments has changed. The new syntax uses a postfix `*`, analogously to how a vararg parameter is declared. + +```scala +val arr = Array(0, 1, 2, 3) +val lst = List(arr*) // vararg splice argument +lst match + case List(0, 1, xs*) => println(xs) // binds xs to Seq(2, 3) + case List(1, _*) => // wildcard pattern +``` + +The old syntax for splice arguments will be phased out. + +```scala +/*!*/ val lst = List(arr: _*) // syntax error + lst match + case List(0, 1, xs @ _*) // ok, equivalent to `xs*` +``` + +## Syntax + +``` +ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ + | ‘(’ [Patterns ‘,’] Pattern2 ‘*’ ‘)’ + +ParArgumentExprs ::= ‘(’ [‘using’] ExprsInParens ‘)’ + | ‘(’ [ExprsInParens ‘,’] PostfixExpr ‘*’ ‘)’ +``` + +## Compatibility considerations + +To enable cross compilation between Scala 2 and Scala 3, the compiler will +accept both the old and the new syntax. Under the `-source future` setting, an error +will be emitted when the old syntax is encountered. An automatic rewrite from old +to new syntax is offered under `-source future-migration`. diff --git a/docs/_spec/TODOreference/changed-features/wildcards.md b/docs/_spec/TODOreference/changed-features/wildcards.md new file mode 100644 index 000000000000..0d3e13c3d7e0 --- /dev/null +++ b/docs/_spec/TODOreference/changed-features/wildcards.md @@ -0,0 +1,50 @@ +--- +layout: doc-page +title: Wildcard Arguments in Types +nightlyOf: https://docs.scala-lang.org/scala3/reference/changed-features/wildcards.html +--- + +The syntax of wildcard arguments in types has changed from `_` to `?`. Example: +```scala +List[?] +Map[? <: AnyRef, ? >: Null] +``` + +## Motivation + +We would like to use the underscore syntax `_` to stand for an anonymous type parameter, aligning it with its meaning in +value parameter lists. So, just as `f(_)` is a shorthand for the lambda `x => f(x)`, in the future `C[_]` will be a shorthand +for the type lambda `[X] =>> C[X]`. This makes higher-kinded types easier to use. It also removes the wart that, used as a type +parameter, `F[_]` means `F` is a type constructor whereas used as a type, `F[_]` means it is a wildcard (i.e. existential) type. +In the future, `F[_]` will mean the same thing, no matter where it is used. + +We pick `?` as a replacement syntax for wildcard types, since it aligns with +[Java's syntax](https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html). + +## Migration Strategy + +The migration to the new scheme is complicated, in particular since the [kind projector](https://github.com/typelevel/kind-projector) +compiler plugin still uses the reverse convention, with `?` meaning parameter placeholder instead of wildcard. Fortunately, kind projector has added `*` as an alternative syntax for `?`. + +A step-by-step migration is made possible with the following measures: + + 1. In Scala 3.0, both `_` and `?` are legal names for wildcards. + 2. In Scala 3.1, `_` is deprecated in favor of `?` as a name for a wildcard. A `-rewrite` option is + available to rewrite one to the other. + 3. In Scala 3.2, the meaning of `_` changes from wildcard to placeholder for type parameter. + 4. The Scala 3.1 behavior is already available today under the `-source future` setting. + +To smooth the transition for codebases that use kind-projector, we adopt the following measures under the command line +option `-Ykind-projector`: + + 1. In Scala 3.0, `*` is available as a type parameter placeholder. + 2. In Scala 3.2, `*` is deprecated in favor of `_`. A `-rewrite` option is + available to rewrite one to the other. + 3. In Scala 3.3, `*` is removed again, and all type parameter placeholders will be expressed with `_`. + +These rules make it possible to cross build between Scala 2 using the kind projector plugin and Scala 3.0 - 3.2 using the compiler option `-Ykind-projector`. + +There is also a migration path for users that want a one-time transition to syntax with `_` as a type parameter placeholder. +With option `-Ykind-projector:underscores` Scala 3 will regard `_` as a type parameter placeholder, leaving `?` as the only syntax for wildcards. + +To cross-compile with old Scala 2 sources, while using `_` a placeholder, you must use options `-Xsource:3 -P:kind-projector:underscore-placeholders` together with a recent version of kind-projector (`0.13` and higher) and most recent versions of Scala 2 (`2.13.5` and higher and `2.12.14` and higher) diff --git a/docs/_spec/TODOreference/contextual/by-name-context-parameters.md b/docs/_spec/TODOreference/contextual/by-name-context-parameters.md new file mode 100644 index 000000000000..3004bfb2c4c2 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/by-name-context-parameters.md @@ -0,0 +1,65 @@ +--- +layout: doc-page +title: "By-Name Context Parameters" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/by-name-context-parameters.html +--- + +Context parameters can be declared by-name to avoid a divergent inferred expansion. Example: + +```scala +trait Codec[T]: + def write(x: T): Unit + +given intCodec: Codec[Int] = ??? + +given optionCodec[T](using ev: => Codec[T]): Codec[Option[T]] with + def write(xo: Option[T]) = xo match + case Some(x) => ev.write(x) + case None => + +val s = summon[Codec[Option[Int]]] + +s.write(Some(33)) +s.write(None) +``` +As is the case for a normal by-name parameter, the argument for the context parameter `ev` +is evaluated on demand. In the example above, if the option value `x` is `None`, it is +not evaluated at all. + +The synthesized argument for a context parameter is backed by a local val +if this is necessary to prevent an otherwise diverging expansion. + +The precise steps for synthesizing an argument for a by-name context parameter of type `=> T` are as follows. + + 1. Create a new given of type `T`: + + ```scala + given lv: T = ??? + ``` + + where `lv` is an arbitrary fresh name. + + 1. This given is not immediately available as candidate for argument inference (making it immediately available could result in a loop in the synthesized computation). But it becomes available in all nested contexts that look again for an argument to a by-name context parameter. + + 1. If this search succeeds with expression `E`, and `E` contains references to `lv`, replace `E` by + + ```scala + { given lv: T = E; lv } + ``` + + Otherwise, return `E` unchanged. + +In the example above, the definition of `s` would be expanded as follows. + +```scala +val s = summon[Test.Codec[Option[Int]]]( + optionCodec[Int](using intCodec) +) +``` + +No local given instance was generated because the synthesized argument is not recursive. + +## Reference + +For more information, see [Issue #1998](https://github.com/lampepfl/dotty/issues/1998) +and the associated [Scala SIP](https://docs.scala-lang.org/sips/byname-implicits.html). diff --git a/docs/_spec/TODOreference/contextual/context-bounds.md b/docs/_spec/TODOreference/contextual/context-bounds.md new file mode 100644 index 000000000000..42479d6802b3 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/context-bounds.md @@ -0,0 +1,53 @@ +--- +layout: doc-page +title: "Context Bounds" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/context-bounds.html +--- + +A context bound is a shorthand for expressing the common pattern of a context parameter that depends on a type parameter. Using a context bound, the `maximum` function of the last section can be written like this: + +```scala +def maximum[T: Ord](xs: List[T]): T = xs.reduceLeft(max) +``` + +A bound like `: Ord` on a type parameter `T` of a method or class indicates a context parameter `using Ord[T]`. The context parameter(s) generated from context bounds +are added as follows: + + - If the method parameters end in an implicit parameter list or using clause, + context parameters are added in front of that list. + - Otherwise they are added as a separate parameter clause at the end. + +Example: + +```scala +def f[T: C1 : C2, U: C3](x: T)(using y: U, z: V): R +``` + +would expand to + +```scala +def f[T, U](x: T)(using _: C1[T], _: C2[T], _: C3[U], y: U, z: V): R +``` + +Context bounds can be combined with subtype bounds. If both are present, subtype bounds come first, e.g. + +```scala +def g[T <: B : C](x: T): R = ... +``` + +## Migration + +To ease migration, context bounds in Dotty map in Scala 3.0 to old-style implicit parameters +for which arguments can be passed either with a `(using ...)` clause or with a normal application. From Scala 3.1 on, they will map to context parameters instead, as is described above. + +If the source version is `future-migration`, any pairing of an evidence +context parameter stemming from a context bound with a normal argument will give a migration +warning. The warning indicates that a `(using ...)` clause is needed instead. The rewrite can be +done automatically under `-rewrite`. + +## Syntax + +``` +TypeParamBounds ::= [SubtypeBounds] {ContextBound} +ContextBound ::= ‘:’ Type +``` diff --git a/docs/_spec/TODOreference/contextual/context-functions-spec.md b/docs/_spec/TODOreference/contextual/context-functions-spec.md new file mode 100644 index 000000000000..109513e9da86 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/context-functions-spec.md @@ -0,0 +1,79 @@ +--- +layout: doc-page +title: "Context Functions - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/context-functions-spec.html +--- + +## Syntax + +``` +Type ::= ... + | FunArgTypes ‘?=>’ Type +Expr ::= ... + | FunParams ‘?=>’ Expr +``` + +Context function types associate to the right, e.g. +`S ?=> T ?=> U` is the same as `S ?=> (T ?=> U)`. + +## Implementation + +Context function types are shorthands for class types that define `apply` +methods with context parameters. Specifically, the `N`-ary function type + +`T1, ..., TN ?=> R` is a shorthand for the class type +`ContextFunctionN[T1, ..., TN, R]`. Such class types are assumed to have the following definitions, for any value of `N >= 1`: + +```scala +package scala +trait ContextFunctionN[-T1, ..., -TN, +R]: + def apply(using x1: T1, ..., xN: TN): R +``` + +Context function types erase to normal function types, so these classes are +generated on the fly for typechecking, but not realized in actual code. + +Context function literals `(x1: T1, ..., xn: Tn) ?=> e` map +context parameters `xi` of types `Ti` to the result of evaluating the expression `e`. +The scope of each context parameter `xi` is `e`. The parameters must have pairwise distinct names. + +If the expected type of the context function literal is of the form +`scala.ContextFunctionN[S1, ..., Sn, R]`, the expected type of `e` is `R` and +the type `Ti` of any of the parameters `xi` can be omitted, in which case `Ti += Si` is assumed. If the expected type of the context function literal is +some other type, all context parameter types must be explicitly given, and the expected type of `e` is undefined. +The type of the context function literal is `scala.ContextFunctionN[S1, ...,Sn, T]`, where `T` is the widened +type of `e`. `T` must be equivalent to a type which does not refer to any of +the context parameters `xi`. + +The context function literal is evaluated as the instance creation expression + +```scala +new scala.ContextFunctionN[T1, ..., Tn, T]: + def apply(using x1: T1, ..., xn: Tn): T = e +``` + +A context parameter may also be a wildcard represented by an underscore `_`. In that case, a fresh name for the parameter is chosen arbitrarily. + +**Note:** The closing paragraph of the +[Anonymous Functions section](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#anonymous-functions) +of Scala 2.13 is subsumed by context function types and should be removed. + +Context function literals `(x1: T1, ..., xn: Tn) ?=> e` are +automatically created for any expression `e` whose expected type is +`scala.ContextFunctionN[T1, ..., Tn, R]`, unless `e` is +itself a context function literal. This is analogous to the automatic +insertion of [`scala.Function0`](https://scala-lang.org/api/3.x/scala/Function0.html) around expressions in by-name argument position. + +Context function types generalize to `N > 22` in the same way that function types do, see [the corresponding +documentation](../dropped-features/limit22.md). + +## Examples + +See the section on Expressiveness from [Simplicitly: foundations and +applications of implicit function +types](https://dl.acm.org/citation.cfm?id=3158130). + +## Type Checking + +After desugaring no additional typing rules are required for context function types. diff --git a/docs/_spec/TODOreference/contextual/context-functions.md b/docs/_spec/TODOreference/contextual/context-functions.md new file mode 100644 index 000000000000..0ad3c8757782 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/context-functions.md @@ -0,0 +1,154 @@ +--- +layout: doc-page +title: "Context Functions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/context-functions.html +--- + +_Context functions_ are functions with (only) context parameters. +Their types are _context function types_. Here is an example of a context function type: + +```scala +type Executable[T] = ExecutionContext ?=> T +``` +Context functions are written using `?=>` as the "arrow" sign. +They are applied to synthesized arguments, in +the same way methods with context parameters are applied. For instance: +```scala + given ec: ExecutionContext = ... + + def f(x: Int): ExecutionContext ?=> Int = ... + + // could be written as follows with the type alias from above + // def f(x: Int): Executable[Int] = ... + + f(2)(using ec) // explicit argument + f(2) // argument is inferred +``` +Conversely, if the expected type of an expression `E` is a context function type +`(T_1, ..., T_n) ?=> U` and `E` is not already an +context function literal, `E` is converted to a context function literal by rewriting it to +```scala + (x_1: T1, ..., x_n: Tn) ?=> E +``` +where the names `x_1`, ..., `x_n` are arbitrary. This expansion is performed +before the expression `E` is typechecked, which means that `x_1`, ..., `x_n` +are available as givens in `E`. + +Like their types, context function literals are written using `?=>` as the arrow between parameters and results. They differ from normal function literals in that their types are context function types. + +For example, continuing with the previous definitions, +```scala + def g(arg: Executable[Int]) = ... + + g(22) // is expanded to g((ev: ExecutionContext) ?=> 22) + + g(f(2)) // is expanded to g((ev: ExecutionContext) ?=> f(2)(using ev)) + + g((ctx: ExecutionContext) ?=> f(3)) // is expanded to g((ctx: ExecutionContext) ?=> f(3)(using ctx)) + g((ctx: ExecutionContext) ?=> f(3)(using ctx)) // is left as it is +``` + +## Example: Builder Pattern + +Context function types have considerable expressive power. For +instance, here is how they can support the "builder pattern", where +the aim is to construct tables like this: +```scala + table { + row { + cell("top left") + cell("top right") + } + row { + cell("bottom left") + cell("bottom right") + } + } +``` +The idea is to define classes for `Table` and `Row` that allow the +addition of elements via `add`: +```scala + class Table: + val rows = new ArrayBuffer[Row] + def add(r: Row): Unit = rows += r + override def toString = rows.mkString("Table(", ", ", ")") + + class Row: + val cells = new ArrayBuffer[Cell] + def add(c: Cell): Unit = cells += c + override def toString = cells.mkString("Row(", ", ", ")") + + case class Cell(elem: String) +``` +Then, the `table`, `row` and `cell` constructor methods can be defined +with context function types as parameters to avoid the plumbing boilerplate +that would otherwise be necessary. +```scala + def table(init: Table ?=> Unit) = + given t: Table = Table() + init + t + + def row(init: Row ?=> Unit)(using t: Table) = + given r: Row = Row() + init + t.add(r) + + def cell(str: String)(using r: Row) = + r.add(new Cell(str)) +``` +With that setup, the table construction code above compiles and expands to: +```scala + table { ($t: Table) ?=> + + row { ($r: Row) ?=> + cell("top left")(using $r) + cell("top right")(using $r) + }(using $t) + + row { ($r: Row) ?=> + cell("bottom left")(using $r) + cell("bottom right")(using $r) + }(using $t) + } +``` +## Example: Postconditions + +As a larger example, here is a way to define constructs for checking arbitrary postconditions using an extension method `ensuring` so that the checked result can be referred to simply by `result`. The example combines opaque type aliases, context function types, and extension methods to provide a zero-overhead abstraction. + +```scala +object PostConditions: + opaque type WrappedResult[T] = T + + def result[T](using r: WrappedResult[T]): T = r + + extension [T](x: T) + def ensuring(condition: WrappedResult[T] ?=> Boolean): T = + assert(condition(using x)) + x +end PostConditions +import PostConditions.{ensuring, result} + +val s = List(1, 2, 3).sum.ensuring(result == 6) +``` +**Explanations**: We use a context function type `WrappedResult[T] ?=> Boolean` +as the type of the condition of `ensuring`. An argument to `ensuring` such as +`(result == 6)` will therefore have a given of type `WrappedResult[T]` in +scope to pass along to the `result` method. `WrappedResult` is a fresh type, to make sure +that we do not get unwanted givens in scope (this is good practice in all cases +where context parameters are involved). Since `WrappedResult` is an opaque type alias, its +values need not be boxed, and since `ensuring` is added as an extension method, its argument +does not need boxing either. Hence, the implementation of `ensuring` is close in efficiency to the best possible code one could write by hand: + +```scala +val s = + val result = List(1, 2, 3).sum + assert(result == 6) + result +``` +## Reference + +For more information, see the [blog article](https://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html), +(which uses a different syntax that has been superseded). + +[More details](./context-functions-spec.md) diff --git a/docs/_spec/TODOreference/contextual/contextual.md b/docs/_spec/TODOreference/contextual/contextual.md new file mode 100644 index 000000000000..fda63397f8f9 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/contextual.md @@ -0,0 +1,83 @@ +--- +layout: index +title: "Contextual Abstractions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual.html +--- + +## Critique of the Status Quo + +Scala's implicits are its most distinguished feature. They are _the_ fundamental way to abstract over context. They represent a unified paradigm with a great variety of use cases, among them: implementing type classes, establishing context, dependency injection, expressing capabilities, computing new types and proving relationships between them. + +Following Haskell, Scala was the second popular language to have some form of implicits. Other languages have followed suit. E.g [Rust's traits](https://doc.rust-lang.org/rust-by-example/trait.html) or [Swift's protocol extensions](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID521). Design proposals are also on the table for Kotlin as [compile time dependency resolution](https://github.com/Kotlin/KEEP/blob/e863b25f8b3f2e9b9aaac361c6ee52be31453ee0/proposals/compile-time-dependency-resolution.md), for C# as [Shapes and Extensions](https://github.com/dotnet/csharplang/issues/164) +or for F# as [Traits](https://github.com/MattWindsor91/visualfsharp/blob/hackathon-vs/examples/fsconcepts.md). Implicits are also a common feature of theorem provers such as [Coq](https://coq.inria.fr/refman/language/extensions/implicit-arguments.html) or [Agda](https://agda.readthedocs.io/en/latest/language/implicit-arguments.html). + +Even though these designs use widely different terminology, they are all variants of the core idea of _term inference_. Given a type, the compiler synthesizes a "canonical" term that has that type. Scala embodies the idea in a purer form than most other languages: An implicit parameter directly leads to an inferred argument term that could also be written down explicitly. By contrast, type class based designs are less direct since they hide term inference behind some form of type classification and do not offer the option of writing the inferred quantities (typically, dictionaries) explicitly. + +Given that term inference is where the industry is heading, and given that Scala has it in a very pure form, how come implicits are not more popular? In fact, it's fair to say that implicits are at the same time Scala's most distinguished and most controversial feature. I believe this is due to a number of aspects that together make implicits harder to learn than necessary and also make it harder to prevent abuses. + +Particular criticisms are: + +1. Being very powerful, implicits are easily over-used and mis-used. This observation holds in almost all cases when we talk about _implicit conversions_, which, even though conceptually different, share the same syntax with other implicit definitions. For instance, regarding the two definitions + + ```scala + implicit def i1(implicit x: T): C[T] = ... + implicit def i2(x: T): C[T] = ... + ``` + + the first of these is a conditional implicit _value_, the second an implicit _conversion_. Conditional implicit values are a cornerstone for expressing type classes, whereas most applications of implicit conversions have turned out to be of dubious value. The problem is that many newcomers to the language start with defining implicit conversions since they are easy to understand and seem powerful and convenient. Scala 3 will put under a language flag both definitions and applications of "undisciplined" implicit conversions between types defined elsewhere. This is a useful step to push back against overuse of implicit conversions. But the problem remains that syntactically, conversions and values just look too similar for comfort. + +2. Another widespread abuse is over-reliance on implicit imports. This often leads to inscrutable type errors that go away with the right import incantation, leaving a feeling of frustration. Conversely, it is hard to see what implicits a program uses since implicits can hide anywhere in a long list of imports. + +3. The syntax of implicit definitions is too minimal. It consists of a single modifier, `implicit`, that can be attached to a large number of language constructs. A problem with this for newcomers is that it conveys mechanism instead of intent. For instance, a type class instance is an implicit object or val if unconditional and an implicit def with implicit parameters referring to some class if conditional. This describes precisely what the implicit definitions translate to -- just drop the `implicit` modifier, and that's it! But the cues that define intent are rather indirect and can be easily misread, as demonstrated by the definitions of `i1` and `i2` above. + +4. The syntax of implicit parameters also has shortcomings. While implicit _parameters_ are designated specifically, arguments are not. Passing an argument to an implicit parameter looks like a regular application `f(arg)`. This is problematic because it means there can be confusion regarding what parameter gets instantiated in a call. For instance, in + + ```scala + def currentMap(implicit ctx: Context): Map[String, Int] + ``` + + one cannot write `currentMap("abc")` since the string `"abc"` is taken as explicit argument to the implicit `ctx` parameter. One has to write `currentMap.apply("abc")` instead, which is awkward and irregular. For the same reason, a method definition can only have one implicit parameter section and it must always come last. This restriction not only reduces orthogonality, but also prevents some useful program constructs, such as a method with a regular parameter whose type depends on an implicit value. Finally, it's also a bit annoying that implicit parameters must have a name, even though in many cases that name is never referenced. + +5. Implicits pose challenges for tooling. The set of available implicits depends on context, so command completion has to take context into account. This is feasible in an IDE but tools like [Scaladoc](https://docs.scala-lang.org/overviews/scaladoc/overview.html) that are based on static web pages can only provide an approximation. Another problem is that failed implicit searches often give very unspecific error messages, in particular if some deeply recursive implicit search has failed. Note that the Scala 3 compiler has already made a lot of progress in the error diagnostics area. If a recursive search fails some levels down, it shows what was constructed and what is missing. Also, it suggests imports that can bring missing implicits in scope. + +None of the shortcomings is fatal, after all implicits are very widely used, and many libraries and applications rely on them. But together, they make code using implicits a lot more cumbersome and less clear than it could be. + +Historically, many of these shortcomings come from the way implicits were gradually "discovered" in Scala. Scala originally had only implicit conversions with the intended use case of "extending" a class or trait after it was defined, i.e. what is expressed by implicit classes in later versions of Scala. Implicit parameters and instance definitions came later in 2006 and we picked similar syntax since it seemed convenient. For the same reason, no effort was made to distinguish implicit imports or arguments from normal ones. + +Existing Scala programmers by and large have gotten used to the status quo and see little need for change. But for newcomers this status quo presents a big hurdle. I believe if we want to overcome that hurdle, we should take a step back and allow ourselves to consider a radically new design. + +## The New Design + +The following pages introduce a redesign of contextual abstractions in Scala. They introduce four fundamental changes: + +1. [Given Instances](./givens.md) are a new way to define basic terms that can be synthesized. They replace implicit definitions. The core principle of the proposal is that, rather than mixing the `implicit` modifier with a large number of features, we have a single way to define terms that can be synthesized for types. + +2. [Using Clauses](./using-clauses.md) are a new syntax for implicit _parameters_ and their _arguments_. It unambiguously aligns parameters and arguments, solving a number of language warts. It also allows us to have several `using` clauses in a definition. + +3. ["Given" Imports](./given-imports.md) are a new class of import selectors that specifically import + givens and nothing else. + +4. [Implicit Conversions](./conversions.md) are now expressed as given instances of a standard `Conversion` class. All other forms of implicit conversions will be phased out. + +This section also contains pages describing other language features that are related to context abstraction. These are: + +- [Context Bounds](./context-bounds.md), which carry over unchanged. +- [Extension Methods](./extension-methods.md) replace implicit classes in a way that integrates better with type classes. +- [Implementing Type Classes](./type-classes.md) demonstrates how some common type classes can be implemented using the new constructs. +- [Type Class Derivation](./derivation.md) introduces constructs to automatically derive type class instances for ADTs. +- [Multiversal Equality](./multiversal-equality.md) introduces a special type class to support type safe equality. +- [Context Functions](./context-functions.md) provide a way to abstract over context parameters. +- [By-Name Context Parameters](./by-name-context-parameters.md) are an essential tool to define recursive synthesized values without looping. +- [Relationship with Scala 2 Implicits](./relationship-implicits.md) discusses the relationship between old-style implicits and new-style givens and how to migrate from one to the other. + +Overall, the new design achieves a better separation of term inference from the rest of the language: There is a single way to define givens instead of a multitude of forms all taking an `implicit` modifier. There is a single way to introduce implicit parameters and arguments instead of conflating implicit with normal arguments. There is a separate way to import givens that does not allow them to hide in a sea of normal imports. And there is a single way to define an implicit conversion which is clearly marked as such and does not require special syntax. + +This design thus avoids feature interactions and makes the language more consistent and orthogonal. It will make implicits easier to learn and harder to abuse. It will greatly improve the clarity of the 95% of Scala programs that use implicits. It has thus the potential to fulfil the promise of term inference in a principled way that is also accessible and friendly. + +Could we achieve the same goals by tweaking existing implicits? After having tried for a long time, I believe now that this is impossible. + +- First, some of the problems are clearly syntactic and require different syntax to solve them. +- Second, there is the problem how to migrate. We cannot change the rules in mid-flight. At some stage of language evolution we need to accommodate both the new and the old rules. With a syntax change, this is easy: Introduce the new syntax with new rules, support the old syntax for a while to facilitate cross compilation, deprecate and phase out the old syntax at some later time. Keeping the same syntax does not offer this path, and in fact does not seem to offer any viable path for evolution +- Third, even if we would somehow succeed with migration, we still have the problem + how to teach this. We cannot make existing tutorials go away. Almost all existing tutorials start with implicit conversions, which will go away; they use normal imports, which will go away, and they explain calls to methods with implicit parameters by expanding them to plain applications, which will also go away. This means that we'd have + to add modifications and qualifications to all existing literature and courseware, likely causing more confusion with beginners instead of less. By contrast, with a new syntax there is a clear criterion: Any book or courseware that mentions `implicit` is outdated and should be updated. diff --git a/docs/_spec/TODOreference/contextual/conversions.md b/docs/_spec/TODOreference/contextual/conversions.md new file mode 100644 index 000000000000..1ce8d42074e7 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/conversions.md @@ -0,0 +1,76 @@ +--- +layout: doc-page +title: "Implicit Conversions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/conversions.html +--- + +Implicit conversions are defined by given instances of the `scala.Conversion` class. +This class is defined in package `scala` as follows: +```scala +abstract class Conversion[-T, +U] extends (T => U): + def apply (x: T): U +``` +For example, here is an implicit conversion from `String` to `Token`: +```scala +given Conversion[String, Token] with + def apply(str: String): Token = new KeyWord(str) +``` +Using an alias this can be expressed more concisely as: +```scala +given Conversion[String, Token] = new KeyWord(_) +``` +An implicit conversion is applied automatically by the compiler in three situations: + +1. If an expression `e` has type `T`, and `T` does not conform to the expression's expected type `S`. +2. In a selection `e.m` with `e` of type `T`, but `T` defines no member `m`. +3. In an application `e.m(args)` with `e` of type `T`, if `T` does define + some member(s) named `m`, but none of these members can be applied to the arguments `args`. + +In the first case, the compiler looks for a given `scala.Conversion` instance that maps +an argument of type `T` to type `S`. In the second and third +case, it looks for a given `scala.Conversion` instance that maps an argument of type `T` +to a type that defines a member `m` which can be applied to `args` if present. +If such an instance `C` is found, the expression `e` is replaced by `C.apply(e)`. + +## Examples + +1. The `Predef` package contains "auto-boxing" conversions that map +primitive number types to subclasses of `java.lang.Number`. For instance, the +conversion from `Int` to `java.lang.Integer` can be defined as follows: + ```scala + given int2Integer: Conversion[Int, java.lang.Integer] = + java.lang.Integer.valueOf(_) + ``` + +2. The "magnet" pattern is sometimes used to express many variants of a method. Instead of defining overloaded versions of the method, one can also let the method take one or more arguments of specially defined "magnet" types, into which various argument types can be converted. Example: + ```scala + object Completions: + + // The argument "magnet" type + enum CompletionArg: + case Error(s: String) + case Response(f: Future[HttpResponse]) + case Status(code: Future[StatusCode]) + + object CompletionArg: + + // conversions defining the possible arguments to pass to `complete` + // these always come with CompletionArg + // They can be invoked explicitly, e.g. + // + // CompletionArg.fromStatusCode(statusCode) + + given fromString : Conversion[String, CompletionArg] = Error(_) + given fromFuture : Conversion[Future[HttpResponse], CompletionArg] = Response(_) + given fromStatusCode: Conversion[Future[StatusCode], CompletionArg] = Status(_) + end CompletionArg + import CompletionArg.* + + def complete[T](arg: CompletionArg) = arg match + case Error(s) => ... + case Response(f) => ... + case Status(code) => ... + + end Completions + ``` +This setup is more complicated than simple overloading of `complete`, but it can still be useful if normal overloading is not available (as in the case above, since we cannot have two overloaded methods that take `Future[...]` arguments), or if normal overloading would lead to a combinatorial explosion of variants. diff --git a/docs/_spec/TODOreference/contextual/derivation-macro.md b/docs/_spec/TODOreference/contextual/derivation-macro.md new file mode 100644 index 000000000000..be7565616913 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/derivation-macro.md @@ -0,0 +1,205 @@ +--- +layout: doc-page +title: "How to write a type class `derived` method using macros" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/derivation-macro.html +--- + +In the main [derivation](./derivation.md) documentation page, we explained the +details behind `Mirror`s and type class derivation. Here we demonstrate how to +implement a type class `derived` method using macros only. We follow the same +example of deriving `Eq` instances and for simplicity we support a `Product` +type e.g., a case class `Person`. The low-level method we will use to implement +the `derived` method exploits quotes, splices of both expressions and types and +the `scala.quoted.Expr.summon` method which is the equivalent of +`summonFrom`. The former is suitable for use in a quote context, used within +macros. + +As in the original code, the type class definition is the same: + +```scala +trait Eq[T]: + def eqv(x: T, y: T): Boolean +``` + +we need to implement a method `Eq.derived` on the companion object of `Eq` that +produces a quoted instance for `Eq[T]`. Here is a possible signature, + +```scala +given derived[T: Type](using Quotes): Expr[Eq[T]] +``` + +and for comparison reasons we give the same signature we had with `inline`: + +```scala +inline given derived[T](using Mirror.Of[T]): Eq[T] = ??? +``` + +Note, that since a type is used in a subsequent stage it will need to be lifted +to a `Type` by using the corresponding context bound. Also, note that we can +summon the quoted `Mirror` inside the body of the `derived` thus we can omit it +from the signature. The body of the `derived` method is shown below: + + +```scala +given derived[T: Type](using Quotes): Expr[Eq[T]] = + import quotes.reflect.* + + val ev: Expr[Mirror.Of[T]] = Expr.summon[Mirror.Of[T]].get + + ev match + case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} => + val elemInstances = summonAll[elementTypes] + def eqProductBody(x: Expr[Product], y: Expr[Product])(using Quotes): Expr[Boolean] = { + elemInstances.zipWithIndex.foldLeft(Expr(true)) { + case (acc, ('{ $elem: Eq[t] }, index)) => + val indexExpr = Expr(index) + val e1 = '{ $x.productElement($indexExpr).asInstanceOf[t] } + val e2 = '{ $y.productElement($indexExpr).asInstanceOf[t] } + '{ $acc && $elem.eqv($e1, $e2) } + } + } + '{ eqProduct((x: T, y: T) => ${eqProductBody('x.asExprOf[Product], 'y.asExprOf[Product])}) } + + // case for Mirror.ProductOf[T] + // ... +``` + +Note, that in the `inline` case we can merely write +`summonAll[m.MirroredElemTypes]` inside the inline method but here, since +`Expr.summon` is required, we can extract the element types in a macro fashion. +Being inside a macro, our first reaction would be to write the code below. Since +the path inside the type argument is not stable this cannot be used: + +```scala +'{ + summonAll[$m.MirroredElemTypes] +} +``` + +Instead we extract the tuple-type for element types using pattern matching over +quotes and more specifically of the refined type: + +```scala + case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} => ... +``` + +Shown below is the implementation of `summonAll` as a macro. We assume that +given instances for our primitive types exist. + +```scala +def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = + Type.of[T] match + case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] + case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] + case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] + case '[EmptyTuple] => Nil +``` + +One additional difference with the body of `derived` here as opposed to the one +with `inline` is that with macros we need to synthesize the body of the code during the +macro-expansion time. That is the rationale behind the `eqProductBody` function. +Assuming that we calculate the equality of two `Person`s defined with a case +class that holds a name of type [`String`](https://scala-lang.org/api/3.x/scala/Predef$.html#String-0) +and an age of type `Int`, the equality check we want to generate is the following: + +```scala + true + && Eq[String].eqv(x.productElement(0),y.productElement(0)) + && Eq[Int].eqv(x.productElement(1), y.productElement(1)) +``` + +## Calling the derived method inside the macro + +Following the rules in [Macros](../metaprogramming/metaprogramming.md) we create two methods. +One that hosts the top-level splice `eqv` and one that is the implementation. +Alternatively and what is shown below is that we can call the `eqv` method +directly. The `eqGen` can trigger the derivation. + +```scala +extension [T](inline x: T) + inline def === (inline y: T)(using eq: Eq[T]): Boolean = eq.eqv(x, y) + +inline given eqGen[T]: Eq[T] = ${ Eq.derived[T] } +``` + +Note, that we use inline method syntax and we can compare instance such as +`Sm(Person("Test", 23)) === Sm(Person("Test", 24))` for e.g., the following two +types: + +```scala +case class Person(name: String, age: Int) + +enum Opt[+T]: + case Sm(t: T) + case Nn +``` + +The full code is shown below: + +```scala +import scala.deriving.* +import scala.quoted.* + + +trait Eq[T]: + def eqv(x: T, y: T): Boolean + +object Eq: + given Eq[String] with + def eqv(x: String, y: String) = x == y + + given Eq[Int] with + def eqv(x: Int, y: Int) = x == y + + def eqProduct[T](body: (T, T) => Boolean): Eq[T] = + new Eq[T]: + def eqv(x: T, y: T): Boolean = body(x, y) + + def eqSum[T](body: (T, T) => Boolean): Eq[T] = + new Eq[T]: + def eqv(x: T, y: T): Boolean = body(x, y) + + def summonAll[T: Type](using Quotes): List[Expr[Eq[_]]] = + Type.of[T] match + case '[String *: tpes] => '{ summon[Eq[String]] } :: summonAll[tpes] + case '[Int *: tpes] => '{ summon[Eq[Int]] } :: summonAll[tpes] + case '[tpe *: tpes] => derived[tpe] :: summonAll[tpes] + case '[EmptyTuple] => Nil + + given derived[T: Type](using q: Quotes): Expr[Eq[T]] = + import quotes.reflect.* + + val ev: Expr[Mirror.Of[T]] = Expr.summon[Mirror.Of[T]].get + + ev match + case '{ $m: Mirror.ProductOf[T] { type MirroredElemTypes = elementTypes }} => + val elemInstances = summonAll[elementTypes] + val eqProductBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => + elemInstances.zipWithIndex.foldLeft(Expr(true: Boolean)) { + case (acc, (elem, index)) => + val e1 = '{$x.asInstanceOf[Product].productElement(${Expr(index)})} + val e2 = '{$y.asInstanceOf[Product].productElement(${Expr(index)})} + + '{ $acc && $elem.asInstanceOf[Eq[Any]].eqv($e1, $e2) } + } + '{ eqProduct((x: T, y: T) => ${eqProductBody('x, 'y)}) } + + case '{ $m: Mirror.SumOf[T] { type MirroredElemTypes = elementTypes }} => + val elemInstances = summonAll[elementTypes] + val eqSumBody: (Expr[T], Expr[T]) => Expr[Boolean] = (x, y) => + val ordx = '{ $m.ordinal($x) } + val ordy = '{ $m.ordinal($y) } + + val elements = Expr.ofList(elemInstances) + '{ $ordx == $ordy && $elements($ordx).asInstanceOf[Eq[Any]].eqv($x, $y) } + + '{ eqSum((x: T, y: T) => ${eqSumBody('x, 'y)}) } + end derived +end Eq + +object Macro3: + extension [T](inline x: T) + inline def === (inline y: T)(using eq: Eq[T]): Boolean = eq.eqv(x, y) + + inline given eqGen[T]: Eq[T] = ${ Eq.derived[T] } +``` diff --git a/docs/_spec/TODOreference/contextual/derivation.md b/docs/_spec/TODOreference/contextual/derivation.md new file mode 100644 index 000000000000..bad47dcb0096 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/derivation.md @@ -0,0 +1,425 @@ +--- +layout: doc-page +title: "Type Class Derivation" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/derivation.html +--- + +Type class derivation is a way to automatically generate given instances for type classes which satisfy some simple +conditions. A type class in this sense is any trait or class with a type parameter determining the type being operated +on. Common examples are `Eq`, `Ordering`, or `Show`. For example, given the following `Tree` algebraic data type +(ADT), + +```scala +enum Tree[T] derives Eq, Ordering, Show: + case Branch(left: Tree[T], right: Tree[T]) + case Leaf(elem: T) +``` + +The `derives` clause generates the following given instances for the `Eq`, `Ordering` and `Show` type classes in the +companion object of `Tree`, + +```scala +given [T: Eq] : Eq[Tree[T]] = Eq.derived +given [T: Ordering] : Ordering[Tree[T]] = Ordering.derived +given [T: Show] : Show[Tree[T]] = Show.derived +``` + +We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Show` instances are _derived instances_. + +## Types supporting `derives` clauses + +All data types can have a `derives` clause. This document focuses primarily on data types which also have a given instance +of the `Mirror` type class available. + +`Mirror` type class instances provide information at the type level about the components and labelling of the type. +They also provide minimal term level infrastructure to allow higher level libraries to provide comprehensive +derivation support. + +Instances of the `Mirror` type class are generated automatically by the compiler +unconditionally for: +- enums and enum cases, +- case objects. + +Instances for `Mirror` are also generated conditionally for: +- case classes where the constructor is visible at the callsite (always true if the companion is not a case object) +- sealed classes and sealed traits where: + - there exists at least one child case, + - each child case is reachable from the parent's definition, + - if the sealed trait/class has no companion, then each child case is reachable from the callsite through the prefix of the type being mirrored, + - and where the compiler can generate a `Mirror` type class instance for each child case. + + +The `Mirror` type class definition is as follows: + +```scala +sealed trait Mirror: + + /** the type being mirrored */ + type MirroredType + + /** the type of the elements of the mirrored type */ + type MirroredElemTypes + + /** The mirrored *-type */ + type MirroredMonoType + + /** The name of the type */ + type MirroredLabel <: String + + /** The names of the elements of the type */ + type MirroredElemLabels <: Tuple + +object Mirror: + + /** The Mirror for a product type */ + trait Product extends Mirror: + + /** Create a new instance of type `T` with elements + * taken from product `p`. + */ + def fromProduct(p: scala.Product): MirroredMonoType + + trait Sum extends Mirror: + + /** The ordinal number of the case class of `x`. + * For enums, `ordinal(x) == x.ordinal` + */ + def ordinal(x: MirroredMonoType): Int + +end Mirror +``` + +Product types (i.e. case classes and objects, and enum cases) have mirrors which are subtypes of `Mirror.Product`. Sum +types (i.e. sealed class or traits with product children, and enums) have mirrors which are subtypes of `Mirror.Sum`. + +For the `Tree` ADT from above the following `Mirror` instances will be automatically provided by the compiler, + +```scala +// Mirror for Tree +new Mirror.Sum: + type MirroredType = Tree + type MirroredElemTypes[T] = (Branch[T], Leaf[T]) + type MirroredMonoType = Tree[_] + type MirroredLabel = "Tree" + type MirroredElemLabels = ("Branch", "Leaf") + + def ordinal(x: MirroredMonoType): Int = x match + case _: Branch[_] => 0 + case _: Leaf[_] => 1 + +// Mirror for Branch +new Mirror.Product: + type MirroredType = Branch + type MirroredElemTypes[T] = (Tree[T], Tree[T]) + type MirroredMonoType = Branch[_] + type MirroredLabel = "Branch" + type MirroredElemLabels = ("left", "right") + + def fromProduct(p: Product): MirroredMonoType = + new Branch(...) + +// Mirror for Leaf +new Mirror.Product: + type MirroredType = Leaf + type MirroredElemTypes[T] = Tuple1[T] + type MirroredMonoType = Leaf[_] + type MirroredLabel = "Leaf" + type MirroredElemLabels = Tuple1["elem"] + + def fromProduct(p: Product): MirroredMonoType = + new Leaf(...) +``` + +If a Mirror cannot be generated automatically for a given type, an error will appear explaining why it is neither a supported +sum type nor a product type. For example, if `A` is a trait that is not sealed, + +``` +No given instance of type deriving.Mirror.Of[A] was found for parameter x of method summon in object Predef. Failed to synthesize an instance of type deriving.Mirror.Of[A]: + * trait A is not a generic product because it is not a case class + * trait A is not a generic sum because it is not a sealed trait +``` + + +Note the following properties of `Mirror` types, + ++ Properties are encoded using types rather than terms. This means that they have no runtime footprint unless used and + also that they are a compile time feature for use with Scala 3's metaprogramming facilities. ++ There is no restriction against the mirrored type being a local or inner class. ++ The kinds of `MirroredType` and `MirroredElemTypes` match the kind of the data type the mirror is an instance for. + This allows `Mirror`s to support ADTs of all kinds. ++ There is no distinct representation type for sums or products (ie. there is no `HList` or `Coproduct` type as in + Scala 2 versions of Shapeless). Instead the collection of child types of a data type is represented by an ordinary, + possibly parameterized, tuple type. Scala 3's metaprogramming facilities can be used to work with these tuple types + as-is, and higher level libraries can be built on top of them. ++ For both product and sum types, the elements of `MirroredElemTypes` are arranged in definition order (i.e. `Branch[T]` + precedes `Leaf[T]` in `MirroredElemTypes` for `Tree` because `Branch` is defined before `Leaf` in the source file). + This means that `Mirror.Sum` differs in this respect from Shapeless's generic representation for ADTs in Scala 2, + where the constructors are ordered alphabetically by name. ++ The methods `ordinal` and `fromProduct` are defined in terms of `MirroredMonoType` which is the type of kind-`*` + which is obtained from `MirroredType` by wildcarding its type parameters. + +## Type classes supporting automatic deriving + +A trait or class can appear in a `derives` clause if its companion object defines a method named `derived`. The +signature and implementation of a `derived` method for a type class `TC[_]` are arbitrary but it is typically of the +following form, + +```scala +import scala.deriving.Mirror + +inline def derived[T](using Mirror.Of[T]): TC[T] = ... +``` + +That is, the `derived` method takes a context parameter of (some subtype of) type `Mirror` which defines the shape of +the deriving type `T`, and computes the type class implementation according to that shape. This is all that the +provider of an ADT with a `derives` clause has to know about the derivation of a type class instance. + +Note that `derived` methods may have context `Mirror` parameters indirectly (e.g. by having a context argument which in turn +has a context `Mirror` parameter, or not at all (e.g. they might use some completely different user-provided mechanism, for +instance using Scala 3 macros or runtime reflection). We expect that (direct or indirect) `Mirror` based implementations +will be the most common and that is what this document emphasises. + +Type class authors will most likely use higher level derivation or generic programming libraries to implement +`derived` methods. An example of how a `derived` method might be implemented using _only_ the low level facilities +described above and Scala 3's general metaprogramming features is provided below. It is not anticipated that type class +authors would normally implement a `derived` method in this way, however this walkthrough can be taken as a guide for +authors of the higher level derivation libraries that we expect typical type class authors will use (for a fully +worked out example of such a library, see [Shapeless 3](https://github.com/milessabin/shapeless/tree/shapeless-3)). + +## How to write a type class `derived` method using low level mechanisms + +The low-level method we will use to implement a type class `derived` method in this example exploits three new +type-level constructs in Scala 3: inline methods, inline matches, and implicit searches via `summonInline` or `summonFrom`. Given this definition of the +`Eq` type class, + +```scala +trait Eq[T]: + def eqv(x: T, y: T): Boolean +``` + +we need to implement a method `Eq.derived` on the companion object of `Eq` that produces a given instance for `Eq[T]` given +a `Mirror[T]`. Here is a possible implementation, + +```scala +import scala.deriving.Mirror + +inline given derived[T](using m: Mirror.Of[T]): Eq[T] = + val elemInstances = summonAll[m.MirroredElemTypes] // (1) + inline m match // (2) + case s: Mirror.SumOf[T] => eqSum(s, elemInstances) + case p: Mirror.ProductOf[T] => eqProduct(p, elemInstances) +``` + +Note that `derived` is defined as an `inline` given. This means that the method will be expanded at +call sites (for instance the compiler generated instance definitions in the companion objects of ADTs which have a +`derived Eq` clause), and also that it can be used recursively if necessary, to compute instances for children. + +The body of this method (1) first materializes the `Eq` instances for all the child types of type the instance is +being derived for. This is either all the branches of a sum type or all the fields of a product type. The +implementation of `summonAll` is `inline` and uses Scala 3's `summonInline` construct to collect the instances as a +`List`, + +```scala +inline def summonAll[T <: Tuple]: List[Eq[_]] = + inline erasedValue[T] match + case _: EmptyTuple => Nil + case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts] +``` + +with the instances for children in hand the `derived` method uses an `inline match` to dispatch to methods which can +construct instances for either sums or products (2). Note that because `derived` is `inline` the match will be +resolved at compile-time and only the left-hand side of the matching case will be inlined into the generated code with +types refined as revealed by the match. + +In the sum case, `eqSum`, we use the runtime `ordinal` values of the arguments to `eqv` to first check if the two +values are of the same subtype of the ADT (3) and then, if they are, to further test for equality based on the `Eq` +instance for the appropriate ADT subtype using the auxiliary method `check` (4). + +```scala +import scala.deriving.Mirror + +def eqSum[T](s: Mirror.SumOf[T], elems: List[Eq[_]]): Eq[T] = + new Eq[T]: + def eqv(x: T, y: T): Boolean = + val ordx = s.ordinal(x) // (3) + (s.ordinal(y) == ordx) && check(elems(ordx))(x, y) // (4) +``` + +In the product case, `eqProduct` we test the runtime values of the arguments to `eqv` for equality as products based +on the `Eq` instances for the fields of the data type (5), + +```scala +import scala.deriving.Mirror + +def eqProduct[T](p: Mirror.ProductOf[T], elems: List[Eq[_]]): Eq[T] = + new Eq[T]: + def eqv(x: T, y: T): Boolean = + iterator(x).zip(iterator(y)).zip(elems.iterator).forall { // (5) + case ((x, y), elem) => check(elem)(x, y) + } +``` + +Pulling this all together we have the following complete implementation, + +```scala +import scala.deriving.* +import scala.compiletime.{erasedValue, summonInline} + +inline def summonAll[T <: Tuple]: List[Eq[_]] = + inline erasedValue[T] match + case _: EmptyTuple => Nil + case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts] + +trait Eq[T]: + def eqv(x: T, y: T): Boolean + +object Eq: + given Eq[Int] with + def eqv(x: Int, y: Int) = x == y + + def check(elem: Eq[_])(x: Any, y: Any): Boolean = + elem.asInstanceOf[Eq[Any]].eqv(x, y) + + def iterator[T](p: T) = p.asInstanceOf[Product].productIterator + + def eqSum[T](s: Mirror.SumOf[T], elems: => List[Eq[_]]): Eq[T] = + new Eq[T]: + def eqv(x: T, y: T): Boolean = + val ordx = s.ordinal(x) + (s.ordinal(y) == ordx) && check(elems(ordx))(x, y) + + def eqProduct[T](p: Mirror.ProductOf[T], elems: => List[Eq[_]]): Eq[T] = + new Eq[T]: + def eqv(x: T, y: T): Boolean = + iterator(x).zip(iterator(y)).zip(elems.iterator).forall { + case ((x, y), elem) => check(elem)(x, y) + } + + inline given derived[T](using m: Mirror.Of[T]): Eq[T] = + lazy val elemInstances = summonAll[m.MirroredElemTypes] + inline m match + case s: Mirror.SumOf[T] => eqSum(s, elemInstances) + case p: Mirror.ProductOf[T] => eqProduct(p, elemInstances) +end Eq +``` + +we can test this relative to a simple ADT like so, + +```scala +enum Opt[+T] derives Eq: + case Sm(t: T) + case Nn + +@main def test(): Unit = + import Opt.* + val eqoi = summon[Eq[Opt[Int]]] + assert(eqoi.eqv(Sm(23), Sm(23))) + assert(!eqoi.eqv(Sm(23), Sm(13))) + assert(!eqoi.eqv(Sm(23), Nn)) +``` + +In this case the code that is generated by the inline expansion for the derived `Eq` instance for `Opt` looks like the +following, after a little polishing, + +```scala +given derived$Eq[T](using eqT: Eq[T]): Eq[Opt[T]] = + eqSum( + summon[Mirror[Opt[T]]], + List( + eqProduct(summon[Mirror[Sm[T]]], List(summon[Eq[T]])), + eqProduct(summon[Mirror[Nn.type]], Nil) + ) + ) +``` + +Alternative approaches can be taken to the way that `derived` methods can be defined. For example, more aggressively +inlined variants using Scala 3 macros, whilst being more involved for type class authors to write than the example +above, can produce code for type classes like `Eq` which eliminate all the abstraction artefacts (eg. the `Lists` of +child instances in the above) and generate code which is indistinguishable from what a programmer might write by hand. +As a third example, using a higher level library such as Shapeless the type class author could define an equivalent +`derived` method as, + +```scala +given eqSum[A](using inst: => K0.CoproductInstances[Eq, A]): Eq[A] with + def eqv(x: A, y: A): Boolean = inst.fold2(x, y)(false)( + [t] => (eqt: Eq[t], t0: t, t1: t) => eqt.eqv(t0, t1) + ) + +given eqProduct[A](using inst: K0.ProductInstances[Eq, A]): Eq[A] with + def eqv(x: A, y: A): Boolean = inst.foldLeft2(x, y)(true: Boolean)( + [t] => (acc: Boolean, eqt: Eq[t], t0: t, t1: t) => + Complete(!eqt.eqv(t0, t1))(false)(true) + ) + +inline def derived[A](using gen: K0.Generic[A]): Eq[A] = + gen.derive(eqProduct, eqSum) +``` + +The framework described here enables all three of these approaches without mandating any of them. + +For a brief discussion on how to use macros to write a type class `derived` +method please read more at [How to write a type class `derived` method using macros](./derivation-macro.md). + +## Deriving instances elsewhere + +Sometimes one would like to derive a type class instance for an ADT after the ADT is defined, without being able to +change the code of the ADT itself. To do this, simply define an instance using the `derived` method of the type class +as right-hand side. E.g, to implement `Ordering` for `Option` define, + +```scala +given [T: Ordering]: Ordering[Option[T]] = Ordering.derived +``` + +Assuming the `Ordering.derived` method has a context parameter of type `Mirror[T]` it will be satisfied by the +compiler generated `Mirror` instance for `Option` and the derivation of the instance will be expanded on the right +hand side of this definition in the same way as an instance defined in ADT companion objects. + +## Syntax + +``` +Template ::= InheritClauses [TemplateBody] +EnumDef ::= id ClassConstr InheritClauses EnumBody +InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] +ConstrApps ::= ConstrApp {‘with’ ConstrApp} + | ConstrApp {‘,’ ConstrApp} +``` + +**Note:** To align `extends` clauses and `derives` clauses, Scala 3 also allows multiple +extended types to be separated by commas. So the following is now legal: + +```scala +class A extends B, C { ... } +``` + +It is equivalent to the old form + +```scala +class A extends B with C { ... } +``` + +## Discussion + +This type class derivation framework is intentionally very small and low-level. There are essentially two pieces of +infrastructure in compiler-generated `Mirror` instances, + ++ type members encoding properties of the mirrored types. ++ a minimal value level mechanism for working generically with terms of the mirrored types. + +The `Mirror` infrastructure can be seen as an extension of the existing `Product` infrastructure for case classes: +typically `Mirror` types will be implemented by the ADTs companion object, hence the type members and the `ordinal` or +`fromProduct` methods will be members of that object. The primary motivation for this design decision, and the +decision to encode properties via types rather than terms was to keep the bytecode and runtime footprint of the +feature small enough to make it possible to provide `Mirror` instances _unconditionally_. + +Whilst `Mirrors` encode properties precisely via type members, the value level `ordinal` and `fromProduct` are +somewhat weakly typed (because they are defined in terms of `MirroredMonoType`) just like the members of `Product`. +This means that code for generic type classes has to ensure that type exploration and value selection proceed in +lockstep and it has to assert this conformance in some places using casts. If generic type classes are correctly +written these casts will never fail. + +As mentioned, however, the compiler-provided mechanism is intentionally very low level and it is anticipated that +higher level type class derivation and generic programming libraries will build on this and Scala 3's other +metaprogramming facilities to hide these low-level details from type class authors and general users. Type class +derivation in the style of both Shapeless and Magnolia are possible (a prototype of Shapeless 3, which combines +aspects of both Shapeless 2 and Magnolia has been developed alongside this language feature) as is a more aggressively +inlined style, supported by Scala 3's new quote/splice macro and inlining facilities. diff --git a/docs/_spec/TODOreference/contextual/extension-methods.md b/docs/_spec/TODOreference/contextual/extension-methods.md new file mode 100644 index 000000000000..d23cadf513d7 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/extension-methods.md @@ -0,0 +1,306 @@ +--- +layout: doc-page +title: "Extension Methods" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/extension-methods.html +--- + +Extension methods allow one to add methods to a type after the type is defined. Example: + +```scala +case class Circle(x: Double, y: Double, radius: Double) + +extension (c: Circle) + def circumference: Double = c.radius * math.Pi * 2 +``` + +Like regular methods, extension methods can be invoked with infix `.`: + +```scala +val circle = Circle(0, 0, 1) +circle.circumference +``` + +## Translation of Extension Methods + +An extension method translates to a specially labelled method that takes the leading parameter section as its first argument list. The label, expressed +as `` here, is compiler-internal. So, the definition of `circumference` above translates to the following method, and can also be invoked as such: + +``` + def circumference(c: Circle): Double = c.radius * math.Pi * 2 + +assert(circle.circumference == circumference(circle)) +``` + +## Operators + +The extension method syntax can also be used to define operators. Examples: + +```scala +extension (x: String) + def < (y: String): Boolean = ... +extension (x: Elem) + def +: (xs: Seq[Elem]): Seq[Elem] = ... +extension (x: Number) + infix def min (y: Number): Number = ... + +"ab" < "c" +1 +: List(2, 3) +x min 3 +``` + +The three definitions above translate to + +``` + def < (x: String)(y: String): Boolean = ... + def +: (xs: Seq[Elem])(x: Elem): Seq[Elem] = ... + infix def min(x: Number)(y: Number): Number = ... +``` + +Note the swap of the two parameters `x` and `xs` when translating +the right-associative operator `+:` to an extension method. This is analogous +to the implementation of right binding operators as normal methods. The Scala +compiler preprocesses an infix operation `x +: xs` to `xs.+:(x)`, so the extension +method ends up being applied to the sequence as first argument (in other words, the +two swaps cancel each other out). See [here for details](./right-associative-extension-methods.md). + +## Generic Extensions + +It is also possible to extend generic types by adding type parameters to an extension. For instance: + +```scala +extension [T](xs: List[T]) + def second = xs.tail.head + +extension [T: Numeric](x: T) + def + (y: T): T = summon[Numeric[T]].plus(x, y) +``` + +Type parameters on extensions can also be combined with type parameters on the methods +themselves: + +```scala +extension [T](xs: List[T]) + def sumBy[U: Numeric](f: T => U): U = ... +``` + +Type arguments matching method type parameters are passed as usual: + +```scala +List("a", "bb", "ccc").sumBy[Int](_.length) +``` + +By contrast, type arguments matching type parameters following `extension` can be passed +only if the method is referenced as a non-extension method: + +```scala +sumBy[String](List("a", "bb", "ccc"))(_.length) +``` + +Or, when passing both type arguments: + +```scala +sumBy[String](List("a", "bb", "ccc"))[Int](_.length) +``` + +Extensions can also take using clauses. For instance, the `+` extension above could equivalently be written with a using clause: + +```scala +extension [T](x: T)(using n: Numeric[T]) + def + (y: T): T = n.plus(x, y) +``` + +## Collective Extensions + +Sometimes, one wants to define several extension methods that share the same +left-hand parameter type. In this case one can "pull out" the common parameters into +a single extension and enclose all methods in braces or an indented region. +Example: + +```scala +extension (ss: Seq[String]) + + def longestStrings: Seq[String] = + val maxLength = ss.map(_.length).max + ss.filter(_.length == maxLength) + + def longestString: String = longestStrings.head +``` + +The same can be written with braces as follows (note that indented regions can still be used inside braces): + +```scala +extension (ss: Seq[String]) { + + def longestStrings: Seq[String] = { + val maxLength = ss.map(_.length).max + ss.filter(_.length == maxLength) + } + + def longestString: String = longestStrings.head +} +``` + +Note the right-hand side of `longestString`: it calls `longestStrings` directly, implicitly +assuming the common extended value `ss` as receiver. + +Collective extensions like these are a shorthand for individual extensions +where each method is defined separately. For instance, the first extension above expands to: + +```scala +extension (ss: Seq[String]) + def longestStrings: Seq[String] = + val maxLength = ss.map(_.length).max + ss.filter(_.length == maxLength) + +extension (ss: Seq[String]) + def longestString: String = ss.longestStrings.head +``` + +Collective extensions also can take type parameters and have using clauses. Example: + +```scala +extension [T](xs: List[T])(using Ordering[T]) + def smallest(n: Int): List[T] = xs.sorted.take(n) + def smallestIndices(n: Int): List[Int] = + val limit = smallest(n).max + xs.zipWithIndex.collect { case (x, i) if x <= limit => i } +``` + +## Translation of Calls to Extension Methods + +To convert a reference to an extension method, the compiler has to know about the extension +method. We say in this case that the extension method is _applicable_ at the point of reference. +There are four possible ways for an extension method to be applicable: + + 1. The extension method is visible under a simple name, by being defined or inherited or imported in a scope enclosing the reference. + 2. The extension method is a member of some given + instance that is visible at the point of the reference. + 3. The reference is of the form `r.m` and the extension method + is defined in the implicit scope of the type of `r`. + 4. The reference is of the form `r.m` and the extension method + is defined in some given instance in the implicit scope of the type of `r`. + +Here is an example for the first rule: + +```scala +trait IntOps: + extension (i: Int) def isZero: Boolean = i == 0 + + extension (i: Int) def safeMod(x: Int): Option[Int] = + // extension method defined in same scope IntOps + if x.isZero then None + else Some(i % x) + +object IntOpsEx extends IntOps: + extension (i: Int) def safeDiv(x: Int): Option[Int] = + // extension method brought into scope via inheritance from IntOps + if x.isZero then None + else Some(i / x) + +trait SafeDiv: + import IntOpsEx.* // brings safeDiv and safeMod into scope + + extension (i: Int) def divide(d: Int): Option[(Int, Int)] = + // extension methods imported and thus in scope + (i.safeDiv(d), i.safeMod(d)) match + case (Some(d), Some(r)) => Some((d, r)) + case _ => None +``` + +By the second rule, an extension method can be made available by defining a given instance containing it, like this: + +```scala +given ops1: IntOps() // brings safeMod into scope + +1.safeMod(2) +``` + +By the third and fourth rule, an extension method is available if it is in the implicit scope of the receiver type or in a given instance in that scope. Example: + +```scala +class List[T]: + ... +object List: + ... + extension [T](xs: List[List[T]]) + def flatten: List[T] = xs.foldLeft(List.empty[T])(_ ++ _) + + given [T: Ordering]: Ordering[List[T]] with + extension (xs: List[T]) + def < (ys: List[T]): Boolean = ... +end List + +// extension method available since it is in the implicit scope +// of List[List[Int]] +List(List(1, 2), List(3, 4)).flatten + +// extension method available since it is in the given Ordering[List[T]], +// which is itself in the implicit scope of List[Int] +List(1, 2) < List(3) +``` + +The precise rules for resolving a selection to an extension method are as follows. + +Assume a selection `e.m[Ts]` where `m` is not a member of `e`, where the type arguments `[Ts]` are optional, and where `T` is the expected type. +The following two rewritings are tried in order: + + 1. The selection is rewritten to `m[Ts](e)`. + 2. If the first rewriting does not typecheck with expected type `T`, + and there is an extension method `m` in some eligible object `o`, the selection is rewritten to `o.m[Ts](e)`. An object `o` is _eligible_ if + + - `o` forms part of the implicit scope of `T`, or + - `o` is a given instance that is visible at the point of the application, or + - `o` is a given instance in the implicit scope of `T`. + + This second rewriting is attempted at the time where the compiler also tries an implicit conversion + from `T` to a type containing `m`. If there is more than one way of rewriting, an ambiguity error results. + +An extension method can also be referenced using a simple identifier without a preceding expression. If an identifier `g` appears in the body of an extension method `f` and refers to an extension method `g` that is defined in the same collective extension + +```scala +extension (x: T) + def f ... = ... g ... + def g ... +``` + +the identifier is rewritten to `x.g`. This is also the case if `f` and `g` are the same method. Example: + +```scala +extension (s: String) + def position(ch: Char, n: Int): Int = + if n < s.length && s(n) != ch then position(ch, n + 1) + else n +``` + +The recursive call `position(ch, n + 1)` expands to `s.position(ch, n + 1)` in this case. The whole extension method rewrites to + +```scala +def position(s: String)(ch: Char, n: Int): Int = + if n < s.length && s(n) != ch then position(s)(ch, n + 1) + else n +``` + +## Syntax + +Here are the syntax changes for extension methods and collective extensions relative +to the [current syntax](../syntax.md). + +``` +BlockStat ::= ... | Extension +TemplateStat ::= ... | Extension +TopStat ::= ... | Extension +Extension ::= ‘extension’ [DefTypeParamClause] {UsingParamClause} + ‘(’ DefParam ‘)’ {UsingParamClause} ExtMethods +ExtMethods ::= ExtMethod | [nl] <<< ExtMethod {semi ExtMethod} >>> +ExtMethod ::= {Annotation [nl]} {Modifier} ‘def’ DefDef +``` + +In the above the notation `<<< ts >>>` in the production rule `ExtMethods` is defined as follows : + +``` +<<< ts >>> ::= ‘{’ ts ‘}’ | indent ts outdent +``` + +`extension` is a soft keyword. It is recognized as a keyword only if it appears +at the start of a statement and is followed by `[` or `(`. In all other cases +it is treated as an identifier. diff --git a/docs/_spec/TODOreference/contextual/given-imports.md b/docs/_spec/TODOreference/contextual/given-imports.md new file mode 100644 index 000000000000..6a55368979b1 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/given-imports.md @@ -0,0 +1,117 @@ +--- +layout: doc-page +title: "Importing Givens" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/given-imports.html +--- + +A special form of import wildcard selector is used to import given instances. Example: + +```scala +object A: + class TC + given tc: TC = ??? + def f(using TC) = ??? + +object B: + import A.* + import A.given + ... +``` + +In the code above, the `import A.*` clause in object `B` imports all members +of `A` _except_ the given instance `tc`. Conversely, the second import `import A.given` will import _only_ that given instance. +The two import clauses can also be merged into one: + +```scala +object B: + import A.{given, *} + ... +``` + +Generally, a normal wildcard selector `*` brings all definitions other than givens or extensions into scope +whereas a `given` selector brings all givens (including those resulting from extensions) into scope. + +There are two main benefits arising from these rules: + +- It is made clearer where givens in scope are coming from. + In particular, it is not possible to hide imported givens in a long list of regular wildcard imports. +- It enables importing all givens + without importing anything else. This is particularly important since givens + can be anonymous, so the usual recourse of using named imports is not + practical. + +## Importing By Type + +Since givens can be anonymous it is not always practical to import them by their name, and wildcard imports are typically used instead. By-type imports provide a more specific alternative to wildcard imports, which makes it clearer what is imported. Example: + +```scala +import A.given TC +``` + +This imports any given in `A` that has a type which conforms to `TC`. Importing givens of several types `T1,...,Tn` +is expressed by multiple `given` selectors. + +```scala +import A.{given T1, ..., given Tn} +``` + +Importing all given instances of a parameterized type is expressed by wildcard arguments. +For instance, assuming the object + +```scala +object Instances: + given intOrd: Ordering[Int] = ... + given listOrd[T: Ordering]: Ordering[List[T]] = ... + given ec: ExecutionContext = ... + given im: Monoid[Int] = ... +``` + +the import clause + +```scala +import Instances.{given Ordering[?], given ExecutionContext} +``` + +would import the `intOrd`, `listOrd`, and `ec` instances but leave out the `im` instance, since it fits none of the specified bounds. + +By-type imports can be mixed with by-name imports. If both are present in an import clause, by-type imports come last. For instance, the import clause + +```scala +import Instances.{im, given Ordering[?]} +``` + +would import `im`, `intOrd`, and `listOrd` but leave out `ec`. + +## Migration + +The rules for imports stated above have the consequence that a library +would have to migrate in lockstep with all its users from old style implicits and +normal imports to givens and given imports. + +The following modifications avoid this hurdle to migration. + + 1. A `given` import selector also brings old style implicits into scope. So, in Scala 3.0 + an old-style implicit definition can be brought into scope either by a `*` or a `given` wildcard selector. + + 2. In Scala 3.1, old-style implicits accessed through a `*` wildcard import will give a deprecation warning. + + 3. In some version after 3.1, old-style implicits accessed through a `*` wildcard import will give a compiler error. + +These rules mean that library users can use `given` selectors to access old-style implicits in Scala 3.0, +and will be gently nudged and then forced to do so in later versions. Libraries can then switch to +given instances once their user base has migrated. + +## Syntax + +``` +Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} +Export ::= ‘export’ ImportExpr {‘,’ ImportExpr} +ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec +ImportSpec ::= NamedSelector + | WildcardSelector + | ‘{’ ImportSelectors) ‘}’ +NamedSelector ::= id [‘as’ (id | ‘_’)] +WildCardSelector ::= ‘*' | ‘given’ [InfixType] +ImportSelectors ::= NamedSelector [‘,’ ImportSelectors] + | WildCardSelector {‘,’ WildCardSelector} +``` diff --git a/docs/_spec/TODOreference/contextual/givens.md b/docs/_spec/TODOreference/contextual/givens.md new file mode 100644 index 000000000000..411d50ba63ea --- /dev/null +++ b/docs/_spec/TODOreference/contextual/givens.md @@ -0,0 +1,193 @@ +--- +layout: doc-page +title: "Given Instances" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/givens.html +--- + +Given instances (or, simply, "givens") define "canonical" values of certain types +that serve for synthesizing arguments to [context parameters](./using-clauses.md). Example: + +```scala +trait Ord[T]: + def compare(x: T, y: T): Int + extension (x: T) def < (y: T) = compare(x, y) < 0 + extension (x: T) def > (y: T) = compare(x, y) > 0 + +given intOrd: Ord[Int] with + def compare(x: Int, y: Int) = + if x < y then -1 else if x > y then +1 else 0 + +given listOrd[T](using ord: Ord[T]): Ord[List[T]] with + + def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match + case (Nil, Nil) => 0 + case (Nil, _) => -1 + case (_, Nil) => +1 + case (x :: xs1, y :: ys1) => + val fst = ord.compare(x, y) + if fst != 0 then fst else compare(xs1, ys1) + +``` + +This code defines a trait `Ord` with two given instances. `intOrd` defines +a given for the type `Ord[Int]` whereas `listOrd[T]` defines givens +for `Ord[List[T]]` for all types `T` that come with a given instance for `Ord[T]` +themselves. The `using` clause in `listOrd` defines a condition: There must be a +given of type `Ord[T]` for a given of type `Ord[List[T]]` to exist. +Such conditions are expanded by the compiler to [context parameters](./using-clauses.md). + +## Anonymous Givens + +The name of a given can be left out. So the definitions +of the last section can also be expressed like this: + +```scala +given Ord[Int] with + ... +given [T](using Ord[T]): Ord[List[T]] with + ... +``` + +If the name of a given is missing, the compiler will synthesize a name from +the implemented type(s). + +**Note** The name synthesized by the compiler is chosen to be readable and reasonably concise. For instance, the two instances above would get the names: + +```scala +given_Ord_Int +given_Ord_List +``` + +The precise rules for synthesizing names are found [here](./relationship-implicits.html#anonymous-given-instances). These rules do not guarantee absence of name conflicts between +given instances of types that are "too similar". To avoid conflicts one can +use named instances. + +**Note** To ensure robust binary compatibility, publicly available libraries should prefer named instances. + +## Alias Givens + +An alias can be used to define a given instance that is equal to some expression. Example: + +```scala +given global: ExecutionContext = ForkJoinPool() +``` + +This creates a given `global` of type `ExecutionContext` that resolves to the right +hand side `ForkJoinPool()`. +The first time `global` is accessed, a new `ForkJoinPool` is created, which is then +returned for this and all subsequent accesses to `global`. This operation is thread-safe. + +Alias givens can be anonymous as well, e.g. + +```scala +given Position = enclosingTree.position +given (using config: Config): Factory = MemoizingFactory(config) +``` + +An alias given can have type parameters and context parameters just like any other given, +but it can only implement a single type. + +## Given Macros + +Given aliases can have the `inline` and `transparent` modifiers. +Example: + +```scala +transparent inline given mkAnnotations[A, T]: Annotations[A, T] = ${ + // code producing a value of a subtype of Annotations +} +``` + +Since `mkAnnotations` is `transparent`, the type of an application is the type of its right-hand side, which can be a proper subtype of the declared result type `Annotations[A, T]`. + +Given instances can have the `inline` but not `transparent` modifiers as their type is already known from the signature. +Example: + +```scala +trait Show[T] { + inline def show(x: T): String +} + +inline given Show[Foo] with { + /*transparent*/ inline def show(x: Foo): String = ${ ... } +} + +def app = + // inlines `show` method call and removes the call to `given Show[Foo]` + summon[Show[Foo]].show(foo) +``` +Note that the inline methods within the given instances may be `transparent`. + +The inlining of given instances will not inline/duplicate the implementation of the given, it will just inline the instantiation of that instance. +This is used to help dead code elimination of the given instances that are not used after inlining. + + +## Pattern-Bound Given Instances + +Given instances can also appear in patterns. Example: + +```scala +for given Context <- applicationContexts do + +pair match + case (ctx @ given Context, y) => ... +``` + +In the first fragment above, anonymous given instances for class `Context` are established by enumerating over `applicationContexts`. In the second fragment, a given `Context` +instance named `ctx` is established by matching against the first half of the `pair` selector. + +In each case, a pattern-bound given instance consists of `given` and a type `T`. The pattern matches exactly the same selectors as the type ascription pattern `_: T`. + +## Negated Givens + +Scala 2's somewhat puzzling behavior with respect to ambiguity has been exploited to implement the analogue of a "negated" search in implicit resolution, +where a query Q1 fails if some other query Q2 succeeds and Q1 succeeds if Q2 fails. With the new cleaned up behavior these techniques no longer work. +But the new special type [`scala.util.NotGiven`](https://scala-lang.org/api/3.x/scala/util/NotGiven.html) now implements negation directly. + +For any query type `Q`, [`NotGiven[Q]`](https://scala-lang.org/api/3.x/scala/util/NotGiven.html) succeeds if and only if the implicit +search for `Q` fails, for example: + +```scala +import scala.util.NotGiven + +trait Tagged[A] + +case class Foo[A](value: Boolean) +object Foo: + given fooTagged[A](using Tagged[A]): Foo[A] = Foo(true) + given fooNotTagged[A](using NotGiven[Tagged[A]]): Foo[A] = Foo(false) + +@main def test(): Unit = + given Tagged[Int]() + assert(summon[Foo[Int]].value) // fooTagged is found + assert(!summon[Foo[String]].value) // fooNotTagged is found +``` + +## Given Instance Initialization + +A given instance without type or context parameters is initialized on-demand, the first +time it is accessed. If a given has type or context parameters, a fresh instance +is created for each reference. + +## Syntax + +Here is the syntax for given instances: + +``` +TmplDef ::= ... + | ‘given’ GivenDef +GivenDef ::= [GivenSig] StructuralInstance + | [GivenSig] AnnotType ‘=’ Expr + | [GivenSig] AnnotType +GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘:’ +StructuralInstance ::= ConstrApp {‘with’ ConstrApp} ‘with’ TemplateBody +``` + +A given instance starts with the reserved word `given` and an optional _signature_. The signature +defines a name and/or parameters for the instance. It is followed by `:`. There are three kinds +of given instances: + +- A _structural instance_ contains one or more types or constructor applications, + followed by `with` and a template body that contains member definitions of the instance. +- An _alias instance_ contains a type, followed by `=` and a right-hand side expression. +- An _abstract instance_ contains just the type, which is not followed by anything. diff --git a/docs/_spec/TODOreference/contextual/multiversal-equality.md b/docs/_spec/TODOreference/contextual/multiversal-equality.md new file mode 100644 index 000000000000..e9a81b95f472 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/multiversal-equality.md @@ -0,0 +1,227 @@ +--- +layout: doc-page +title: "Multiversal Equality" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/multiversal-equality.html +--- + +Previously, Scala had universal equality: Two values of any types +could be compared with each other with `==` and `!=`. This came from +the fact that `==` and `!=` are implemented in terms of Java's +`equals` method, which can also compare values of any two reference +types. + +Universal equality is convenient. But it is also dangerous since it +undermines type safety. For instance, let's assume one is left after some refactoring +with an erroneous program where a value `y` has type `S` instead of the correct type `T`. + +```scala +val x = ... // of type T +val y = ... // of type S, but should be T +x == y // typechecks, will always yield false +``` + +If `y` gets compared to other values of type `T`, +the program will still typecheck, since values of all types can be compared with each other. +But it will probably give unexpected results and fail at runtime. + +Multiversal equality is an opt-in way to make universal equality safer. +It uses a binary type class [`scala.CanEqual`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/CanEqual.scala) +to indicate that values of two given types can be compared with each other. +The example above would not typecheck if `S` or `T` was a class +that derives `CanEqual`, e.g. + +```scala +class T derives CanEqual +``` + +Alternatively, one can also provide a `CanEqual` given instance directly, like this: + +```scala +given CanEqual[T, T] = CanEqual.derived +``` + +This definition effectively says that values of type `T` can (only) be +compared to other values of type `T` when using `==` or `!=`. The definition +affects type checking but it has no significance for runtime +behavior, since `==` always maps to `equals` and `!=` always maps to +the negation of `equals`. The right-hand side `CanEqual.derived` of the definition +is a value that has any `CanEqual` instance as its type. Here is the definition of class +`CanEqual` and its companion object: + +```scala +package scala +import annotation.implicitNotFound + +@implicitNotFound("Values of types ${L} and ${R} cannot be compared with == or !=") +sealed trait CanEqual[-L, -R] + +object CanEqual: + object derived extends CanEqual[Any, Any] +``` + +One can have several `CanEqual` given instances for a type. For example, the four +definitions below make values of type `A` and type `B` comparable with +each other, but not comparable to anything else: + +```scala +given CanEqual[A, A] = CanEqual.derived +given CanEqual[B, B] = CanEqual.derived +given CanEqual[A, B] = CanEqual.derived +given CanEqual[B, A] = CanEqual.derived +``` + +The [`scala.CanEqual`](https://github.com/lampepfl/dotty/blob/main/library/src/scala/CanEqual.scala) +object defines a number of `CanEqual` given instances that together +define a rule book for what standard types can be compared (more details below). + +There is also a "fallback" instance named `canEqualAny` that allows comparisons +over all types that do not themselves have a `CanEqual` given. `canEqualAny` is defined as follows: + +```scala +def canEqualAny[L, R]: CanEqual[L, R] = CanEqual.derived +``` + +Even though `canEqualAny` is not declared as `given`, the compiler will still +construct an `canEqualAny` instance as answer to an implicit search for the +type `CanEqual[L, R]`, unless `L` or `R` have `CanEqual` instances +defined on them, or the language feature `strictEquality` is enabled. + +The primary motivation for having `canEqualAny` is backwards compatibility. +If this is of no concern, one can disable `canEqualAny` by enabling the language +feature `strictEquality`. As for all language features this can be either +done with an import + +```scala +import scala.language.strictEquality +``` +or with a command line option `-language:strictEquality`. + +## Deriving CanEqual Instances + +Instead of defining `CanEqual` instances directly, it is often more convenient to derive them. Example: + +```scala +class Box[T](x: T) derives CanEqual +``` + +By the usual rules of [type class derivation](./derivation.md), +this generates the following `CanEqual` instance in the companion object of `Box`: + +```scala +given [T, U](using CanEqual[T, U]): CanEqual[Box[T], Box[U]] = + CanEqual.derived +``` + +That is, two boxes are comparable with `==` or `!=` if their elements are. Examples: + +```scala +new Box(1) == new Box(1L) // ok since there is an instance for `CanEqual[Int, Long]` +new Box(1) == new Box("a") // error: can't compare +new Box(1) == 1 // error: can't compare +``` + +## Precise Rules for Equality Checking + +The precise rules for equality checking are as follows. + +If the `strictEquality` feature is enabled then +a comparison using `x == y` or `x != y` between values `x: T` and `y: U` +is legal if there is a `given` of type `CanEqual[T, U]`. + +In the default case where the `strictEquality` feature is not enabled the comparison is +also legal if + + 1. `T` and `U` are the same, or + 2. one of `T`, `U` is a subtype of the _lifted_ version of the other type, or + 3. neither `T` nor `U` have a _reflexive_ `CanEqual` instance. + +Explanations: + + - _lifting_ a type `S` means replacing all references to abstract types + in covariant positions of `S` by their upper bound, and replacing + all refinement types in covariant positions of `S` by their parent. + - a type `T` has a _reflexive_ `CanEqual` instance if the implicit search for `CanEqual[T, T]` + succeeds. + +## Predefined CanEqual Instances + +The `CanEqual` object defines instances for comparing + - the primitive types `Byte`, `Short`, `Char`, `Int`, `Long`, `Float`, `Double`, `Boolean`, and `Unit`, + - `java.lang.Number`, `java.lang.Boolean`, and `java.lang.Character`, + - `scala.collection.Seq`, and `scala.collection.Set`. + +Instances are defined so that every one of these types has a _reflexive_ `CanEqual` instance, and the following holds: + + - Primitive numeric types can be compared with each other. + - Primitive numeric types can be compared with subtypes of `java.lang.Number` (and _vice versa_). + - `Boolean` can be compared with `java.lang.Boolean` (and _vice versa_). + - `Char` can be compared with `java.lang.Character` (and _vice versa_). + - Two sequences (of arbitrary subtypes of `scala.collection.Seq`) can be compared + with each other if their element types can be compared. The two sequence types + need not be the same. + - Two sets (of arbitrary subtypes of `scala.collection.Set`) can be compared + with each other if their element types can be compared. The two set types + need not be the same. + - Any subtype of `AnyRef` can be compared with `Null` (and _vice versa_). + +## Why Two Type Parameters? + +One particular feature of the `CanEqual` type is that it takes _two_ type parameters, representing the types of the two items to be compared. By contrast, conventional +implementations of an equality type class take only a single type parameter which represents the common type of _both_ operands. +One type parameter is simpler than two, so why go through the additional complication? The reason has to do with the fact that, rather than coming up with a type class where no operation existed before, +we are dealing with a refinement of pre-existing, universal equality. It is best illustrated through an example. + +Say you want to come up with a safe version of the `contains` method on `List[T]`. The original definition of `contains` in the standard library was: +```scala +class List[+T]: + ... + def contains(x: Any): Boolean +``` +That uses universal equality in an unsafe way since it permits arguments of any type to be compared with the list's elements. The "obvious" alternative definition +```scala + def contains(x: T): Boolean +``` +does not work, since it refers to the covariant parameter `T` in a nonvariant context. The only variance-correct way to use the type parameter `T` in `contains` is as a lower bound: +```scala + def contains[U >: T](x: U): Boolean +``` +This generic version of `contains` is the one used in the current (Scala 2.13) version of `List`. +It looks different but it admits exactly the same applications as the `contains(x: Any)` definition we started with. +However, we can make it more useful (i.e. restrictive) by adding a `CanEqual` parameter: +```scala + def contains[U >: T](x: U)(using CanEqual[T, U]): Boolean // (1) +``` +This version of `contains` is equality-safe! More precisely, given +`x: T`, `xs: List[T]` and `y: U`, then `xs.contains(y)` is type-correct if and only if +`x == y` is type-correct. + +Unfortunately, the crucial ability to "lift" equality type checking from simple equality and pattern matching to arbitrary user-defined operations gets lost if we restrict ourselves to an equality class with a single type parameter. Consider the following signature of `contains` with a hypothetical `CanEqual1[T]` type class: +```scala + def contains[U >: T](x: U)(using CanEqual1[U]): Boolean // (2) +``` +This version could be applied just as widely as the original `contains(x: Any)` method, +since the `CanEqual1[Any]` fallback is always available! So we have gained nothing. What got lost in the transition to a single parameter type class was the original rule that `CanEqual[A, B]` is available only if neither `A` nor `B` have a reflexive `CanEqual` instance. That rule simply cannot be expressed if there is a single type parameter for `CanEqual`. + +The situation is different under `-language:strictEquality`. In that case, +the `CanEqual[Any, Any]` or `CanEqual1[Any]` instances would never be available, and the +single and two-parameter versions would indeed coincide for most practical purposes. + +But assuming `-language:strictEquality` immediately and everywhere poses migration problems which might well be unsurmountable. Consider again `contains`, which is in the standard library. Parameterizing it with the `CanEqual` type class as in (1) is an immediate win since it rules out non-sensical applications while still allowing all sensible ones. +So it can be done almost at any time, modulo binary compatibility concerns. +On the other hand, parameterizing `contains` with `CanEqual1` as in (2) would make `contains` +unusable for all types that have not yet declared a `CanEqual1` instance, including all +types coming from Java. This is clearly unacceptable. It would lead to a situation where, +rather than migrating existing libraries to use safe equality, the only upgrade path is to have parallel libraries, with the new version only catering to types deriving `CanEqual1` and the old version dealing with everything else. Such a split of the ecosystem would be very problematic, which means the cure is likely to be worse than the disease. + +For these reasons, it looks like a two-parameter type class is the only way forward because it can take the existing ecosystem where it is and migrate it towards a future where more and more code uses safe equality. + +In applications where `-language:strictEquality` is the default one could also introduce a one-parameter type alias such as +```scala +type Eq[-T] = CanEqual[T, T] +``` +Operations needing safe equality could then use this alias instead of the two-parameter `CanEqual` class. But it would only +work under `-language:strictEquality`, since otherwise the universal `Eq[Any]` instance would be available everywhere. + + +More on multiversal equality is found in a [blog post](http://www.scala-lang.org/blog/2016/05/06/multiversal-equality.html) +and a [GitHub issue](https://github.com/lampepfl/dotty/issues/1247). diff --git a/docs/_spec/TODOreference/contextual/relationship-implicits.md b/docs/_spec/TODOreference/contextual/relationship-implicits.md new file mode 100644 index 000000000000..fce07f51151a --- /dev/null +++ b/docs/_spec/TODOreference/contextual/relationship-implicits.md @@ -0,0 +1,206 @@ +--- +layout: doc-page +title: "Relationship with Scala 2 Implicits" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/relationship-implicits.html +--- + +Many, but not all, of the new contextual abstraction features in Scala 3 can be mapped to Scala 2's implicits. This page gives a rundown on the relationships between new and old features. + +## Simulating Scala 3 Contextual Abstraction Concepts with Scala 2 Implicits + +### Given Instances + +Given instances can be mapped to combinations of implicit objects, classes and implicit methods. + + 1. Given instances without parameters are mapped to implicit objects. For instance, + + ```scala + given intOrd: Ord[Int] with { ... } + ``` + + maps to + + ```scala + implicit object intOrd extends Ord[Int] { ... } + ``` + + 2. Parameterized givens are mapped to combinations of classes and implicit methods. For instance, + + ```scala + given listOrd[T](using ord: Ord[T]): Ord[List[T]] with { ... } + ``` + + maps to + + ```scala + class listOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... } + final implicit def listOrd[T](implicit ord: Ord[T]): listOrd[T] = + new listOrd[T] + ``` + + 3. Alias givens map to implicit methods or implicit lazy vals. If an alias has neither type nor context parameters, + it is treated as a lazy val, unless the right-hand side is a simple reference, in which case we can use a forwarder to + that reference without caching it. + +Examples: + +```scala +given global: ExecutionContext = new ForkJoinContext() + +val ctx: Context +given Context = ctx +``` + +would map to + +```scala +final implicit lazy val global: ExecutionContext = new ForkJoinContext() +final implicit def given_Context = ctx +``` + +### Anonymous Given Instances + +Anonymous given instances get compiler synthesized names, which are generated in a reproducible way from the implemented type(s). For example, if the names of the `IntOrd` and `ListOrd` givens above were left out, the following names would be synthesized instead: + +```scala +given given_Ord_Int: Ord[Int] with { ... } +given given_Ord_List[T](using ord: Ord[T]): Ord[List[T]] with { ... } +``` + +The synthesized type names are formed from + +1. the prefix `given_`, +2. the simple name(s) of the implemented type(s), leaving out any prefixes, +3. the simple name(s) of the top-level argument type constructors to these types. + +Tuples are treated as transparent, i.e. a type `F[(X, Y)]` would get the synthesized name +`F_X_Y`. Directly implemented function types `A => B` are represented as `A_to_B`. Function types used as arguments to other type constructors are represented as `Function`. + +### Using Clauses + +Using clauses correspond largely to Scala 2's implicit parameter clauses. E.g. + +```scala +def max[T](x: T, y: T)(using ord: Ord[T]): T +``` + +would be written + +```scala +def max[T](x: T, y: T)(implicit ord: Ord[T]): T +``` + +in Scala 2. The main difference concerns applications of such parameters. +Explicit arguments to parameters of using clauses _must_ be written using `(using ...)`, +mirroring the definition syntax. E.g, `max(2, 3)(using IntOrd)`. +Scala 2 uses normal applications `max(2, 3)(IntOrd)` instead. The Scala 2 syntax has some inherent ambiguities and restrictions which are overcome by the new syntax. For instance, multiple implicit parameter lists are not available in the old syntax, even though they can be simulated using auxiliary objects in the "Aux" pattern. + +The `summon` method corresponds to `implicitly` in Scala 2. +It is precisely the same as the `the` method in [Shapeless](https://github.com/milessabin/shapeless). +The difference between `summon` (or `the`) and `implicitly` is +that `summon` can return a more precise type than the type that was +asked for. + +### Context Bounds + +Context bounds are the same in both language versions. They expand to the respective forms of implicit parameters. + +**Note:** To ease migration, context bounds in Scala 3 map for a limited time to old-style implicit parameters for which arguments can be passed either in a using clause or +in a normal argument list. Once old-style implicits are deprecated, context bounds +will map to using clauses instead. + +### Extension Methods + +Extension methods have no direct counterpart in Scala 2, but they can be simulated with implicit classes. For instance, the extension method + +```scala +extension (c: Circle) + def circumference: Double = c.radius * math.Pi * 2 +``` + +could be simulated to some degree by + +```scala +implicit class CircleDecorator(c: Circle) extends AnyVal { + def circumference: Double = c.radius * math.Pi * 2 +} +``` + +Abstract extension methods in traits that are implemented in given instances have no direct counterpart in Scala 2. The only way to simulate these is to make implicit classes available through imports. The Simulacrum macro library can automate this process in some cases. + +### Type Class Derivation + +Type class derivation has no direct counterpart in the Scala 2 language. Comparable functionality can be achieved by macro-based libraries such as [Shapeless](https://github.com/milessabin/shapeless), [Magnolia](https://propensive.com/opensource/magnolia), or [scalaz-deriving](https://github.com/scalaz/scalaz-deriving). + +### Context Function Types + +Context function types have no analogue in Scala 2. + +### Implicit By-Name Parameters + +Implicit by-name parameters are not supported in Scala 2, but can be emulated to some degree by the `Lazy` type in Shapeless. + +## Simulating Scala 2 Implicits in Scala 3 + +### Implicit Conversions + +Implicit conversion methods in Scala 2 can be expressed as given instances of the `scala.Conversion` class in Scala 3. For instance, instead of + +```scala +implicit def stringToToken(str: String): Token = new Keyword(str) +``` + +one can write + +```scala +given stringToToken: Conversion[String, Token] with + def apply(str: String): Token = KeyWord(str) +``` + +or + +```scala +given stringToToken: Conversion[String, Token] = KeyWord(_) +``` + +### Implicit Classes + +Implicit classes in Scala 2 are often used to define extension methods, which are directly supported in Scala 3. Other uses of implicit classes can be simulated by a pair of a regular class and a given `Conversion` instance. + +### Implicit Values + +Implicit `val` definitions in Scala 2 can be expressed in Scala 3 using a regular `val` definition and an alias given. +For instance, Scala 2's + +```scala +lazy implicit val pos: Position = tree.sourcePos +``` + +can be expressed in Scala 3 as + +```scala +lazy val pos: Position = tree.sourcePos +given Position = pos +``` + +### Abstract Implicits + +An abstract implicit `val` or `def` in Scala 2 can be expressed in Scala 3 using a regular abstract definition and an alias given. For instance, Scala 2's + +```scala +implicit def symDecorator: SymDecorator +``` + +can be expressed in Scala 3 as + +```scala +def symDecorator: SymDecorator +given SymDecorator = symDecorator +``` + +## Implementation Status and Timeline + +The Scala 3 implementation implements both Scala 2's implicits and the new abstractions. In fact, support for Scala 2's implicits is an essential part of the common language subset between 2.13 and Scala 3. +Migration to the new abstractions will be supported by making automatic rewritings available. + +Depending on adoption patterns, old style implicits might start to be deprecated in a version following Scala 3.0. diff --git a/docs/_spec/TODOreference/contextual/right-associative-extension-methods.md b/docs/_spec/TODOreference/contextual/right-associative-extension-methods.md new file mode 100644 index 000000000000..068123df8cd2 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/right-associative-extension-methods.md @@ -0,0 +1,52 @@ +--- +layout: doc-page +title: "Right-Associative Extension Methods: Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/right-associative-extension-methods.html +--- + +The most general form of leading parameters of an extension method is as follows: + + - A possibly empty list of using clauses `leadingUsing` + - A single parameter `extensionParam` + - A possibly empty list of using clauses `trailingUsing` + +This is then followed by `def`, the method name, and possibly further parameters +`otherParams`. An example is: + +```scala + extension (using a: A, b: B)(using c: C) // <-- leadingUsing + (x: X) // <-- extensionParam + (using d: D) // <-- trailingUsing + def +:: (y: Y)(using e: E)(z: Z) // <-- otherParams +``` + +An extension method is treated as a right-associative operator +(as in [SLS §6.12.3](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#infix-operations)) +if it has a name ending in `:` and is immediately followed by a +single parameter. In the example above, that parameter is `(y: Y)`. + +The Scala compiler pre-processes a right-associative infix operation such as `x +: xs` +to `xs.+:(x)` if `x` is a pure expression or a call-by-name parameter and to `val y = x; xs.+:(y)` otherwise. This is necessary since a regular right-associative infix method +is defined in the class of its right operand. To make up for this swap, +the expansion of right-associative extension methods performs an analogous parameter swap. More precisely, if `otherParams` consists of a single parameter +`rightParam` followed by `remaining`, the total parameter sequence +of the extension method's expansion is: + +``` + leadingUsing rightParam trailingUsing extensionParam remaining +``` + +For instance, the `+::` method above would become + +```scala + def +:: (using a: A, b: B)(using c: C) + (y: Y) + (using d: D) + (x: X) + (using e: E)(z: Z) +``` + +This expansion has to be kept in mind when writing right-associative extension +methods with inter-parameter dependencies. + +An overall simpler design could be obtained if right-associative operators could _only_ be defined as extension methods, and would be disallowed as normal methods. In that case neither arguments nor parameters would have to be swapped. Future versions of Scala should strive to achieve this simplification. diff --git a/docs/_spec/TODOreference/contextual/type-classes.md b/docs/_spec/TODOreference/contextual/type-classes.md new file mode 100644 index 000000000000..9fc0d2eec864 --- /dev/null +++ b/docs/_spec/TODOreference/contextual/type-classes.md @@ -0,0 +1,282 @@ +--- +layout: doc-page +title: "Implementing Type classes" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/type-classes.html +--- + +A _type class_ is an abstract, parameterized type that lets you add new behavior to any closed data type without using sub-typing. This can be useful in multiple use-cases, for example: + +* expressing how a type you don't own (from the standard or 3rd-party library) conforms to such behavior +* expressing such a behavior for multiple types without involving sub-typing relationships (one `extends` another) between those types (see: [ad hoc polymorphism](https://en.wikipedia.org/wiki/Ad_hoc_polymorphism) for instance) + +Therefore in Scala 3, _type classes_ are just _traits_ with one or more parameters whose implementations are not defined through the `extends` keyword, but by **given instances**. +Here are some examples of common type classes: + +## Semigroups and monoids + +Here's the `Monoid` type class definition: + +```scala +trait SemiGroup[T]: + extension (x: T) def combine (y: T): T + +trait Monoid[T] extends SemiGroup[T]: + def unit: T +``` + +An implementation of this `Monoid` type class for the type `String` can be the following: + +```scala +given Monoid[String] with + extension (x: String) def combine (y: String): String = x.concat(y) + def unit: String = "" +``` + +Whereas for the type `Int` one could write the following: + +```scala +given Monoid[Int] with + extension (x: Int) def combine (y: Int): Int = x + y + def unit: Int = 0 +``` + +This monoid can now be used as _context bound_ in the following `combineAll` method: + +```scala +def combineAll[T: Monoid](xs: List[T]): T = + xs.foldLeft(summon[Monoid[T]].unit)(_.combine(_)) +``` + +To get rid of the `summon[...]` we can define a `Monoid` object as follows: + +```scala +object Monoid: + def apply[T](using m: Monoid[T]) = m +``` + +Which would allow to re-write the `combineAll` method this way: + +```scala +def combineAll[T: Monoid](xs: List[T]): T = + xs.foldLeft(Monoid[T].unit)(_.combine(_)) +``` + +## Functors + +A `Functor` for a type provides the ability for its values to be "mapped over", i.e. apply a function that transforms inside a value while remembering its shape. For example, to modify every element of a collection without dropping or adding elements. +We can represent all types that can be "mapped over" with `F`. It's a type constructor: the type of its values becomes concrete when provided a type argument. +Therefore we write it `F[_]`, hinting that the type `F` takes another type as argument. +The definition of a generic `Functor` would thus be written as: + +```scala +trait Functor[F[_]]: + def map[A, B](x: F[A], f: A => B): F[B] +``` + +Which could read as follows: "A `Functor` for the type constructor `F[_]` represents the ability to transform `F[A]` to `F[B]` through the application of function `f` with type `A => B`". We call the `Functor` definition here a _type class_. +This way, we could define an instance of `Functor` for the `List` type: + +```scala +given Functor[List] with + def map[A, B](x: List[A], f: A => B): List[B] = + x.map(f) // List already has a `map` method +``` + +With this `given` instance in scope, everywhere a `Functor` is expected, the compiler will accept a `List` to be used. + +For instance, we may write such a testing method: + +```scala +def assertTransformation[F[_]: Functor, A, B](expected: F[B], original: F[A], mapping: A => B): Unit = + assert(expected == summon[Functor[F]].map(original, mapping)) +``` + +And use it this way, for example: + +```scala +assertTransformation(List("a1", "b1"), List("a", "b"), elt => s"${elt}1") +``` + +That's a first step, but in practice we probably would like the `map` function to be a method directly accessible on the type `F`. So that we can call `map` directly on instances of `F`, and get rid of the `summon[Functor[F]]` part. +As in the previous example of Monoids, [`extension` methods](extension-methods.md) help achieving that. Let's re-define the `Functor` type class with extension methods. + +```scala +trait Functor[F[_]]: + extension [A](x: F[A]) + def map[B](f: A => B): F[B] +``` + +The instance of `Functor` for `List` now becomes: + +```scala +given Functor[List] with + extension [A](xs: List[A]) + def map[B](f: A => B): List[B] = + xs.map(f) // List already has a `map` method + +``` + +It simplifies the `assertTransformation` method: + +```scala +def assertTransformation[F[_]: Functor, A, B](expected: F[B], original: F[A], mapping: A => B): Unit = + assert(expected == original.map(mapping)) +``` + +The `map` method is now directly used on `original`. It is available as an extension method +since `original`'s type is `F[A]` and a given instance for `Functor[F[A]]` which defines `map` +is in scope. + +## Monads + +Applying `map` in `Functor[List]` to a mapping function of type `A => B` results in a `List[B]`. So applying it to a mapping function of type `A => List[B]` results in a `List[List[B]]`. To avoid managing lists of lists, we may want to "flatten" the values in a single list. + +That's where `Monad` comes in. A `Monad` for type `F[_]` is a `Functor[F]` with two more operations: + +* `flatMap`, which turns an `F[A]` into an `F[B]` when given a function of type `A => F[B]`, +* `pure`, which creates an `F[A]` from a single value `A`. + +Here is the translation of this definition in Scala 3: + +```scala +trait Monad[F[_]] extends Functor[F]: + + /** The unit value for a monad */ + def pure[A](x: A): F[A] + + extension [A](x: F[A]) + /** The fundamental composition operation */ + def flatMap[B](f: A => F[B]): F[B] + + /** The `map` operation can now be defined in terms of `flatMap` */ + def map[B](f: A => B) = x.flatMap(f.andThen(pure)) + +end Monad +``` + +### List + +A `List` can be turned into a monad via this `given` instance: + +```scala +given listMonad: Monad[List] with + def pure[A](x: A): List[A] = + List(x) + extension [A](xs: List[A]) + def flatMap[B](f: A => List[B]): List[B] = + xs.flatMap(f) // rely on the existing `flatMap` method of `List` +``` + +Since `Monad` is a subtype of `Functor`, `List` is also a functor. The Functor's `map` +operation is already provided by the `Monad` trait, so the instance does not need to define +it explicitly. + +### Option + +`Option` is an other type having the same kind of behaviour: + +```scala +given optionMonad: Monad[Option] with + def pure[A](x: A): Option[A] = + Option(x) + extension [A](xo: Option[A]) + def flatMap[B](f: A => Option[B]): Option[B] = xo match + case Some(x) => f(x) + case None => None +``` + +### Reader + +Another example of a `Monad` is the _Reader_ Monad, which acts on functions instead of +data types like `List` or `Option`. It can be used to combine multiple functions +that all need the same parameter. For instance multiple functions needing access to some configuration, context, environment variables, etc. + +Let's define a `Config` type, and two functions using it: + +```scala +trait Config +// ... +def compute(i: Int)(config: Config): String = ??? +def show(str: String)(config: Config): Unit = ??? +``` + +We may want to combine `compute` and `show` into a single function, accepting a `Config` as parameter, and showing the result of the computation, and we'd like to use +a monad to avoid passing the parameter explicitly multiple times. So postulating +the right `flatMap` operation, we could write: + +```scala +def computeAndShow(i: Int): Config => Unit = compute(i).flatMap(show) +``` + +instead of + +```scala +show(compute(i)(config))(config) +``` + +Let's define this m then. First, we are going to define a type named `ConfigDependent` representing a function that when passed a `Config` produces a `Result`. + +```scala +type ConfigDependent[Result] = Config => Result +``` + +The monad instance will look like this: + +```scala +given configDependentMonad: Monad[ConfigDependent] with + + def pure[A](x: A): ConfigDependent[A] = + config => x + + extension [A](x: ConfigDependent[A]) + def flatMap[B](f: A => ConfigDependent[B]): ConfigDependent[B] = + config => f(x(config))(config) + +end configDependentMonad +``` + +The type `ConfigDependent` can be written using [type lambdas](../new-types/type-lambdas.md): + +```scala +type ConfigDependent = [Result] =>> Config => Result +``` + +Using this syntax would turn the previous `configDependentMonad` into: + +```scala +given configDependentMonad: Monad[[Result] =>> Config => Result] with + + def pure[A](x: A): Config => A = + config => x + + extension [A](x: Config => A) + def flatMap[B](f: A => Config => B): Config => B = + config => f(x(config))(config) + +end configDependentMonad +``` + +It is likely that we would like to use this pattern with other kinds of environments than our `Config` trait. The Reader monad allows us to abstract away `Config` as a type _parameter_, named `Ctx` in the following definition: + +```scala +given readerMonad[Ctx]: Monad[[X] =>> Ctx => X] with + + def pure[A](x: A): Ctx => A = + ctx => x + + extension [A](x: Ctx => A) + def flatMap[B](f: A => Ctx => B): Ctx => B = + ctx => f(x(ctx))(ctx) + +end readerMonad +``` + +## Summary + +The definition of a _type class_ is expressed with a parameterised type with abstract members, such as a `trait`. +The main difference between subtype polymorphism and ad-hoc polymorphism with _type classes_ is how the definition of the _type class_ is implemented, in relation to the type it acts upon. +In the case of a _type class_, its implementation for a concrete type is expressed through a `given` instance definition, which is supplied as an implicit argument alongside the value it acts upon. With subtype polymorphism, the implementation is mixed into the parents of a class, and only a single term is required to perform a polymorphic operation. The type class solution +takes more effort to set up, but is more extensible: Adding a new interface to a +class requires changing the source code of that class. But contrast, instances for type classes can be defined anywhere. + +To conclude, we have seen that traits and given instances, combined with other constructs like extension methods, context bounds and type lambdas allow a concise and natural expression of _type classes_. diff --git a/docs/_spec/TODOreference/contextual/using-clauses.md b/docs/_spec/TODOreference/contextual/using-clauses.md new file mode 100644 index 000000000000..9187e1916e7d --- /dev/null +++ b/docs/_spec/TODOreference/contextual/using-clauses.md @@ -0,0 +1,153 @@ +--- +layout: doc-page +title: "Using Clauses" +nightlyOf: https://docs.scala-lang.org/scala3/reference/contextual/using-clauses.html +--- + +Functional programming tends to express most dependencies as simple function parameterization. +This is clean and powerful, but it sometimes leads to functions that take many parameters where the same value is passed over and over again in long call chains to many +functions. Context parameters can help here since they enable the compiler to synthesize +repetitive arguments instead of the programmer having to write them explicitly. + +For example, with the [given instances](./givens.md) defined previously, +a `max` function that works for any arguments for which an ordering exists can be defined as follows: + +```scala +def max[T](x: T, y: T)(using ord: Ord[T]): T = + if ord.compare(x, y) < 0 then y else x +``` + +Here, `ord` is a _context parameter_ introduced with a `using` clause. +The `max` function can be applied as follows: + +```scala +max(2, 3)(using intOrd) +``` + +The `(using intOrd)` part passes `intOrd` as an argument for the `ord` parameter. But the point of context parameters is that this argument can also be left out (and it usually is). So the following applications are equally valid: + +```scala +max(2, 3) +max(List(1, 2, 3), Nil) +``` + +## Anonymous Context Parameters + +In many situations, the name of a context parameter need not be +mentioned explicitly at all, since it is used only in synthesized arguments for +other context parameters. In that case one can avoid defining a parameter name +and just provide its type. Example: + +```scala +def maximum[T](xs: List[T])(using Ord[T]): T = + xs.reduceLeft(max) +``` + +`maximum` takes a context parameter of type `Ord[T]` only to pass it on as an +inferred argument to `max`. The name of the parameter is left out. + +Generally, context parameters may be defined either as a full parameter list `(p_1: T_1, ..., p_n: T_n)` or just as a sequence of types `T_1, ..., T_n`. Vararg parameters are not supported in `using` clauses. + +## Class Context Parameters + +If a class context parameter is made a member by adding a `val` or `var` modifier, +then that member is available as a given instance. + +Compare the following examples, where the attempt to supply an explicit `given` member induces an ambiguity: + +```scala +class GivenIntBox(using val givenInt: Int): + def n = summon[Int] + +class GivenIntBox2(using givenInt: Int): + given Int = givenInt + //def n = summon[Int] // ambiguous +``` + +The `given` member is importable as explained in the section on [importing `given`s](./given-imports.md): + +```scala +val b = GivenIntBox(using 23) +import b.given +summon[Int] // 23 + +import b.* +//givenInt // Not found +``` + +## Inferring Complex Arguments + +Here are two other methods that have a context parameter of type `Ord[T]`: + +```scala +def descending[T](using asc: Ord[T]): Ord[T] = new Ord[T]: + def compare(x: T, y: T) = asc.compare(y, x) + +def minimum[T](xs: List[T])(using Ord[T]) = + maximum(xs)(using descending) +``` + +The `minimum` method's right-hand side passes `descending` as an explicit argument to `maximum(xs)`. +With this setup, the following calls are all well-formed, and they all normalize to the last one: + +```scala +minimum(xs) +maximum(xs)(using descending) +maximum(xs)(using descending(using listOrd)) +maximum(xs)(using descending(using listOrd(using intOrd))) +``` + +## Multiple `using` Clauses + +There can be several `using` clauses in a definition and `using` clauses can be freely mixed with normal parameter clauses. Example: + +```scala +def f(u: Universe)(using ctx: u.Context)(using s: ctx.Symbol, k: ctx.Kind) = ... +``` + +Multiple `using` clauses are matched left-to-right in applications. Example: + +```scala +object global extends Universe { type Context = ... } +given ctx : global.Context with { type Symbol = ...; type Kind = ... } +given sym : ctx.Symbol +given kind: ctx.Kind + +``` +Then the following calls are all valid (and normalize to the last one) + +```scala +f(global) +f(global)(using ctx) +f(global)(using ctx)(using sym, kind) +``` + +But `f(global)(using sym, kind)` would give a type error. + + +## Summoning Instances + +The method `summon` in `Predef` returns the given of a specific type. For example, +the given instance for `Ord[List[Int]]` is produced by + +```scala +summon[Ord[List[Int]]] // reduces to listOrd(using intOrd) +``` + +The `summon` method is simply defined as the (non-widening) identity function over a context parameter. + +```scala +def summon[T](using x: T): x.type = x +``` + +## Syntax + +Here is the new syntax of parameters and arguments seen as a delta from the [standard context free syntax of Scala 3](../syntax.md). `using` is a soft keyword, recognized only at the start of a parameter or argument list. It can be used as a normal identifier everywhere else. + +``` +ClsParamClause ::= ... | UsingClsParamClause +DefParamClauses ::= ... | UsingParamClause +UsingClsParamClause ::= ‘(’ ‘using’ (ClsParams | Types) ‘)’ +UsingParamClause ::= ‘(’ ‘using’ (DefParams | Types) ‘)’ +ParArgumentExprs ::= ... | ‘(’ ‘using’ ExprsInParens ‘)’ +``` diff --git a/docs/_spec/TODOreference/dropped-features/auto-apply.md b/docs/_spec/TODOreference/dropped-features/auto-apply.md new file mode 100644 index 000000000000..eadfe2f429ea --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/auto-apply.md @@ -0,0 +1,96 @@ +--- +layout: doc-page +title: "Dropped: Auto-Application" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/auto-apply.html +--- + +Previously an empty argument list `()` was implicitly inserted when +calling a nullary method without arguments. Example: + +```scala +def next(): T = ... +next // is expanded to next() +``` + +In Scala 3, this idiom is an error. + +```scala +next +^ +missing arguments for method next +``` + +In Scala 3, the application syntax has to follow exactly the parameter +syntax. Excluded from this rule are methods that are defined in Java +or that override methods defined in Java. The reason for being more +lenient with such methods is that otherwise everyone would have to +write + +```scala +xs.toString().length() +``` + +instead of + +```scala +xs.toString.length +``` + +The latter is idiomatic Scala because it conforms to the _uniform +access principle_. This principle states that one should be able to +change an object member from a field to a non-side-effecting method +and back without affecting clients that access the +member. Consequently, Scala encourages to define such "property" +methods without a `()` parameter list whereas side-effecting methods +should be defined with it. Methods defined in Java cannot make this +distinction; for them a `()` is always mandatory. So Scala fixes the +problem on the client side, by allowing the parameterless references. +But where Scala allows that freedom for all method references, Scala 3 +restricts it to references of external methods that are not defined +themselves in Scala 3. + +For reasons of backwards compatibility, Scala 3 for the moment also +auto-inserts `()` for nullary methods that are defined in Scala 2, or +that override a method defined in Scala 2. It turns out that, because +the correspondence between definition and call was not enforced in +Scala so far, there are quite a few method definitions in Scala 2 +libraries that use `()` in an inconsistent way. For instance, we +find in `scala.math.Numeric` + +```scala +def toInt(): Int +``` + +whereas `toInt` is written without parameters everywhere +else. Enforcing strict parameter correspondence for references to +such methods would project the inconsistencies to client code, which +is undesirable. So Scala 3 opts for more leniency when type-checking +references to such methods until most core libraries in Scala 2 have +been cleaned up. + +Stricter conformance rules also apply to overriding of nullary +methods. It is no longer allowed to override a parameterless method +by a nullary method or _vice versa_. Instead, both methods must agree +exactly in their parameter lists. + +```scala +class A: + def next(): Int + +class B extends A: + def next: Int // overriding error: incompatible type +``` + +Methods overriding Java or Scala 2 methods are again exempted from this +requirement. + +## Migrating code + +Existing Scala code with inconsistent parameters can still be compiled +in Scala 3 under `-source 3.0-migration`. When paired with the `-rewrite` +option, the code will be automatically rewritten to conform to Scala 3's +stricter checking. + +## Reference + +For more information, see [Issue #2570](https://github.com/lampepfl/dotty/issues/2570) and [PR #2716](https://github.com/lampepfl/dotty/pull/2716). diff --git a/docs/_spec/TODOreference/dropped-features/class-shadowing-spec.md b/docs/_spec/TODOreference/dropped-features/class-shadowing-spec.md new file mode 100644 index 000000000000..6c81087408c6 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/class-shadowing-spec.md @@ -0,0 +1,26 @@ +--- +layout: doc-page +title: "Dropped: Class Shadowing - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/class-shadowing-spec.html +--- + +Spec diff: in section [5.1.4 Overriding](https://www.scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#Overriding), add *M' must not be a class*. + +> Why do we want to make this change to the language? + +Class shadowing is irregular compared to other types of overrides. Indeed, inner classes are not actually overridden but simply shadowed. + + +> How much existing code is going to be affected? + +From all the code compiled so far with Scala 3 the only instance of this I could find is in the stdlib. Looking at [this commit](https://github.com/lampepfl/scala/commit/68f13bf39979b631ed211ec1751934306ceb5d6c#diff-7aa508b70e055b47c823764e3e5646b8) it seems like the usage of class shadowing was accidental. + + +> How exactly is existing code going to be affected? + +Code that relies on overridden inner classes will stop compiling. + + +> Is this change going to be migratable automatically? + +No. diff --git a/docs/_spec/TODOreference/dropped-features/class-shadowing.md b/docs/_spec/TODOreference/dropped-features/class-shadowing.md new file mode 100644 index 000000000000..8bfdb1eb196c --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/class-shadowing.md @@ -0,0 +1,33 @@ +--- +layout: doc-page +title: "Dropped: Class Shadowing" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/class-shadowing.html +--- + +Scala 2 so far allowed patterns like this: + +```scala +class Base { + class Ops { ... } +} + +class Sub extends Base { + class Ops { ... } +} +``` + +Scala 3 rejects this with the error message: + +```scala +6 | class Ops { } + | ^ + |class Ops cannot have the same name as class Ops in class Base + | -- class definitions cannot be overridden +``` + +The issue is that the two `Ops` classes _look_ like one overrides the +other, but classes in Scala 2 cannot be overridden. To keep things clean +(and its internal operations consistent) the Scala 3 compiler forces you +to rename the inner classes so that their names are different. + +[More details](./class-shadowing-spec.md) diff --git a/docs/_spec/TODOreference/dropped-features/delayed-init.md b/docs/_spec/TODOreference/dropped-features/delayed-init.md new file mode 100644 index 000000000000..5d4f614ce951 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/delayed-init.md @@ -0,0 +1,32 @@ +--- +layout: doc-page +title: "Dropped: DelayedInit" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/delayed-init.html +--- + +The special handling of the [`DelayedInit`](https://scala-lang.org/api/3.x/scala/DelayedInit.html) +trait is no longer supported. + +One consequence is that the [`App`](https://scala-lang.org/api/3.x/scala/App.html) class, +which used [`DelayedInit`](https://scala-lang.org/api/3.x/scala/DelayedInit.html) is +now partially broken. You can still use `App` as a simple way to set up a main program. Example: + +```scala +object HelloWorld extends App { + println("Hello, world!") +} +``` + +However, the code is now run in the initializer of the object, which on +some JVM's means that it will only be interpreted. So, better not use it +for benchmarking! Also, if you want to access the command line arguments, +you need to use an explicit `main` method for that. + +```scala +object Hello: + def main(args: Array[String]) = + println(s"Hello, ${args(0)}") +``` + +On the other hand, Scala 3 offers a convenient alternative to such "program" objects +with [`@main` methods](../changed-features/main-functions.md). diff --git a/docs/_spec/TODOreference/dropped-features/do-while.md b/docs/_spec/TODOreference/dropped-features/do-while.md new file mode 100644 index 000000000000..08a730b8b5a7 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/do-while.md @@ -0,0 +1,41 @@ +--- +layout: doc-page +title: "Dropped: Do-While" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/do-while.html +--- + +The syntax construct +```scala +do while +``` +is no longer supported. Instead, it is recommended to use the equivalent `while` loop +below: +```scala +while ({ ; }) () +``` +For instance, instead of +```scala +do + i += 1 +while (f(i) == 0) +``` +one writes +```scala +while + i += 1 + f(i) == 0 +do () +``` +The idea to use a block as the condition of a while also gives a solution +to the "loop-and-a-half" problem. Here is another example: +```scala +while + val x: Int = iterator.next + x >= 0 +do print(".") +``` + +## Why Drop The Construct? + + - `do-while` is used relatively rarely and it can be expressed faithfully using just `while`. So there seems to be little point in having it as a separate syntax construct. + - Under the [new syntax rules](../other-new-features/control-syntax.md) `do` is used as a statement continuation, which would clash with its meaning as a statement introduction. diff --git a/docs/_spec/TODOreference/dropped-features/dropped-features.md b/docs/_spec/TODOreference/dropped-features/dropped-features.md new file mode 100644 index 000000000000..f6a13d9fa5da --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/dropped-features.md @@ -0,0 +1,7 @@ +--- +layout: index +title: "Dropped Features" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features.html +--- + +The following pages document the features of Scala 2 that have been dropped in Scala 3. diff --git a/docs/_spec/TODOreference/dropped-features/early-initializers.md b/docs/_spec/TODOreference/dropped-features/early-initializers.md new file mode 100644 index 000000000000..6f7c59c4f031 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/early-initializers.md @@ -0,0 +1,16 @@ +--- +layout: doc-page +title: "Dropped: Early Initializers" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/early-initializers.html +--- + +Early initializers of the form + +```scala +class C extends { ... } with SuperClass ... +``` + +have been dropped. They were rarely used, and mostly to compensate for the lack of +[trait parameters](../other-new-features/trait-parameters.md), which are now directly supported in Scala 3. + +For more information, see [SLS §5.1.6](https://www.scala-lang.org/files/archive/spec/2.13/05-classes-and-objects.html#early-definitions). diff --git a/docs/_spec/TODOreference/dropped-features/existential-types.md b/docs/_spec/TODOreference/dropped-features/existential-types.md new file mode 100644 index 000000000000..6ef815152cd0 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/existential-types.md @@ -0,0 +1,35 @@ +--- +layout: doc-page +title: "Dropped: Existential Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/existential-types.html +--- + +Existential types using `forSome` (as in +[SLS §3.2.12](https://www.scala-lang.org/files/archive/spec/2.13/03-types.html#existential-types)) +have been dropped. The reasons for dropping them are: + + - Existential types violate a type soundness principle on which DOT + and Scala 3 are constructed. That principle says that every + prefix (`p`, respectvely `S`) of a type selection `p.T` or `S#T` + must either come from a value constructed at runtime or refer to a + type that is known to have only good bounds. + + - Existential types create many difficult feature interactions + with other Scala constructs. + + - Existential types largely overlap with path-dependent types, + so the gain of having them is relatively minor. + +Existential types that can be expressed using only wildcards (but not +`forSome`) are still supported, but are treated as refined types. +For instance, the type +```scala +Map[_ <: AnyRef, Int] +``` +is treated as the type `Map`, where the first type parameter +is upper-bounded by `AnyRef` and the second type parameter is an alias +of `Int`. + +When reading class files compiled with Scala 2, Scala 3 will do a best +effort to approximate existential types with its own types. It will +issue a warning that a precise emulation is not possible. diff --git a/docs/_spec/TODOreference/dropped-features/limit22.md b/docs/_spec/TODOreference/dropped-features/limit22.md new file mode 100644 index 000000000000..e72aeadbe2ca --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/limit22.md @@ -0,0 +1,17 @@ +--- +layout: doc-page +title: "Dropped: Limit 22" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/limit22.html +--- + +The limits of 22 for the maximal number of parameters of function types and the +maximal number of fields in tuple types have been dropped. + +* Functions can now have an arbitrary number of parameters. Functions beyond + [`scala.Function22`](https://www.scala-lang.org/api/current/scala/Function22.html) are erased to a new trait [`scala.runtime.FunctionXXL`](https://scala-lang.org/api/3.x/scala/runtime/FunctionXXL.html). + +* Tuples can also have an arbitrary number of fields. Tuples beyond [`scala.Tuple22`](https://www.scala-lang.org/api/current/scala/Tuple22.html) + are erased to a new class [`scala.runtime.TupleXXL`](https://scala-lang.org/api/3.x/scala/runtime/TupleXXL.html) (which extends the trait [`scala.Product`](https://scala-lang.org/api/3.x/scala/Product.md)). Furthermore, they support generic + operation such as concatenation and indexing. + +Both of these are implemented using arrays. diff --git a/docs/_spec/TODOreference/dropped-features/macros.md b/docs/_spec/TODOreference/dropped-features/macros.md new file mode 100644 index 000000000000..7ffe9043d0cd --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/macros.md @@ -0,0 +1,16 @@ +--- +layout: doc-page +title: "Dropped: Scala 2 Macros" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/macros.html +--- + +The previous, experimental macro system has been dropped. + +Instead, there is a cleaner, more restricted system based on two complementary concepts: `inline` and `'{ ... }`/`${ ... }` code generation. +`'{ ... }` delays the compilation of the code and produces an object containing the code, dually `${ ... }` evaluates an expression which produces code and inserts it in the surrounding `${ ... }`. +In this setting, a definition marked as inlined containing a `${ ... }` is a macro, the code inside the `${ ... }` is executed at compile-time and produces code in the form of `'{ ... }`. +Additionally, the contents of code can be inspected and created with a more complex reflection API as an extension of `'{ ... }`/`${ ... }` framework. + +* `inline` has been [implemented](../metaprogramming/inline.md) in Scala 3. +* Quotes `'{ ... }` and splices `${ ... }` has been [implemented](../metaprogramming/macros.md) in Scala 3. +* [TASTy reflect](../metaprogramming/reflection.md) provides more complex tree based APIs to inspect or create quoted code. diff --git a/docs/_spec/TODOreference/dropped-features/nonlocal-returns.md b/docs/_spec/TODOreference/dropped-features/nonlocal-returns.md new file mode 100644 index 000000000000..17b86f77ee56 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/nonlocal-returns.md @@ -0,0 +1,29 @@ +--- +layout: doc-page +title: "Deprecated: Nonlocal Returns" + +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/nonlocal-returns.html +--- + +Returning from nested anonymous functions has been deprecated, and will produce a warning from version `3.2`. + +Nonlocal returns are implemented by throwing and catching `scala.runtime.NonLocalReturnException`-s. This is rarely what is intended by the programmer. It can be problematic because of the hidden performance cost of throwing and catching exceptions. Furthermore, it is a leaky implementation: a catch-all exception handler can intercept a `NonLocalReturnException`. + +A drop-in library replacement is provided in [`scala.util.control.NonLocalReturns`](https://scala-lang.org/api/3.x/scala/util/control/NonLocalReturns$.html). Example: + +```scala +import scala.util.control.NonLocalReturns.* + +extension [T](xs: List[T]) + def has(elem: T): Boolean = returning { + for x <- xs do + if x == elem then throwReturn(true) + false + } + +@main def test(): Unit = + val xs = List(1, 2, 3, 4, 5) + assert(xs.has(2) == xs.contains(2)) +``` + +Note: compiler produces deprecation error on nonlocal returns only with `-source:future` option. diff --git a/docs/_spec/TODOreference/dropped-features/package-objects.md b/docs/_spec/TODOreference/dropped-features/package-objects.md new file mode 100644 index 000000000000..d8149e460bf5 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/package-objects.md @@ -0,0 +1,48 @@ +--- +layout: doc-page +title: "Dropped: Package Objects" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/package-objects.html +--- + +Package objects +```scala +package object p { + val a = ... + def b = ... +} +``` +will be dropped. They are still available in Scala 3.0 and 3.1, but will be deprecated and removed afterwards. + +Package objects are no longer needed since all kinds of definitions can now be written at the top-level. Example: +```scala +package p +type Labelled[T] = (String, T) +val a: Labelled[Int] = ("count", 1) +def b = a._2 + +case class C() + +extension (x: C) def pair(y: C) = (x, y) +``` +There may be several source files in a package containing such top-level definitions, and source files can freely mix top-level value, method, and type definitions with classes and objects. + +The compiler generates synthetic objects that wrap top-level definitions falling into one of the following categories: + + - all pattern, value, method, and type definitions, + - implicit classes and objects, + - companion objects of opaque type aliases. + +If a source file `src.scala` contains such top-level definitions, they will be put in a synthetic object named `src$package`. The wrapping is transparent, however. The definitions in `src` can still be accessed as members of the enclosing package. The synthetic object will be placed last in the file, +after any other package clauses, imports, or object and class definitions. + +**Note:** This means that +1. The name of a source file containing wrapped top-level definitions is relevant for binary compatibility. If the name changes, so does the name of the generated object and its class. + +2. A top-level main method `def main(args: Array[String]): Unit = ...` is wrapped as any other method. If it appears +in a source file `src.scala`, it could be invoked from the command line using a command like `scala src$package`. Since the +"program name" is mangled it is recommended to always put `main` methods in explicitly named objects. + +3. The notion of `private` is independent of whether a definition is wrapped or not. A `private` top-level definition is always visible from everywhere in the enclosing package. + +4. If several top-level definitions are overloaded variants with the same name, +they must all come from the same source file. diff --git a/docs/_spec/TODOreference/dropped-features/procedure-syntax.md b/docs/_spec/TODOreference/dropped-features/procedure-syntax.md new file mode 100644 index 000000000000..de76fbb32af2 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/procedure-syntax.md @@ -0,0 +1,19 @@ +--- +layout: doc-page +title: "Dropped: Procedure Syntax" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/procedure-syntax.html +--- + +Procedure syntax +```scala +def f() { ... } +``` +has been dropped. You need to write one of the following instead: +```scala +def f() = { ... } +def f(): Unit = { ... } +``` +Scala 3 accepts the old syntax under the `-source:3.0-migration` option. +If the `-migration` option is set, it can even rewrite old syntax to new. +The [Scalafix](https://scalacenter.github.io/scalafix/) tool also +can rewrite procedure syntax to make it Scala 3 compatible. diff --git a/docs/_spec/TODOreference/dropped-features/symlits.md b/docs/_spec/TODOreference/dropped-features/symlits.md new file mode 100644 index 000000000000..d3c0180b16e6 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/symlits.md @@ -0,0 +1,24 @@ +--- +layout: doc-page +title: "Dropped: Symbol Literals" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/symlits.html +--- + +Symbol literals are no longer supported. + +The [`scala.Symbol`](https://scala-lang.org/api/3.x/scala/Symbol.html) class still exists, so a literal translation of the symbol literal `'xyz` is `Symbol("xyz")`. However, it is recommended to use a plain string literal `"xyz"` instead. (The `Symbol` class will be deprecated and removed in the future). Example: + + +``` +scalac Test.scala +-- Error: Test.scala:1:25 ------------------------------------------------------------------------------------------------ + +1 |@main def test = println('abc) + | ^ + | symbol literal 'abc is no longer supported, + | use a string literal "abc" or an application Symbol("abc") instead, + | or enclose in braces '{abc} if you want a quoted expression. + | For now, you can also `import language.deprecated.symbolLiterals` to accept + | the idiom, but this possibility might no longer be available in the future. +1 error found +``` diff --git a/docs/_spec/TODOreference/dropped-features/this-qualifier.md b/docs/_spec/TODOreference/dropped-features/this-qualifier.md new file mode 100644 index 000000000000..4fcadff8fae3 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/this-qualifier.md @@ -0,0 +1,33 @@ +--- +layout: doc-page +title: "Dropped: private[this] and protected[this]" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/this-qualifier.html +--- + +The `private[this]` and `protected[this]` access modifiers are deprecated and will be phased out. + +Previously, these modifiers were needed for + + - avoiding the generation of getters and setters + - excluding code under a `private[this]` from variance checks. (Scala 2 also excludes `protected[this]` but this was found to be unsound and was therefore removed). + - avoiding the generation of fields, if a `private[this] val` is not accessed + by a class method. + +The compiler now infers for `private` members the fact that they are only accessed via `this`. Such members are treated as if they had been declared `private[this]`. `protected[this]` is dropped without a replacement. + +This change can in some cases change the semantics of a Scala program, since a +`private` val is no longer guaranteed to generate a field. The field +is omitted if + + - the `val` is only accessed via `this`, and + - the `val` is not accessed from a method in the current class. + +This can cause problems if a program tries to access the missing private field via reflection. The recommended fix is to declare the field instead to be qualified private with the enclosing class as qualifier. Example: +```scala + class C(x: Int): + private[C] val field = x + 1 + // [C] needed if `field` is to be accessed through reflection + val retained = field * field +``` + + diff --git a/docs/_spec/TODOreference/dropped-features/type-projection.md b/docs/_spec/TODOreference/dropped-features/type-projection.md new file mode 100644 index 000000000000..08b5ffb34eca --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/type-projection.md @@ -0,0 +1,18 @@ +--- +layout: doc-page +title: "Dropped: General Type Projection" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/type-projection.html +--- + +Scala so far allowed general type projection `T#A` where `T` is an arbitrary type +and `A` names a type member of `T`. + +Scala 3 disallows this if `T` is an abstract type (class types and type aliases +are fine). This change was made because unrestricted type projection +is [unsound](https://github.com/lampepfl/dotty/issues/1050). + +This restriction rules out the [type-level encoding of a combinator +calculus](https://michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/). + +To rewrite code using type projections on abstract types, consider using +path-dependent types or implicit parameters. diff --git a/docs/_spec/TODOreference/dropped-features/weak-conformance-spec.md b/docs/_spec/TODOreference/dropped-features/weak-conformance-spec.md new file mode 100644 index 000000000000..07625dcfe885 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/weak-conformance-spec.md @@ -0,0 +1,54 @@ +--- +layout: doc-page +title: "Dropped: Weak Conformance - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/weak-conformance-spec.html +--- + +To simplify the underlying type theory, Scala 3 drops the notion of +[*weak conformance*](https://www.scala-lang.org/files/archive/spec/2.13/03-types.html#weak-conformance) +altogether. Instead, it provides more flexibility when +assigning a type to a constant expression. The new rule is: + + - *If* a list of expressions `Es` appears as one of + + - the elements of a vararg parameter, or + - the alternatives of an if-then-else or match expression, or + - the body and catch results of a try expression, + +- *and* all expressions have primitive numeric types, but they do not + all have the same type, + +- *then* the following is attempted: + + - the expressions `Es` are partitioned into `Int` constants on the + one hand, and all other expressions on the other hand, + - if all the other expressions have the same numeric type `T` + (which can be one of `Byte`, `Short`, `Char`, `Int`, `Long`, `Float`, + `Double`), possibly after widening, and if none of the `Int` + literals would incur a loss of precision when converted to `T`, + then they are thus converted (the other expressions are left + unchanged regardless), + - otherwise, the expressions `Es` are used unchanged. + + A loss of precision occurs for + - an `Int -> Float` conversion of a constant + `c` if `c.toFloat.toInt != c` + - an `Int -> Byte` conversion of a constant + `c` if `c.toByte.toInt != c`, + - an `Int -> Short` conversion of a constant + `c` if `c.toShort.toInt != c`. + +## Examples + +```scala +inline val b = 33 +def f(): Int = b + 1 +Array(b, 33, 5.5) : Array[Double] // b is an inline val +Array(f(), 33, 5.5) : Array[AnyVal] // f() is not a constant +Array(5, 11L) : Array[Long] +Array(5, 11L, 5.5) : Array[AnyVal] // Long and Double found +Array(1.0f, 2) : Array[Float] +Array(1.0f, 1234567890): Array[AnyVal] // loss of precision +Array(b, 33, 'a') : Array[Char] +Array(5.toByte, 11) : Array[Byte] +``` diff --git a/docs/_spec/TODOreference/dropped-features/weak-conformance.md b/docs/_spec/TODOreference/dropped-features/weak-conformance.md new file mode 100644 index 000000000000..b1478326b2c9 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/weak-conformance.md @@ -0,0 +1,47 @@ +--- +layout: doc-page +title: "Dropped: Weak Conformance" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/weak-conformance.html +--- + +In some situations, Scala used a _weak conformance_ relation when +testing type compatibility or computing the least upper bound of a set +of types. The principal motivation behind weak conformance was to +make an expression like this have type `List[Double]`: + +```scala +List(1.0, math.sqrt(3.0), 0, -3.3) // : List[Double] +``` + +It's "obvious" that this should be a `List[Double]`. However, without +some special provision, the least upper bound of the lists's element +types `(Double, Double, Int, Double)` would be `AnyVal`, hence the list +expression would be given type `List[AnyVal]`. + +A less obvious example is the following one, which was also typed as a +`List[Double]`, using the weak conformance relation. + +```scala +val n: Int = 3 +val c: Char = 'X' +val d: Double = math.sqrt(3.0) +List(n, c, d) // used to be: List[Double], now: List[AnyVal] +``` + +Here, it is less clear why the type should be widened to +`List[Double]`, a `List[AnyVal]` seems to be an equally valid -- and +more principled -- choice. + +Weak conformance applies to all "numeric" types (including `Char`), and +independently of whether the expressions are literals or not. However, +in hindsight, the only intended use case is for *integer literals* to +be adapted to the type of the other expressions. Other types of numerics +have an explicit type annotation embedded in their syntax (`f`, `d`, +`.`, `L` or `'` for `Char`s) which ensures that their author really +meant them to have that specific type). + +Therefore, Scala 3 drops the general notion of weak conformance, and +instead keeps one rule: `Int` literals are adapted to other numeric +types if necessary. + +[More details](weak-conformance-spec.md) diff --git a/docs/_spec/TODOreference/dropped-features/wildcard-init.md b/docs/_spec/TODOreference/dropped-features/wildcard-init.md new file mode 100644 index 000000000000..e42854079cf9 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/wildcard-init.md @@ -0,0 +1,23 @@ +--- +layout: doc-page +title: "Dropped: Wildcard Initializer" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/wildcard-init.html +--- + +The syntax + +```scala + var x: A = _ +``` + +that was used to indicate an uninitialized field, has been dropped. +At its place there is a special value `uninitialized` in the `scala.compiletime` package. +To get an uninitialized field, you now write + +```scala +import scala.compiletime.uninitialized + +var x: A = uninitialized +``` + +To enable cross-compilation, `_` is still supported, but it will be dropped in a future 3.x version. diff --git a/docs/_spec/TODOreference/dropped-features/xml.md b/docs/_spec/TODOreference/dropped-features/xml.md new file mode 100644 index 000000000000..458a347a66c4 --- /dev/null +++ b/docs/_spec/TODOreference/dropped-features/xml.md @@ -0,0 +1,39 @@ +--- +layout: doc-page +title: "Dropped: XML Literals" +nightlyOf: https://docs.scala-lang.org/scala3/reference/dropped-features/xml.html +--- + +XML Literals are still supported, but will be dropped in the near future, to +be replaced with [XML string interpolation](https://github.com/lampepfl/xml-interpolator): + +```scala +import dotty.xml.interpolator.* + +case class Person(name: String) { override def toString = name } + +@main def test: Unit = + val bill = Person("Bill") + val john = Person("John") + val mike = Person("Mike") + val todoList = List( + (bill, john, "Meeting", "Room 203, 11:00am"), + (john, mike, "Holiday", "March 22-24") + ) + // XML literals (to be dropped) + val mails1 = for (from, to, heading, body) <- todoList yield + + {from}{to} + {heading}{body} + + println(mails1) + // XML string interpolation + val mails2 = for (from, to, heading, body) <- todoList yield xml""" + + ${from}${to} + ${heading}${body} + """ + println(mails2) +``` + +For more information, see the semester project [XML String Interpolator for Dotty](https://infoscience.epfl.ch/record/267527) by Yassin Kammoun (2019). diff --git a/docs/_spec/TODOreference/enums/adts.md b/docs/_spec/TODOreference/enums/adts.md new file mode 100644 index 000000000000..3ab8c9f3b45b --- /dev/null +++ b/docs/_spec/TODOreference/enums/adts.md @@ -0,0 +1,173 @@ +--- +layout: doc-page +title: "Algebraic Data Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/enums/adts.html +--- + +The [`enum` concept](./enums.md) is general enough to also support algebraic data +types (ADTs) and their generalized version (GADTs). Here is an example +how an `Option` type can be represented as an ADT: + +```scala +enum Option[+T]: + case Some(x: T) + case None +``` + +This example introduces an `Option` enum with a covariant type +parameter `T` consisting of two cases, `Some` and `None`. `Some` is +parameterized with a value parameter `x`. It is a shorthand for writing a +case class that extends `Option`. Since `None` is not parameterized, it +is treated as a normal enum value. + +The `extends` clauses that were omitted in the example above can also +be given explicitly: + +```scala +enum Option[+T]: + case Some(x: T) extends Option[T] + case None extends Option[Nothing] +``` + +Note that the parent type of the `None` value is inferred as +`Option[Nothing]`. Generally, all covariant type parameters of the enum +class are minimized in a compiler-generated `extends` clause whereas all +contravariant type parameters are maximized. If `Option` was non-variant, +you would need to give the extends clause of `None` explicitly. + +As for normal enum values, the cases of an `enum` are all defined in +the `enum`s companion object. So it's `Option.Some` and `Option.None` +unless the definitions are "pulled out" with an import: + +```scala +scala> Option.Some("hello") +val res1: t2.Option[String] = Some(hello) + +scala> Option.None +val res2: t2.Option[Nothing] = None +``` + +Note that the type of the expressions above is always `Option`. Generally, the type of a enum case constructor application will be widened to the underlying enum type, unless a more specific type is expected. This is a subtle difference with respect to normal case classes. The classes making up the cases do exist, and can be unveiled, either by constructing them directly with a `new`, or by explicitly providing an expected type. + +```scala +scala> new Option.Some(2) +val res3: Option.Some[Int] = Some(2) +scala> val x: Option.Some[Int] = Option.Some(3) +val res4: Option.Some[Int] = Some(3) +``` + +As all other enums, ADTs can define methods. For instance, here is `Option` again, with an +`isDefined` method and an `Option(...)` constructor in its companion object. + +```scala +enum Option[+T]: + case Some(x: T) + case None + + def isDefined: Boolean = this match + case None => false + case _ => true + +object Option: + + def apply[T >: Null](x: T): Option[T] = + if x == null then None else Some(x) + +end Option +``` + +Enumerations and ADTs have been presented as two different +concepts. But since they share the same syntactic construct, they can +be seen simply as two ends of a spectrum and it is perfectly possible +to construct hybrids. For instance, the code below gives an +implementation of `Color` either with three enum values or with a +parameterized case that takes an RGB value. + +```scala +enum Color(val rgb: Int): + case Red extends Color(0xFF0000) + case Green extends Color(0x00FF00) + case Blue extends Color(0x0000FF) + case Mix(mix: Int) extends Color(mix) +``` + +## Parameter Variance of Enums + +By default, parameterized cases of enums with type parameters will copy the type parameters of their parent, along +with any variance notations. As usual, it is important to use type parameters carefully when they are variant, as shown +below: + +The following `View` enum has a contravariant type parameter `T` and a single case `Refl`, representing a function +mapping a type `T` to itself: + +```scala +enum View[-T]: + case Refl(f: T => T) +``` + +The definition of `Refl` is incorrect, as it uses contravariant type `T` in the covariant result position of a +function type, leading to the following error: + +```scala +-- Error: View.scala:2:12 -------- +2 | case Refl(f: T => T) + | ^^^^^^^^^ + |contravariant type T occurs in covariant position in type T => T of value f + |enum case Refl requires explicit declaration of type T to resolve this issue. +``` + +Because `Refl` does not declare explicit parameters, it looks to the compiler like the following: + +```scala +enum View[-T]: + case Refl[/*synthetic*/-T1](f: T1 => T1) extends View[T1] +``` + +The compiler has inferred for `Refl` the contravariant type parameter `T1`, following `T` in `View`. +We can now clearly see that `Refl` needs to declare its own non-variant type parameter to correctly type `f`, +and can remedy the error by the following change to `Refl`: + +```diff +enum View[-T]: +- case Refl(f: T => T) ++ case Refl[R](f: R => R) extends View[R] +``` + +Above, type `R` is chosen as the parameter for `Refl` to highlight that it has a different meaning to +type `T` in `View`, but any name will do. + +After some further changes, a more complete implementation of `View` can be given as follows and be used +as the function type `T => U`: + +```scala +enum View[-T, +U] extends (T => U): + case Refl[R](f: R => R) extends View[R, R] + + final def apply(t: T): U = this match + case refl: Refl[r] => refl.f(t) +``` + +## Syntax of Enums + +Changes to the syntax fall in two categories: enum definitions and cases inside enums. +The changes are specified below as deltas with respect to the Scala syntax given [here](../syntax.md) + + 1. Enum definitions are defined as follows: + + ``` + TmplDef ::= `enum' EnumDef + EnumDef ::= id ClassConstr [`extends' [ConstrApps]] EnumBody + EnumBody ::= [nl] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’ + EnumStat ::= TemplateStat + | {Annotation [nl]} {Modifier} EnumCase + ``` + + 2. Cases of enums are defined as follows: + + ``` + EnumCase ::= `case' (id ClassConstr [`extends' ConstrApps]] | ids) + ``` + +## Reference + +For more information, see [Issue #1970](https://github.com/lampepfl/dotty/issues/1970). diff --git a/docs/_spec/TODOreference/enums/desugarEnums.md b/docs/_spec/TODOreference/enums/desugarEnums.md new file mode 100644 index 000000000000..477653d670bb --- /dev/null +++ b/docs/_spec/TODOreference/enums/desugarEnums.md @@ -0,0 +1,215 @@ +--- +layout: doc-page +title: "Translation of Enums and ADTs" +nightlyOf: https://docs.scala-lang.org/scala3/reference/enums/desugarEnums.html +--- + +The compiler expands enums and their cases to code that only uses +Scala's other language features. As such, enums in Scala are +convenient _syntactic sugar_, but they are not essential to understand +Scala's core. + +We now explain the expansion of enums in detail. First, +some terminology and notational conventions: + + - We use `E` as a name of an enum, and `C` as a name of a case that appears in `E`. + - We use `<...>` for syntactic constructs that in some circumstances might be empty. For instance, + `` represents one or more parameter lists `(...)` or nothing at all. + + - Enum cases fall into three categories: + + - _Class cases_ are those cases that are parameterized, either with a type parameter section `[...]` or with one or more (possibly empty) parameter sections `(...)`. + - _Simple cases_ are cases of a non-generic enum that have neither parameters nor an extends clause or body. That is, they consist of a name only. + - _Value cases_ are all cases that do not have a parameter section but that do have a (possibly generated) `extends` clause and/or a body. + + Simple cases and value cases are collectively called _singleton cases_. + +The desugaring rules imply that class cases are mapped to case classes, and singleton cases are mapped to `val` definitions. + +There are nine desugaring rules. Rule (1) desugars enum definitions. Rules +(2) and (3) desugar simple cases. Rules (4) to (6) define `extends` clauses for cases that +are missing them. Rules (7) to (9) define how such cases with `extends` clauses +map into `case class`es or `val`s. + +1. An `enum` definition + ```scala + enum E ... { } + ``` + expands to a `sealed abstract` class that extends the `scala.reflect.Enum` trait and + an associated companion object that contains the defined cases, expanded according + to rules (2 - 8). The enum class starts with a compiler-generated import that imports + the names `` of all cases so that they can be used without prefix in the class. + ```scala + sealed abstract class E ... extends with scala.reflect.Enum { + import E.{ } + + } + object E { } + ``` + +2. A simple case consisting of a comma-separated list of enum names + ```scala + case C_1, ..., C_n + ``` + expands to + ```scala + case C_1; ...; case C_n + ``` + Any modifiers or annotations on the original case extend to all expanded + cases. + +3. A simple case + ```scala + case C + ``` + of an enum `E` that does not take type parameters expands to + ```scala + val C = $new(n, "C") + ``` + Here, `$new` is a private method that creates an instance of `E` (see + below). + +4. If `E` is an enum with type parameters + ```scala + V1 T1 >: L1 <: U1 , ... , Vn Tn >: Ln <: Un (n > 0) + ``` + where each of the variances `Vi` is either `'+'` or `'-'`, then a simple case + ```scala + case C + ``` + expands to + ```scala + case C extends E[B1, ..., Bn] + ``` + where `Bi` is `Li` if `Vi = '+'` and `Ui` if `Vi = '-'`. This result is then further + rewritten with rule (8). Simple cases of enums with non-variant type + parameters are not permitted (however value cases with explicit `extends` clause are) + +5. A class case without an extends clause + ```scala + case C + ``` + of an enum `E` that does not take type parameters expands to + ```scala + case C extends E + ``` + This result is then further rewritten with rule (9). + +6. If `E` is an enum with type parameters `Ts`, a class case with neither type parameters nor an extends clause + ```scala + case C + ``` + expands to + ```scala + case C[Ts] extends E[Ts] + ``` + This result is then further rewritten with rule (9). For class cases that have type parameters themselves, an extends clause needs to be given explicitly. + +7. If `E` is an enum with type parameters `Ts`, a class case without type parameters but with an extends clause + ```scala + case C extends + ``` + expands to + ```scala + case C[Ts] extends + ``` + provided at least one of the parameters `Ts` is mentioned in a parameter type in + `` or in a type argument in ``. + +8. A value case + ```scala + case C extends + ``` + expands to a value definition in `E`'s companion object: + ```scala + val C = new { ; def ordinal = n } + ``` + where `n` is the ordinal number of the case in the companion object, + starting from 0. The anonymous class also + implements the abstract `Product` methods that it inherits from `Enum`. + + It is an error if a value case refers to a type parameter of the enclosing `enum` + in a type argument of ``. + +9. A class case + ```scala + case C extends + ``` + expands analogous to a final case class in `E`'s companion object: + ```scala + final case class C extends + ``` + The enum case defines an `ordinal` method of the form + ```scala + def ordinal = n + ``` + where `n` is the ordinal number of the case in the companion object, + starting from 0. + + It is an error if a value case refers to a type parameter of the enclosing `enum` + in a parameter type in `` or in a type argument of ``, unless that parameter is already + a type parameter of the case, i.e. the parameter name is defined in ``. + + The compiler-generated `apply` and `copy` methods of an enum case + ```scala + case C(ps) extends P1, ..., Pn + ``` + are treated specially. A call `C(ts)` of the apply method is ascribed the underlying type + `P1 & ... & Pn` (dropping any [transparent traits](../other-new-features/transparent-traits.md)) + as long as that type is still compatible with the expected type at the point of application. + A call `t.copy(ts)` of `C`'s `copy` method is treated in the same way. + +## Translation of Enums with Singleton Cases + +An enum `E` (possibly generic) that defines one or more singleton cases +will define the following additional synthetic members in its companion object (where `E'` denotes `E` with +any type parameters replaced by wildcards): + + - A method `valueOf(name: String): E'`. It returns the singleton case value whose identifier is `name`. + - A method `values` which returns an `Array[E']` of all singleton case + values defined by `E`, in the order of their definitions. + +If `E` contains at least one simple case, its companion object will define in addition: + + - A private method `$new` which defines a new simple case value with given + ordinal number and name. This method can be thought as being defined as + follows. + + ```scala + private def $new(_$ordinal: Int, $name: String) = + new E with runtime.EnumValue: + def ordinal = _$ordinal + override def productPrefix = $name // if not overridden in `E` + override def toString = $name // if not overridden in `E` + ``` + +The anonymous class also implements the abstract `Product` methods that it inherits from `Enum`. +The `ordinal` method is only generated if the enum does not extend from `java.lang.Enum` (as Scala enums do not extend +`java.lang.Enum`s unless explicitly specified). In case it does, there is no need to generate `ordinal` as +`java.lang.Enum` defines it. Similarly there is no need to override `toString` as that is defined in terms of `name` in +`java.lang.Enum`. Finally, `productPrefix` will call `this.name` when `E` extends `java.lang.Enum`. + +## Scopes for Enum Cases + +A case in an `enum` is treated similarly to a secondary constructor. It can access neither the enclosing `enum` using `this`, nor its value parameters or instance members using simple +identifiers. + +Even though translated enum cases are located in the enum's companion object, referencing +this object or its members via `this` or a simple identifier is also illegal. The compiler typechecks enum cases in the scope of the enclosing companion object but flags any such illegal accesses as errors. + +## Translation of Java-compatible enums + +A Java-compatible enum is an enum that extends `java.lang.Enum`. The translation rules are the same as above, with the reservations defined in this section. + +It is a compile-time error for a Java-compatible enum to have class cases. + +Cases such as `case C` expand to a `@static val` as opposed to a `val`. This allows them to be generated as static fields of the enum type, thus ensuring they are represented the same way as Java enums. + +## Other Rules + +- A normal case class which is not produced from an enum case is not allowed to extend + `scala.reflect.Enum`. This ensures that the only cases of an enum are the ones that are + explicitly declared in it. + +- If an enum case has an `extends` clause, the enum class must be one of the + classes that's extended. diff --git a/docs/_spec/TODOreference/enums/enums-index.md b/docs/_spec/TODOreference/enums/enums-index.md new file mode 100644 index 000000000000..80d703c3e897 --- /dev/null +++ b/docs/_spec/TODOreference/enums/enums-index.md @@ -0,0 +1,7 @@ +--- +layout: index +title: "Enums" +nightlyOf: https://docs.scala-lang.org/scala3/reference/enums/index.html +--- + +This chapter documents enums in Scala 3. diff --git a/docs/_spec/TODOreference/enums/enums.md b/docs/_spec/TODOreference/enums/enums.md new file mode 100644 index 000000000000..65051bdfb39f --- /dev/null +++ b/docs/_spec/TODOreference/enums/enums.md @@ -0,0 +1,222 @@ +--- +layout: doc-page +title: "Enumerations" +nightlyOf: https://docs.scala-lang.org/scala3/reference/enums/enums.html +--- + +An enumeration is used to define a type consisting of a set of named values. + +```scala +enum Color: + case Red, Green, Blue +``` + +This defines a new `sealed` class, `Color`, with three values, `Color.Red`, +`Color.Green`, `Color.Blue`. The color values are members of `Color`s +companion object. + +## Parameterized enums + +Enums can be parameterized. + +```scala +enum Color(val rgb: Int): + case Red extends Color(0xFF0000) + case Green extends Color(0x00FF00) + case Blue extends Color(0x0000FF) +``` + +As the example shows, you can define the parameter value by using an +explicit extends clause. + +## Methods defined for enums + +The values of an enum correspond to unique integers. The integer +associated with an enum value is returned by its `ordinal` method: + +```scala +scala> val red = Color.Red +val red: Color = Red +scala> red.ordinal +val res0: Int = 0 +``` + +The companion object of an enum also defines three utility methods. +The `valueOf` method obtains an enum value +by its name. The `values` method returns all enum values +defined in an enumeration in an `Array`. The `fromOrdinal` +method obtains an enum value from its ordinal (`Int`) value. + +```scala +scala> Color.valueOf("Blue") +val res0: Color = Blue +scala> Color.values +val res1: Array[Color] = Array(Red, Green, Blue) +scala> Color.fromOrdinal(0) +val res2: Color = Red +``` + +## User-defined members of enums + +It is possible to add your own definitions to an enum. Example: + +```scala +enum Planet(mass: Double, radius: Double): + private final val G = 6.67300E-11 + def surfaceGravity = G * mass / (radius * radius) + def surfaceWeight(otherMass: Double) = otherMass * surfaceGravity + + case Mercury extends Planet(3.303e+23, 2.4397e6) + case Venus extends Planet(4.869e+24, 6.0518e6) + case Earth extends Planet(5.976e+24, 6.37814e6) + case Mars extends Planet(6.421e+23, 3.3972e6) + case Jupiter extends Planet(1.9e+27, 7.1492e7) + case Saturn extends Planet(5.688e+26, 6.0268e7) + case Uranus extends Planet(8.686e+25, 2.5559e7) + case Neptune extends Planet(1.024e+26, 2.4746e7) +end Planet +``` + +## User-defined companion object of enums +It is also possible to define an explicit companion object for an enum: + +```scala +object Planet: + def main(args: Array[String]) = + val earthWeight = args(0).toDouble + val mass = earthWeight / Earth.surfaceGravity + for p <- values do + println(s"Your weight on $p is ${p.surfaceWeight(mass)}") +end Planet +``` + +## Restrictions on Enum Cases + +Enum case declarations are similar to secondary constructors: +they are scoped outside of the enum template, despite being declared within it. +This means that enum case declarations cannot access inner members of the +enum class. + +Similarly, enum case declarations may not directly reference members of the enum's companion object, +even if they are imported (directly, or by renaming). For example: + +```scala +import Planet.* +enum Planet(mass: Double, radius: Double): + private final val (mercuryMass, mercuryRadius) = (3.303e+23, 2.4397e6) + + case Mercury extends Planet(mercuryMass, mercuryRadius) // Not found + case Venus extends Planet(venusMass, venusRadius) // illegal reference + case Earth extends Planet(Planet.earthMass, Planet.earthRadius) // ok +object Planet: + private final val (venusMass, venusRadius) = (4.869e+24, 6.0518e6) + private final val (earthMass, earthRadius) = (5.976e+24, 6.37814e6) +end Planet +``` +The fields referenced by `Mercury` are not visible, and the fields referenced by `Venus` may not +be referenced directly (using `import Planet.*`). You must use an indirect reference, +such as demonstrated with `Earth`. + +## Deprecation of Enum Cases + +As a library author, you may want to signal that an enum case is no longer intended for use. However you could still want to gracefully handle the removal of a case from your public API, such as special casing deprecated cases. + +To illustrate, say that the `Planet` enum originally had an additional case: + +```diff + enum Planet(mass: Double, radius: Double): + ... + case Neptune extends Planet(1.024e+26, 2.4746e7) ++ case Pluto extends Planet(1.309e+22, 1.1883e3) + end Planet +``` + +We now want to deprecate the `Pluto` case. First we add the `scala.deprecated` annotation to `Pluto`: + +```diff + enum Planet(mass: Double, radius: Double): + ... + case Neptune extends Planet(1.024e+26, 2.4746e7) +- case Pluto extends Planet(1.309e+22, 1.1883e3) ++ ++ @deprecated("refer to IAU definition of planet") ++ case Pluto extends Planet(1.309e+22, 1.1883e3) + end Planet +``` + +Outside the lexical scopes of `enum Planet` or `object Planet`, references to `Planet.Pluto` will produce a deprecation warning, but within those scopes we can still reference it to implement introspection over the deprecated cases: + +```scala +trait Deprecations[T <: reflect.Enum] { + extension (t: T) def isDeprecatedCase: Boolean +} + +object Planet { + given Deprecations[Planet] with { + extension (p: Planet) + def isDeprecatedCase = p == Pluto + } +} +``` + +We could imagine that a library may use [type class derivation](../contextual/derivation.md) to automatically provide an instance for `Deprecations`. + +## Compatibility with Java Enums + +If you want to use the Scala-defined enums as [Java enums](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html), you can do so by extending +the class `java.lang.Enum`, which is imported by default, as follows: + +```scala +enum Color extends Enum[Color] { case Red, Green, Blue } +``` + +The type parameter comes from the Java enum [definition](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Enum.html) and should be the same as the type of the enum. +There is no need to provide constructor arguments (as defined in the Java API docs) to `java.lang.Enum` when extending it – the compiler will generate them automatically. + +After defining `Color` like that, you can use it like you would a Java enum: + +```scala +scala> Color.Red.compareTo(Color.Green) +val res15: Int = -1 +``` + +For a more in-depth example of using Scala 3 enums from Java, see [this test](https://github.com/lampepfl/dotty/tree/main/tests/run/enum-java). In the test, the enums are defined in the `MainScala.scala` file and used from a Java source, `Test.java`. + +## Implementation + +Enums are represented as `sealed` classes that extend the `scala.reflect.Enum` trait. +This trait defines a single public method, `ordinal`: + +```scala +package scala.reflect + +/** A base trait of all Scala enum definitions */ +transparent trait Enum extends Any, Product, Serializable: + + /** A number uniquely identifying a case of an enum */ + def ordinal: Int +``` + +Enum values with `extends` clauses get expanded to anonymous class instances. +For instance, the `Venus` value above would be defined like this: + +```scala +val Venus: Planet = new Planet(4.869E24, 6051800.0): + def ordinal: Int = 1 + override def productPrefix: String = "Venus" + override def toString: String = "Venus" +``` + +Enum values without `extends` clauses all share a single implementation +that can be instantiated using a private method that takes a tag and a name as arguments. +For instance, the first +definition of value `Color.Red` above would expand to: + +```scala +val Red: Color = $new(0, "Red") +``` + +## Reference + +For more information, see [Issue #1970](https://github.com/lampepfl/dotty/issues/1970) and +[PR #4003](https://github.com/lampepfl/dotty/pull/4003). diff --git a/docs/_spec/TODOreference/experimental/canthrow.md b/docs/_spec/TODOreference/experimental/canthrow.md new file mode 100644 index 000000000000..025a0ed1c686 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/canthrow.md @@ -0,0 +1,281 @@ +--- +layout: doc-page +title: "CanThrow Capabilities" +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/canthrow.html +--- + +This page describes experimental support for exception checking in Scala 3. It is enabled by the language import +```scala +import language.experimental.saferExceptions +``` +The reason for publishing this extension now is to get feedback on its usability. We are working on more advanced type systems that build on the general ideas put forward in the extension. Those type systems have application areas beyond checked exceptions. Exception checking is a useful starting point since exceptions are familiar to all Scala programmers and their current treatment leaves room for improvement. + +## Why Exceptions? + +Exceptions are an ideal mechanism for error handling in many situations. They serve the intended purpose of propagating error conditions with a minimum of boilerplate. They cause zero overhead for the "happy path", which means they are very efficient as long as errors arise infrequently. Exceptions are also debug friendly, since they produce stack traces that can be inspected at the handler site. So one never has to guess where an erroneous condition originated. + +## Why Not Exceptions? + +However, exceptions in current Scala and many other languages are not reflected in the type system. This means that an essential part of the contract of a function - i.e. what exceptions can it produce? - is not statically checked. Most people acknowledge that this is a problem, but that so far the alternative of checked exceptions was just too painful to be considered. A good example are Java checked exceptions, which do the right thing in principle, but are widely regarded as a mistake since they are so difficult to deal with. So far, none of the successor languages that are modeled after Java or that build on the JVM has copied this feature. See for example Anders Hejlsberg's [statement on why C# does not have checked exceptions](https://www.artima.com/articles/the-trouble-with-checked-exceptions). + +## The Problem With Java's Checked Exceptions + +The main problem with [Java's checked exception model](https://docs.oracle.com/javase/specs/jls/se8/html/jls-11.html#jls-11.2) is its inflexibility, which is due to lack of polymorphism. Consider for instance the `map` function which is declared on `List[A]` like this: +```scala + def map[B](f: A => B): List[B] +``` +In the Java model, function `f` is not allowed to throw a checked exception. So the following call would be invalid: +```scala + xs.map(x => if x < limit then x * x else throw LimitExceeded()) +``` +The only way around this would be to wrap the checked exception `LimitExceeded` in an unchecked [`java.lang.RuntimeException`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/RuntimeException.html) that is caught at the callsite and unwrapped again. Something like this: +```scala + try + xs.map(x => if x < limit then x * x else throw Wrapper(LimitExceeded())) + catch case Wrapper(ex) => throw ex +``` +Ugh! No wonder checked exceptions in Java are not very popular. + +## Monadic Effects + +So the dilemma is that exceptions are easy to use only as long as we forget static type checking. This has caused many people working with Scala to abandon exceptions altogether and to use an error monad like [`Either`](https://scala-lang.org/api/3.x/scala/util/Either.html) instead. This can work in many situations but is not without its downsides either. It makes code a lot more complicated and harder to refactor. It means one is quickly confronted with the problem how to work with several monads. In general, dealing with one monad at a time in Scala is straightforward but dealing with several monads together is much less pleasant since monads don't compose. A great number of techniques have been proposed, implemented, and promoted to deal with this, from monad transformers, to free monads, to tagless final. But none of these techniques is universally liked; each introduces a complicated DSL that's hard to understand for non-experts, introduces runtime overheads, and makes debugging difficult. In the end, quite a few developers prefer to work instead with a single "super-monad" like [`ZIO`](https://zio.dev/version-1.x/datatypes/core/zio) that has error propagation built in alongside other aspects. This one-size fits all approach can work very nicely, even though (or is it because?) it represents an all-encompassing framework. + +However, a programming language is not a framework; it has to cater also for those applications that do not fit the framework's use cases. So there's still a strong motivation for getting exception checking right. + +## From Effects To Capabilities + +Why does `map` work so poorly with Java's checked exception model? It's because +`map`'s signature limits function arguments to not throw checked exceptions. We could try to come up with a more polymorphic formulation of `map`. For instance, it could look like this: +```scala + def map[B, E](f: A => B throws E): List[B] throws E +``` +This assumes a type `A throws E` to indicate computations of type `A` that can throw an exception of type `E`. But in practice the overhead of the additional type parameters makes this approach unappealing as well. Note in particular that we'd have to parameterize _every method_ that takes a function argument that way, so the added overhead of declaring all these exception types looks just like a sort of ceremony we would like to avoid. + +But there is a way to avoid the ceremony. Instead of concentrating on possible _effects_ such as "this code might throw an exception", concentrate on _capabilities_ such as "this code needs the capability to throw an exception". From a standpoint of expressiveness this is quite similar. But capabilities can be expressed as parameters whereas traditionally effects are expressed as some addition to result values. It turns out that this can make a big difference! + +## The `CanThrow` Capability + +In the _effects as capabilities_ model, an effect is expressed as an (implicit) parameter of a certain type. For exceptions we would expect parameters of type +[`CanThrow[E]`](https://scala-lang.org/api/3.x/scala/CanThrow.html) where `E` stands for the exception that can be thrown. Here is the definition of `CanThrow`: +```scala +erased class CanThrow[-E <: Exception] +``` +This shows another experimental Scala feature: [erased definitions](./erased-defs.md). Roughly speaking, values of an erased class do not generate runtime code; they are erased before code generation. This means that all `CanThrow` capabilities are compile-time only artifacts; they do not have a runtime footprint. + +Now, if the compiler sees a `throw Exc()` construct where `Exc` is a checked exception, it will check that there is a capability of type `CanThrow[Exc]` that can be summoned as a given. It's a compile-time error if that's not the case. + +How can the capability be produced? There are several possibilities: + +Most often, the capability is produced by having a using clause `(using CanThrow[Exc])` in some enclosing scope. This roughly corresponds to a [`throws`](https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.6) clause in Java. The analogy is even stronger since alongside [`CanThrow`](https://scala-lang.org/api/3.x/scala/CanThrow.html) there is also the following type alias defined in the [`scala`](https://scala-lang.org/api/3.x/scala.html) package: +```scala +infix type A = Int +``` +```scala +infix type $throws[R, +E <: Exception] = CanThrow[E] ?=> R +``` +That is, [`R $throws E`](https://scala-lang.org/api/3.x/scala/runtime.html#$throws-0) is a context function type that takes an implicit `CanThrow[E]` parameter and that returns a value of type `R`. What's more, the compiler will translate an infix types with `throws` as the operator to `$throws` applications according to the rules +``` + A throws E --> A $throws E + A throws E₁ | ... | Eᵢ --> A $throws E₁ ... $throws Eᵢ +``` +Therefore, a method written like this: +```scala +def m(x: T)(using CanThrow[E]): U +``` +can alternatively be expressed like this: +```scala +def m(x: T): U throws E +``` +Also the capability to throw multiple types of exceptions can be expressed in a few ways as shown in the examples below: +```scala +def m(x: T): U throws E1 | E2 +def m(x: T): U throws E1 throws E2 +def m(x: T)(using CanThrow[E1], CanThrow[E2]): U +def m(x: T)(using CanThrow[E1])(using CanThrow[E2]): U +def m(x: T)(using CanThrow[E1]): U throws E2 +``` + +**Note 1:** A signature like +```scala +def m(x: T)(using CanThrow[E1 | E2]): U +``` +would also allow throwing `E1` or `E2` inside the method's body but might cause problems when someone tried to call this method +from another method declaring its `CanThrow` capabilities like in the earlier examples. +This is because `CanThrow` has a contravariant type parameter so `CanThrow[E1 | E2]` is a subtype of both `CanThrow[E1]` and `CanThrow[E2]`. +Hence the presence of a given instance of `CanThrow[E1 | E2]` in scope satisfies the requirement for `CanThrow[E1]` and `CanThrow[E2]` +but given instances of `CanThrow[E1]` and `CanThrow[E2]` cannot be combined to provide and instance of `CanThrow[E1 | E2]`. + +**Note 2:** One should keep in mind that `|` binds its left and right arguments more tightly than `throws` so `A | B throws E1 | E2` means `(A | B) throws (Ex1 | Ex2)`, not `A | (B throws E1) | E2`. + +The `CanThrow`/`throws` combo essentially propagates the `CanThrow` requirement outwards. But where are these capabilities created in the first place? That's in the `try` expression. Given a `try` like this: + +```scala +try + body +catch + case ex1: Ex1 => handler1 + ... + case exN: ExN => handlerN +``` +the compiler generates an accumulated capability of type `CanThrow[Ex1 | ... | Ex2]` that is available as a given in the scope of `body`. It does this by augmenting the `try` roughly as follows: +```scala +try + erased given CanThrow[Ex1 | ... | ExN] = compiletime.erasedValue + body +catch ... +``` +Note that the right-hand side of the synthesized given is `???` (undefined). This is OK since +this given is erased; it will not be executed at runtime. + +**Note 1:** The [`saferExceptions`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$experimental$$saferExceptions$.html) feature is designed to work only with checked exceptions. An exception type is _checked_ if it is a subtype of +`Exception` but not of `RuntimeException`. The signature of `CanThrow` still admits `RuntimeException`s since `RuntimeException` is a proper subtype of its bound, `Exception`. But no capabilities will be generated for `RuntimeException`s. Furthermore, `throws` clauses +also may not refer to `RuntimeException`s. + +**Note 2:** To keep things simple, the compiler will currently only generate capabilities +for catch clauses of the form +```scala + case ex: Ex => +``` +where `ex` is an arbitrary variable name (`_` is also allowed), and `Ex` is an arbitrary +checked exception type. Constructor patterns such as `Ex(...)` or patterns with guards +are not allowed. The compiler will issue an error if one of these is used to catch +a checked exception and `saferExceptions` is enabled. + +## Example + +That's it. Let's see it in action in an example. First, add an import +```scala +import language.experimental.saferExceptions +``` +to enable exception checking. Now, define an exception `LimitExceeded` and +a function `f` like this: +```scala +val limit = 10e9 +class LimitExceeded extends Exception +def f(x: Double): Double = + if x < limit then x * x else throw LimitExceeded() +``` +You'll get this error message: +``` + if x < limit then x * x else throw LimitExceeded() + ^^^^^^^^^^^^^^^^^^^^^ +The capability to throw exception LimitExceeded is missing. +``` +The capability can be provided by one of the following: + + - Adding a using clause `(using CanThrow[LimitExceeded])` to the definition of the enclosing method + - Adding `throws LimitExceeded` clause after the result type of the enclosing method + - Wrapping this piece of code with a `try` block that catches `LimitExceeded` + +The following import might fix the problem: +```scala + import unsafeExceptions.canThrowAny +``` +As the error message implies, you have to declare that `f` needs the capability to throw a `LimitExceeded` exception. The most concise way to do so is to add a `throws` clause: +```scala +def f(x: Double): Double throws LimitExceeded = + if x < limit then x * x else throw LimitExceeded() +``` +Now put a call to `f` in a `try` that catches `LimitExceeded`: +```scala +@main def test(xs: Double*) = + try println(xs.map(f).sum) + catch case ex: LimitExceeded => println("too large") +``` +Run the program with some inputs: +``` +> scala test 1 2 3 +14.0 +> scala test +0.0 +> scala test 1 2 3 100000000000 +too large +``` +Everything typechecks and works as expected. But wait - we have called `map` without any ceremony! How did that work? Here's how the compiler expands the `test` function: +```scala +// compiler-generated code +@main def test(xs: Double*) = + try + erased given ctl: CanThrow[LimitExceeded] = compiletime.erasedValue + println(xs.map(x => f(x)(using ctl)).sum) + catch case ex: LimitExceeded => println("too large") +``` +The `CanThrow[LimitExceeded]` capability is passed in a synthesized `using` clause to `f`, since `f` requires it. Then the resulting closure is passed to `map`. The signature of `map` does not have to account for effects. It takes a closure as always, but that +closure may refer to capabilities in its free variables. This means that `map` is +already effect polymorphic even though we did not change its signature at all. +So the takeaway is that the effects as capabilities model naturally provides for effect polymorphism whereas this is something that other approaches struggle with. + +## Gradual Typing Via Imports + +Another advantage is that the model allows a gradual migration from current unchecked exceptions to safer exceptions. Imagine for a moment that [`experimental.saferExceptions`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$experimental$$saferExceptions$.html) is turned on everywhere. There would be lots of code that breaks since functions have not yet been properly annotated with `throws`. But it's easy to create an escape hatch that lets us ignore the breakages for a while: simply add the import +```scala +import scala.unsafeExceptions.canThrowAny +``` +This will provide the [`CanThrow`](https://scala-lang.org/api/3.x/scala/CanThrow.html) capability for any exception, and thereby allow +all throws and all other calls, no matter what the current state of `throws` declarations is. Here's the +definition of [`canThrowAny`](https://scala-lang.org/api/3.x/scala/unsafeExceptions$.html#canThrowAny-0): +```scala +package scala +object unsafeExceptions: + given canThrowAny: CanThrow[Exception] = ??? +``` +Of course, defining a global capability like this amounts to cheating. But the cheating is useful for gradual typing. The import could be used to migrate existing code, or to +enable more fluid explorations of code without regard for complete exception safety. At the end of these migrations or explorations the import should be removed. + +## Scope Of the Extension + +To summarize, the extension for safer exception checking consists of the following elements: + + - It adds to the standard library the class `scala.CanThrow`, the type `scala.$throws`, and the [`scala.unsafeExceptions`](https://scala-lang.org/api/3.x/scala/unsafeExceptions$.html) object, as they were described above. + - It adds some desugaring rules ro rewrite `throws` types to cascaded `$throws` types. + - It augments the type checking of `throw` by _demanding_ a `CanThrow` capability or the thrown exception. + - It augments the type checking of `try` by _providing_ `CanThrow` capabilities for every caught exception. + +That's all. It's quite remarkable that one can do exception checking in this way without any special additions to the type system. We just need regular givens and context functions. Any runtime overhead is eliminated using `erased`. + +## Caveats + +Our capability model allows to declare and check the thrown exceptions of first-order code. But as it stands, it does not give us enough mechanism to enforce the _absence_ of +capabilities for arguments to higher-order functions. Consider a variant `pureMap` +of `map` that should enforce that its argument does not throw exceptions or have any other effects (maybe because wants to reorder computations transparently). Right now +we cannot enforce that since the function argument to `pureMap` can capture arbitrary +capabilities in its free variables without them showing up in its type. One possible way to +address this would be to introduce a pure function type (maybe written `A -> B`). Pure functions are not allowed to close over capabilities. Then `pureMap` could be written +like this: +```scala + def pureMap(f: A -> B): List[B] +``` +Another area where the lack of purity requirements shows up is when capabilities escape from bounded scopes. Consider the following function +```scala +def escaped(xs: Double*): () => Int = + try () => xs.map(f).sum + catch case ex: LimitExceeded => -1 +``` +With the system presented here, this function typechecks, with expansion +```scala +// compiler-generated code +def escaped(xs: Double*): () => Int = + try + given ctl: CanThrow[LimitExceeded] = ??? + () => xs.map(x => f(x)(using ctl)).sum + catch case ex: LimitExceeded => -1 +``` +But if you try to call `escaped` like this +```scala +val g = escaped(1, 2, 1000000000) +g() +``` +the result will be a `LimitExceeded` exception thrown at the second line where `g` is called. What's missing is that `try` should enforce that the capabilities it generates do not escape as free variables in the result of its body. It makes sense to describe such scoped effects as _ephemeral capabilities_ - they have lifetimes that cannot be extended to delayed code in a lambda. + + +## Outlook + +We are working on a new class of type system that supports ephemeral capabilities by tracking the free variables of values. Once that research matures, it will hopefully be possible to augment the Scala language so that we can enforce the missing properties. + +And it would have many other applications besides: Exceptions are a special case of _algebraic effects_, which has been a very active research area over the last 20 years and is finding its way into programming languages (e.g. [Koka](https://koka-lang.github.io/koka/doc/book.html#why-handlers), [Eff](https://www.eff-lang.org/learn/), [Multicore OCaml](https://discuss.ocaml.org/t/multicore-ocaml-september-2021-effect-handlers-will-be-in-ocaml-5-0/8554), [Unison](https://www.unisonweb.org/docs/language-reference/#abilities-and-ability-handlers)). In fact, algebraic effects have been characterized as being equivalent to exceptions with an additional _resume_ operation. The techniques developed here for exceptions can probably be generalized to other classes of algebraic effects. + +But even without these additional mechanisms, exception checking is already useful as it is. It gives a clear path forward to make code that uses exceptions safer, better documented, and easier to refactor. The only loophole arises for scoped capabilities - here we have to verify manually that these capabilities do not escape. Specifically, a `try` always has to be placed in the same computation stage as the throws that it enables. + +Put another way: If the status quo is 0% static checking since 100% is too painful, then an alternative that gives you 95% static checking with great ergonomics looks like a win. And we might still get to 100% in the future. + +For more info, see also our [paper at the ACM Scala Symposium 2021](https://infoscience.epfl.ch/record/290885). diff --git a/docs/_spec/TODOreference/experimental/cc.md b/docs/_spec/TODOreference/experimental/cc.md new file mode 100644 index 000000000000..878bc0a64ed6 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/cc.md @@ -0,0 +1,738 @@ +--- +layout: doc-page +title: "Capture Checking" +--- + +Capture checking is a research project that modifies the Scala type system to track references to capabilities in values. It can be enabled with a `-Ycc` compiler option. +At present, capture checking is still highly experimental and unstable. + +To get an idea what capture checking can do, let's start with a small example: +```scala +def usingLogFile[T](op: FileOutputStream => T): T = + val logFile = FileOutputStream("log") + val result = op(logFile) + logFile.close() + result +``` +The `usingLogFile` method invokes a given operation with a fresh log file as parameter. Once the operation has ended, the log file is closed and the +operation's result is returned. This is a typical _try-with-resources_ pattern, similar to many other such patterns which are often supported by special language constructs in other languages. + +The problem is that `usingLogFile`'s implementation is not entirely safe. One can +undermine it by passing an operation that performs the logging at some later point +after it has terminated. For instance: +```scala +val later = usingLogFile { file => () => file.write(0) } +later() // crash +``` +When `later` is executed it tries to write to a file that is already closed, which +results in an uncaught `IOException`. + +Capture checking gives us the mechanism to prevent such errors _statically_. To +prevent unsafe usages of `usingLogFile`, we can declare it like this: +```scala +def usingLogFile[T](op: ({*} FileOutputStream) => T): T = + // same body as before +``` +The only thing that's changed is that the `FileOutputStream` parameter of `op` is now +tagged with `{*}`. We'll see that this turns the parameter into a _capability_ whose lifetime is tracked. + +If we now try to define the problematic value `later`, we get a static error: +``` + | val later = usingLogFile { f => () => f.write(0) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |The expression's type {*} () -> Unit is not allowed to capture the root capability `*`. + |This usually means that a capability persists longer than its allowed lifetime. +``` +In this case, it was easy to see that the `logFile` capability escapes in the closure passed to `usingLogFile`. But capture checking also works for more complex cases. +For instance, capture checking is able to distinguish between the following safe code: +```scala +val xs = usingLogFile { f => + List(1, 2, 3).map { x => f.write(x); x * x } +} +``` +and the following unsafe one: +```scala +val xs = usingLogFile { f => + LazyList(1, 2, 3).map { x => f.write(x); x * x } +} +``` +An error would be issued in the second case, but not the first one (this assumes a capture-aware +formulation of `LazyList` which we will present later in this page). + +It turns out that capture checking has very broad applications. Besides the various +try-with-resources patterns, it can also be a key part to the solutions of many other long standing problems in programming languages. Among them: + + - How to have a simple and flexible system for checked exceptions. We show later + how capture checking enables a clean and fully safe system for checked exceptions in Scala. + - How to address the problem of effect polymorphism in general. + - How to solve the "what color is your function?" problem of mixing synchronous + and asynchronous computations. + - How to do region-based allocation, safely, + - How to reason about capabilities associated with memory locations. + +The following sections explain in detail how capture checking works in Scala 3. + + +## Overview + +The capture checker extension introduces a new kind of types and it enforces some rules for working with these types. + +Capture checking is enabled by the compiler option `-Ycc`. If the option is not given, the new +type forms can still be written but they are not checked for consistency, because they are +treated simply as certain uninterpreted annotated types. + +## Capabilities and Capturing Types + +Capture checking is done in terms of _capturing types_ of the form +`{c₁, ..., cᵢ} T`. Here `T` is a type, and `{c₁, ..., cᵢ}` is a _capture set_ consisting of references to capabilities `c₁, ..., cᵢ`. + +A _capability_ is syntactically a method- or class-parameter, a local variable, or the `this` of an enclosing class. The type of a capability +must be a capturing type with a non-empty capture set. We also say that +variables that are capabilities are _tracked_. + +In a sense, every +capability gets its authority from some other, more sweeping capability which it captures. The most sweeping capability, from which ultimately all others are derived is written `*`. We call it the _universal capability_. + +Here is an example: +```scala +class FileSystem + +class Logger(fs: {*} FileSystem): + def log(s: String): Unit = ... // Write to a log file, using `fs` + +def test(fs: {*} FileSystem) = + val l: {fs} Logger = Logger(fs) + l.log("hello world!") + val xs: {l} LazyList[Int] = + LazyList.from(1) + .map { i => + l.log(s"computing elem # $i") + i * i + } + xs +``` +Here, the `test` method takes a `FileSystem` as a parameter. `fs` is a capability since its type has a non-empty capture set. The capability is passed to the `Logger` constructor +and retained as a field in class `Logger`. Hence, the local variable `l` has type +`{fs} Logger`: it is a `Logger` which retains the `fs` capability. + +The second variable defined in `test` is `xs`, a lazy list that is obtained from +`LazyList.from(1)` by logging and mapping consecutive numbers. Since the list is lazy, +it needs to retain the reference to the logger `l` for its computations. Hence, the +type of the list is `{l} LazyList[Int]`. On the other hand, since `xs` only logs but does +not do other file operations, it retains the `fs` capability only indirectly. That's why +`fs` does not show up in the capture set of `xs`. + +Capturing types come with a subtype relation where types with "smaller" capture sets are subtypes of types with larger sets (the _subcapturing_ relation is defined in more detail below). If a type `T` does not have a capture set, it is called _pure_, and is a subtype of +any capturing type that adds a capture set to `T`. + +## Function Types + +The usual function type `A => B` now stands for a function that can capture arbitrary capabilities. We call such functions +_impure_. By contrast, the new single arrow function type `A -> B` stands for a function that cannot capture any capabilities, or otherwise said, is _pure_. One can add a capture set in front of an otherwise pure function. +For instance, `{c, d} A -> B` would be a function that can capture capabilities `c` and `d`, but no others. + +The impure function type `A => B` is treated as an alias for `{*} A -> B`. That is, impure functions are functions that can capture anything. + +Function types and captures both associate to the right, so +```scala +{c} A -> {d} B -> C +``` +is the same as +```scala +{c} (A -> {d} (B -> C)) +``` +Contrast with +```scala +({c} A) -> ({d} B) -> C +``` +which is a curried pure function over argument types that can capture `c` and `d`, respectively. + +Analogous conventions apply to context function types. `A ?=> B` is an impure context function, with `A ?-> B` as its pure complement. + +**Note 1:** The identifiers `->` and `?->` are now treated as soft keywords when used as infix type operators. They are +still available as regular identifiers for terms. For instance, the mapping syntax `Map("x" -> 1, "y" -> 2)` is still supported since it only applies to terms. + +**Note 2:** The distinctions between pure vs impure function types do not apply to methods. In fact, since methods are not values they never capture anything directly. References to +capabilities in a method are instead counted in the capture set of the enclosing object. + +## By-Name Parameter Types + +A convention analogous to function types also extends to by-name parameters. In +```scala +def f(x: => Int): Int +``` +the actual argument can refer to arbitrary capabilities. So the following would be OK: +```scala +f(if p(y) then throw Ex() else 1) +``` +On the other hand, if `f` was defined like this +```scala +def f(x: -> Int): Int +``` +the actual argument to `f` could not refer to any capabilities, so the call above would be rejected. +One can also allow specific capabilities like this: +```scala +def f(x: {c}-> Int): Int +``` +Here, the actual argument to `f` is allowed to use the `c` capability but no others. + +**Note**: It is strongly recommended to write the capability set and the arrow `->` without intervening spaces, +as otherwise the notation would look confusingly like a function type. + +## Subtyping and Subcapturing + +Capturing influences subtyping. As usual we write `T₁ <: T₂` to express that the type +`T₁` is a subtype of the type `T₂`, or equivalently, that `T₁` conforms to `T₂`. An +analogous _subcapturing_ relation applies to capture sets. If `C₁` and `C₂` are capture sets, we write `C₁ <: C₂` to express that `C₁` _is covered by_ `C₂`, or, swapping the operands, that `C₂` _covers_ `C₁`. + +Subtyping extends as follows to capturing types: + + - Pure types are subtypes of capturing types. That is, `T <: C T`, for any type `T`, capturing set `C`. + - For capturing types, smaller capturing sets produce subtypes: `C₁ T₁ <: C₂ T₂` if + `C₁ <: C₂` and `T₁ <: T₂`. + +A subcapturing relation `C₁ <: C₂` holds if `C₂` _accounts for_ every element `c` in `C₁`. This means one of the following three conditions must be true: + + - `c ∈ C₂`, + - `c` refers to a parameter of some class `Cls` and `C₂` contains `Cls.this`, + - `c`'s type has capturing set `C` and `C₂` accounts for every element of `C` (that is, `C <: C₂`). + + +**Example 1.** Given +```scala +fs: {*} FileSystem +ct: {*} CanThrow[Exception] +l : {fs} Logger +``` +we have +``` +{l} <: {fs} <: {*} +{fs} <: {fs, ct} <: {*} +{ct} <: {fs, ct} <: {*} +``` +The set consisting of the root capability `{*}` covers every other capture set. This is +a consequence of the fact that, ultimately, every capability is created from `*`. + +**Example 2.** Consider again the FileSystem/Logger example from before. `LazyList[Int]` is a proper subtype of `{l} LazyList[Int]`. So if the `test` method in that example +was declared with a result type `LazyList[Int]`, we'd get a type error. Here is the error message: +``` +11 |def test(using fs: {*} FileSystem): LazyList[Int] = { + | ^ + | Found: {fs} LazyList[Int] + | Required: LazyList[Int] +``` +Why does it say `{fs} LazyList[Int]` and not `{l} LazyList[Int]`, which is, after all, the type of the returned value `xs`? The reason is that `l` is a local variable in the body of `test`, so it cannot be referred to in a type outside that body. What happens instead is that the type is _widened_ to the smallest supertype that does not mention `l`. Since `l` has capture set `fs`, we have that `{fs}` covers `{l}`, and `{fs}` is acceptable in a result type of `test`, so `{fs}` is the result of that widening. +This widening is called _avoidance_; it is not specific to capture checking but applies to all variable references in Scala types. + +## Capability Classes + +Classes like `CanThrow` or `FileSystem` have the property that their values are always intended to be capabilities. We can make this intention explicit and save boilerplate by declaring these classes with a `@capability` annotation. + +The capture set of a capability class type is always `{*}`. This means we could equivalently express the `FileSystem` and `Logger` classes as follows: +```scala +import annotation.capability + +@capability class FileSystem + +class Logger(using FileSystem): + def log(s: String): Unit = ??? + +def test(using fs: FileSystem) = + val l: {fs} Logger = Logger() + ... +``` +In this version, `FileSystem` is a capability class, which means that the `{*}` capture set is implied on the parameters of `Logger` and `test`. Writing the capture set explicitly produces a warning: +```scala +class Logger(using {*} FileSystem): + ^^^^^^^^^^^^^^ + redundant capture: FileSystem already accounts for * +``` +Another, unrelated change in the version of the last example here is that the `FileSystem` capability is now passed as an implicit parameter. It is quite natural to model capabilities with implicit parameters since it greatly reduces the wiring overhead once multiple capabilities are in play. + +## Capture Checking of Closures + +If a closure refers to capabilities in its body, it captures these capabilities in its type. For instance, consider: +```scala +def test(fs: FileSystem): {fs} String -> Unit = + (x: String) => Logger(fs).log(x) +``` +Here, the body of `test` is a lambda that refers to the capability `fs`, which means that `fs` is retained in the lambda. +Consequently, the type of the lambda is `{fs} String -> Unit`. + +**Note:** Function values are always written with `=>` (or `?=>` for context functions). There is no syntactic +distinction for pure _vs_ impure function values. The distinction is only made in their types. + +A closure also captures all capabilities that are captured by the functions +it calls. For instance, in +```scala +def test(fs: FileSystem) = + def f() = g() + def g() = (x: String) => Logger(fs).log(x) + f +``` +the result of `test` has type `{fs} String -> Unit` even though function `f` itself does not refer to `fs`. + +## Capture Checking of Classes + +The principles for capture checking closures also apply to classes. For instance, consider: +```scala +class Logger(using fs: FileSystem): + def log(s: String): Unit = ... summon[FileSystem] ... + +def test(xfs: FileSystem): {xfs} Logger = + Logger(xfs) +``` +Here, class `Logger` retains the capability `fs` as a (private) field. Hence, the result +of `test` is of type `{xfs} Logger` + +Sometimes, a tracked capability is meant to be used only in the constructor of a class, but +is not intended to be retained as a field. This fact can be communicated to the capture +checker by declaring the parameter as `@constructorOnly`. Example: +```scala +import annotation.constructorOnly + +class NullLogger(using @constructorOnly fs: FileSystem): + ... +def test2(using fs: FileSystem): NullLogger = NullLogger() // OK +``` + +The captured references of a class include _local capabilities_ and _argument capabilities_. Local capabilities are capabilities defined outside the class and referenced from its body. Argument capabilities are passed as parameters to the primary constructor of the class. Local capabilities are inherited: +the local capabilities of a superclass are also local capabilities of its subclasses. Example: + +```scala +@capability class Cap + +def test(a: Cap, b: Cap, c: Cap) = + class Super(y: Cap): + def f = a + class Sub(x: Cap) extends Super(x) + def g = b + Sub(c) +``` +Here class `Super` has local capability `a`, which gets inherited by class +`Sub` and is combined with `Sub`'s own local capability `b`. Class `Sub` also has an argument capability corresponding to its parameter `x`. This capability gets instantiated to `c` in the final constructor call `Sub(c)`. Hence, +the capture set of that call is `{a, b, c}`. + +The capture set of the type of `this` of a class is inferred by the capture checker, unless the type is explicitly declared with a self type annotation like this one: +```scala +class C: + self: {a, b} D => ... +``` +The inference observes the following constraints: + + - The type of `this` of a class `C` includes all captured references of `C`. + - The type of `this` of a class `C` is a subtype of the type of `this` + of each parent class of `C`. + - The type of `this` must observe all constraints where `this` is used. + +For instance, in +```scala +@capability class Cap +def test(c: Cap) = + class A: + val x: A = this + def f = println(c) // error +``` +we know that the type of `this` must be pure, since `this` is the right hand side of a `val` with type `A`. However, in the last line we find that the capture set of the class, and with it the capture set of `this`, would include `c`. This leads to a contradiction, and hence to a checking error: +``` +16 | def f = println(c) // error + | ^ + |(c : Cap) cannot be referenced here; it is not included in the allowed capture set {} +``` + +## Capture Tunnelling + +Consider the following simple definition of a `Pair` class: +```scala +class Pair[+A, +B](x: A, y: B): + def fst: A = x + def snd: B = y +``` +What happens if `Pair` is instantiated like this (assuming `ct` and `fs` are two capabilities in scope)? +```scala +def x: {ct} Int -> String +def y: {fs} Logger +def p = Pair(x, y) +``` +The last line will be typed as follows: +```scala +def p: Pair[{ct} Int -> String, {fs} Logger] = Pair(x, y) +``` +This might seem surprising. The `Pair(x, y)` value does capture capabilities `ct` and `fs`. Why don't they show up in its type at the outside? + +The answer is capture tunnelling. Once a type variable is instantiated to a capturing type, the +capture is not propagated beyond this point. On the other hand, if the type variable is instantiated +again on access, the capture information "pops out" again. For instance, even though `p` is technically pure because its capture set is empty, writing `p.fst` would record a reference to the captured capability `ct`. So if this access was put in a closure, the capability would again form part of the outer capture set. E.g. +```scala +() => p.fst : {ct} () -> {ct} Int -> String +``` +In other words, references to capabilities "tunnel through" in generic instantiations from creation to access; they do not affect the capture set of the enclosing generic data constructor applications. +This principle plays an important part in making capture checking concise and practical. + +## Escape Checking + +The universal capability `*` should be conceptually available only as a parameter to the main program. Indeed, if it was available everywhere, capability checking would be undermined since one could mint new capabilities +at will. In line with this reasoning, some capture sets are restricted so that +they are not allowed to contain the universal capability. + +Specifically, if a capturing type is an instance of a type variable, that capturing type +is not allowed to carry the universal capability `{*}`. There's a connection to tunnelling here. +The capture set of a type has to be present in the environment when a type is instantiated from +a type variable. But `*` is not itself available as a global entity in the environment. Hence, +an error should result. + +We can now reconstruct how this principle produced the error in the introductory example, where +`usingLogFile` was declared like this: +```scala +def usingLogFile[T](op: ({*} FileOutputStream) => T): T = ... +``` +The error message was: +``` + | val later = usingLogFile { f => () => f.write(0) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |The expression's type {*} () -> Unit is not allowed to capture the root capability `*`. + |This usually means that a capability persists longer than its allowed lifetime. +``` +This error message was produced by the following logic: + + - The `f` parameter has type `{*} FileOutputStream`, which makes it a capability. + - Therefore, the type of the expression `() => f.write(0)` is `{f} () -> Unit`. + - This makes the type of the whole closure passed to `usingLogFile` the dependent function type + `(f: {*} FileOutputStream) -> {f} () -> Unit`. + - The expected type of the closure is a simple, parametric, impure function type `({*} FileOutputStream) => T`, + for some instantiation of the type variable `T`. + - The smallest supertype of the closure's dependent function type that is a parametric function type is + `({*} FileOutputStream) => {*} () -> Unit` + - Hence, the type variable `T` is instantiated to `* () -> Unit`, which causes the error. + +An analogous restriction applies to the type of a mutable variable. +Another way one could try to undermine capture checking would be to +assign a closure with a local capability to a global variable. Maybe +like this: +```scala +var loophole: {*} () -> Unit = () => () +usingLogFile { f => + loophole = () => f.write(0) +} +loophole() +``` +But this will not compile either, since mutable variables cannot have universal capture sets. + +One also needs to prevent returning or assigning a closure with a local capability in an argument of a parametric type. For instance, here is a +slightly more refined attack: +```scala +class Cell[+A](x: A) +val sneaky = usingLogFile { f => Cell(() => f.write(0)) } +sneaky.x() +``` +At the point where the `Cell` is created, the capture set of the argument is `f`, which +is OK. But at the point of use, it is `*` (because `f` is no longer in scope), which causes again an error: +``` + | sneaky.x() + | ^^^^^^^^ + |The expression's type {*} () -> Unit is not allowed to capture the root capability `*`. + |This usually means that a capability persists longer than its allowed lifetime. +``` + +Looking at object graphs, we observe a monotonicity property: The capture set of an object `x` covers the capture sets of all objects reachable through `x`. This property is reflected in the type system by the following _monotonicity rule_: + + - In a class `C` with a field `f`, the capture set `{this}` covers the capture set `{this.f}` as well as the capture set of any application of `this.f` to pure arguments. + +## Checked Exceptions + +Scala enables checked exceptions through a language import. Here is an example, +taken from the [safer exceptions page](./canthrow.md), and also described in a +[paper](https://infoscience.epfl.ch/record/290885) presented at the + 2021 Scala Symposium. +```scala +import language.experimental.saferExceptions + +class LimitExceeded extends Exception + +val limit = 10e+10 +def f(x: Double): Double throws LimitExceeded = + if x < limit then x * x else throw LimitExceeded() +``` +The new `throws` clause expands into an implicit parameter that provides +a `CanThrow` capability. Hence, function `f` could equivalently be written +like this: +```scala +def f(x: Double)(using CanThrow[LimitExceeded]): Double = ... +``` +If the implicit parameter is missing, an error is reported. For instance, the function definition +```scala +def g(x: Double): Double = + if x < limit then x * x else throw LimitExceeded() +``` +is rejected with this error message: +``` + | if x < limit then x * x else throw LimitExceeded() + | ^^^^^^^^^^^^^^^^^^^^^ + |The capability to throw exception LimitExceeded is missing. + |The capability can be provided by one of the following: + | - Adding a using clause `(using CanThrow[LimitExceeded])` to the definition of the enclosing method + | - Adding `throws LimitExceeded` clause after the result type of the enclosing method + | - Wrapping this piece of code with a `try` block that catches LimitExceeded +``` +`CanThrow` capabilities are required by `throw` expressions and are created +by `try` expressions. For instance, the expression +```scala +try xs.map(f).sum +catch case ex: LimitExceeded => -1 +``` +would be expanded by the compiler to something like the following: +```scala +try + erased given ctl: CanThrow[LimitExceeded] = compiletime.erasedValue + xs.map(f).sum +catch case ex: LimitExceeded => -1 +``` +(The `ctl` capability is only used for type checking but need not show up in the generated code, so it can be declared as +erased.) + +As with other capability based schemes, one needs to guard against capabilities +that are captured in results. For instance, here is a problematic use case: +```scala +def escaped(xs: Double*): (() => Double) throws LimitExceeded = + try () => xs.map(f).sum + catch case ex: LimitExceeded => () => -1 +val crasher = escaped(1, 2, 10e+11) +crasher() +``` +This code needs to be rejected since otherwise the call to `crasher()` would cause +an unhandled `LimitExceeded` exception to be thrown. + +Under `-Ycc`, the code is indeed rejected +``` +14 | try () => xs.map(f).sum + | ^ + |The expression's type {*} () -> Double is not allowed to capture the root capability `*`. + |This usually means that a capability persists longer than its allowed lifetime. +15 | catch case ex: LimitExceeded => () => -1 +``` +To integrate exception and capture checking, only two changes are needed: + + - `CanThrow` is declared as a `@capability` class, so all references to `CanThrow` instances are tracked. + - Escape checking is extended to `try` expressions. The result type of a `try` is not allowed to + capture the universal capability. + +## A Larger Example + +As a larger example, we present an implementation of lazy lists and some use cases. For simplicity, +our lists are lazy only in their tail part. This corresponds to what the Scala-2 type `Stream` did, whereas Scala 3's `LazyList` type computes strictly less since it is also lazy in the first argument. + +Here is the base trait `LzyList` for our version of lazy lists: +```scala +trait LzyList[+A]: + def isEmpty: Boolean + def head: A + def tail: {this} LzyList[A] +``` +Note that `tail` carries a capture annotation. It says that the tail of a lazy list can +potentially capture the same references as the lazy list as a whole. + +The empty case of a `LzyList` is written as usual: +```scala +object LzyNil extends LzyList[Nothing]: + def isEmpty = true + def head = ??? + def tail = ??? +``` +Here is a formulation of the class for lazy cons nodes: +```scala +import scala.compiletime.uninitialized + +final class LzyCons[+A](hd: A, tl: () => {*} LzyList[A]) extends LzyList[A]: + private var forced = false + private var cache: {this} LzyList[A] = uninitialized + private def force = + if !forced then { cache = tl(); forced = true } + cache + + def isEmpty = false + def head = hd + def tail: {this} LzyList[A] = force +end LzyCons +``` +The `LzyCons` class takes two parameters: A head `hd` and a tail `tl`, which is a function +returning a `LzyList`. Both the function and its result can capture arbitrary capabilities. +The result of applying the function is memoized after the first dereference of `tail` in +the private mutable field `cache`. Note that the typing of the assignment `cache = tl()` relies on the monotonicity rule for `{this}` capture sets. + +Here is an extension method to define an infix cons operator `#:` for lazy lists. It is analogous +to `::` but instead of a strict list it produces a lazy list without evaluating its right operand. +```scala +extension [A](x: A) + def #:(xs1: => {*} LzyList[A]): {xs1} LzyList[A] = + LzyCons(x, () => xs1) +``` +Note that `#:` takes an impure call-by-name parameter `xs1` as its right argument. The result +of `#:` is a lazy list that captures that argument. + +As an example usage of `#:`, here is a method `tabulate` that creates a lazy list +of given length with a generator function `gen`. The generator function is allowed +to have side effects. +```scala +def tabulate[A](n: Int)(gen: Int => A) = + def recur(i: Int): {gen} LzyList[A] = + if i == n then LzyNil + else gen(i) #: recur(i + 1) + recur(0) +``` +Here is a use of `tabulate`: +```scala +class LimitExceeded extends Exception +def squares(n: Int)(using ct: CanThrow[LimitExceeded]) = + tabulate(10) { i => + if i > 9 then throw LimitExceeded() + i * i + } +``` +The inferred result type of `squares` is `{ct} LzyList[Int]`, i.e it is a lazy list of +`Int`s that can throw the `LimitExceeded` exception when it is elaborated by calling `tail` +one or more times. + +Here are some further extension methods for mapping, filtering, and concatenating lazy lists: +```scala +extension [A](xs: {*} LzyList[A]) + def map[B](f: A => B): {xs, f} LzyList[B] = + if xs.isEmpty then LzyNil + else f(xs.head) #: xs.tail.map(f) + + def filter(p: A => Boolean): {xs, p} LzyList[A] = + if xs.isEmpty then LzyNil + else if p(xs.head) then xs.head #: xs.tail.filter(p) + else xs.tail.filter(p) + + def concat(ys: {*} LzyList[A]): {xs, ys} LzyList[A] = + if xs.isEmpty then ys + else xs.head #: xs.tail.concat(ys) + + def drop(n: Int): {xs} LzyList[A] = + if n == 0 then xs else xs.tail.drop(n - 1) +``` +Their capture annotations are all as one would expect: + + - Mapping a lazy list produces a lazy list that captures the original list as well + as the (possibly impure) mapping function. + - Filtering a lazy list produces a lazy list that captures the original list as well + as the (possibly impure) filtering predicate. + - Concatenating two lazy lists produces a lazy list that captures both arguments. + - Dropping elements from a lazy list gives a safe approximation where the original list is captured in the result. In fact, it's only some suffix of the list that is retained at run time, but our modelling identifies lazy lists and their suffixes, so this additional knowledge would not be useful. + +Of course the function passed to `map` or `filter` could also be pure. After all, `A -> B` is a subtype of `{*} A -> B` which is the same as `A => B`. In that case, the pure function +argument will _not_ show up in the result type of `map` or `filter`. For instance: +```scala +val xs = squares(10) +val ys: {xs} LzyList[Int] = xs.map(_ + 1) +``` +The type of the mapped list `ys` has only `xs` in its capture set. The actual function +argument does not show up since it is pure. Likewise, if the lazy list +`xs` was pure, it would not show up in any of the method results. +This demonstrates that capability-based +effect systems with capture checking are naturally _effect polymorphic_. + +This concludes our example. It's worth mentioning that an equivalent program defining and using standard, strict lists would require no capture annotations whatsoever. It would compile exactly as written now in standard Scala 3, yet one gets the capture checking for free. Essentially, `=>` already means "can capture anything" and since in a strict list side effecting operations are not retained in the result, there are no additional captures to record. A strict list could of course capture side-effecting closures in its elements but then tunnelling applies, since +these elements are represented by a type variable. This means we don't need to annotate anything there either. + +Another possibility would be a variant of lazy lists that requires all functions passed to `map`, `filter` and other operations like it to be pure. E.g. `map` on such a list would be defined like this: +```scala +extension [A](xs: LzyList[A]) + def map[B](f: A -> B): LzyList[B] = ... +``` +That variant would not require any capture annotations either. + +To summarize, there are two "sweet spots" of data structure design: strict lists in +side-effecting or resource-aware code and lazy lists in purely functional code. +Both are already correctly capture-typed without requiring any explicit annotations. Capture annotations only come into play where the semantics gets more complicated because we deal with delayed effects such as in impure lazy lists or side-effecting iterators over strict lists. This property is probably one of the greatest plus points of our approach to capture checking compared to previous techniques which tend to be more noisy. + +## Function Type Shorthands + +TBD + +## Compilation Options + +The following options are relevant for capture checking. + + - **-Ycc** Enables capture checking. + - **-Xprint:cc** Prints the program with capturing types as inferred by capture checking. + - **-Ycc-debug** Gives more detailed, implementation-oriented information about capture checking, as described in the next section. + + The implementation supporting capture checking with these options is currently in branch `cc-experiment` on dotty.epfl.ch. + +## Capture Checking Internals + +The capture checker is architected as a propagation constraint solver, which runs as a separate phase after type-checking and some initial transformations. + +Constraint variables stand for unknown capture sets. A constraint variable is introduced + + - for every part of a previously inferred type, + - for the accessed references of every method, class, anonymous function, or by-name argument, + - for the parameters passed in a class constructor call. + +Capture sets in explicitly written types are treated as constants (before capture checking, such sets are simply ignored). + +The capture checker essentially rechecks the program with the usual typing rules. Every time a subtype requirement between capturing types is checked, this translates to a subcapturing test on capture sets. If the two sets are constant, this is simply a yes/no question, where a no will produce an error message. + +If the lower set `C₁` of a comparison `C₁ <: C₂` is a variable, the set `C₂` is recorded +as a _superset_ of `C₁`. If the upper set `C₂` is a variable, the elements of `C₁` are _propagated_ to `C₂`. Propagation of an element `x` to a set `C` means that `x` is included as an element in `C`, and it is also propagated +to all known supersets of `C`. If such a superset is a constant, it is checked that `x` is included in it. If that's not the case, the original comparison `C₁ <: C₂` has no solution and an error is reported. + +The type checker also performs various maps on types, for instance when substituting actual argument types for formal parameter types in dependent functions, or mapping +member types with "as-seen-from" in a selection. Maps keep track of the variance +of positions in a type. The variance is initially covariant, it flips to +contravariant in function parameter positions, and can be either covariant, +contravariant, or nonvariant in type arguments, depending on the variance of +the type parameter. + +When capture checking, the same maps are also performed on capture sets. If a capture set is a constant, its elements (which are capabilities) are mapped as regular types. If the result of such a map is not a capability, the result is approximated according to the variance of the type. A covariant approximation replaces a type by its capture set. +A contravariant approximation replaces it with the empty capture set. A nonvariant +approximation replaces the enclosing capturing type with a range of possible types +that gets propagated and resolved further out. + +When a mapping `m` is performed on a capture set variable `C`, a new variable `Cm` is created that contains the mapped elements and that is linked with `C`. If `C` subsequently acquires further elements through propagation, these are also propagated to `Cm` after being transformed by the `m` mapping. `Cm` also gets the same supersets as `C`, mapped again using `m`. + +One interesting aspect of the capture checker concerns the implementation of capture tunnelling. The [foundational theory](https://infoscience.epfl.ch/record/290885) on which capture checking is based makes tunnelling explicit through so-called _box_ and +_unbox_ operations. Boxing hides a capture set and unboxing recovers it. The capture checker inserts virtual box and unbox operations based on actual and expected types similar to the way the type checker inserts implicit conversions. When capture set variables are first introduced, any capture set in a capturing type that is an instance of a type parameter instance is marked as "boxed". A boxing operation is +inserted if the expected type of an expression is a capturing type with +a boxed capture set variable. The effect of the insertion is that any references +to capabilities in the boxed expression are forgotten, which means that capture +propagation is stopped. Dually, if the actual type of an expression has +a boxed variable as capture set, an unbox operation is inserted, which adds all +elements of the capture set to the environment. + +Boxing and unboxing has no runtime effect, so the insertion of these operations is only simulated; the only visible effect is the retraction and insertion +of variables in the capture sets representing the environment of the currently checked expression. + +The `-Ycc-debug` option provides some insight into the workings of the capture checker. +When it is turned on, boxed sets are marked explicitly and capture set variables are printed with an ID and some information about their provenance. For instance, the string `{f, xs}33M5V` indicates a capture set +variable that is known to hold elements `f` and `xs`. The variable's ID is `33`. The `M` +indicates that the variable was created through a mapping from a variable with ID `5`. The latter is a regular variable, as indicated + by `V`. + +Generally, the string following the capture set consists of alternating numbers and letters where each number gives a variable ID and each letter gives the provenance of the variable. Possible letters are + + - `V` : a regular variable, + - `M` : a variable resulting from a _mapping_ of the variable indicated by the string to the right, + - `B` : similar to `M` but where the mapping is a _bijection_, + - `F` : a variable resulting from _filtering_ the elements of the variable indicated by the string to the right, + - `I` : a variable resulting from an _intersection_ of two capture sets, + - `D` : a variable resulting from the set _difference_ of two capture sets. + +At the end of a compilation run, `-Ycc-debug` will print all variable dependencies of variables referred to in previous output. Here is an example: +``` +Capture set dependencies: + {}2V :: + {}3V :: + {}4V :: + {f, xs}5V :: {f, xs}31M5V, {f, xs}32M5V + {f, xs}31M5V :: {xs, f} + {f, xs}32M5V :: +``` +This section lists all variables that appeared in previous diagnostics and their dependencies, recursively. For instance, we learn that + + - variables 2, 3, 4 are empty and have no dependencies, + - variable `5` has two dependencies: variables `31` and `32` which both result from mapping variable `5`, + - variable `31` has a constant fixed superset `{xs, f}` + - variable `32` has no dependencies. + diff --git a/docs/_spec/TODOreference/experimental/erased-defs-spec.md b/docs/_spec/TODOreference/experimental/erased-defs-spec.md new file mode 100644 index 000000000000..5395a8468399 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/erased-defs-spec.md @@ -0,0 +1,64 @@ +--- +layout: doc-page +title: "Erased Definitions - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/erased-defs-spec.html +--- + +TODO: complete +## Rules + +1. `erased` is a soft modifier. It can appear: + * At the start of a parameter block of a method, function or class + * In a method definition + * In a `val` definition (but not `lazy val` or `var`) + * In a `class` or `trait` definition + + ```scala + erased val x = ... + erased def f = ... + + def g(erased x: Int) = ... + + (erased x: Int) => ... + def h(x: (erased Int) => Int) = ... + + class K(erased x: Int) { ... } + erased class E {} + ``` + + +2. A reference to an `erased` val or def can only be used + * Inside the expression of argument to an `erased` parameter + * Inside the body of an `erased` `val` or `def` + + +3. Functions + * `(erased x1: T1, x2: T2, ..., xN: TN) => y : (erased T1, T2, ..., TN) => R` + * `(given erased x1: T1, x2: T2, ..., xN: TN) => y: (given erased T1, T2, ..., TN) => R` + * `(given erased T1) => R <:< erased T1 => R` + * `(given erased T1, T2) => R <:< (erased T1, T2) => R` + * ... + + Note that there is no subtype relation between `(erased T) => R` and `T => R` (or `(given erased T) => R` and `(given T) => R`) + + +4. Eta expansion + + if `def f(erased x: T): U` then `f: (erased T) => U`. + + +5. Erasure semantics + * All `erased` parameters are removed from the function + * All argument to `erased` parameters are not passed to the function + * All `erased` definitions are removed + * All `(erased T1, T2, ..., TN) => R` and `(given erased T1, T2, ..., TN) => R` become `() => R` + + +6. Overloading + + Method with `erased` parameters will follow the normal overloading constraints after erasure. + + +7. Overriding + * Member definitions overriding each other must both be `erased` or not be `erased` + * `def foo(x: T): U` cannot be overridden by `def foo(erased x: T): U` and vice-versa diff --git a/docs/_spec/TODOreference/experimental/erased-defs.md b/docs/_spec/TODOreference/experimental/erased-defs.md new file mode 100644 index 000000000000..28455f26cdc0 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/erased-defs.md @@ -0,0 +1,231 @@ +--- +layout: doc-page +title: "Erased Definitions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/erased-defs.html +--- + +`erased` is a modifier that expresses that some definition or expression is erased by the compiler instead of being represented in the compiled output. It is not yet part of the Scala language standard. To enable `erased`, turn on the language feature +[`experimental.erasedDefinitions`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$experimental$$erasedDefinitions$.html). This can be done with a language import +```scala +import scala.language.experimental.erasedDefinitions +``` +or by setting the command line option `-language:experimental.erasedDefinitions`. +Erased definitions must be in an experimental scope (see [Experimental definitions](../other-new-features/experimental-defs.md)). + +## Why erased terms? + +Let's describe the motivation behind erased terms with an example. In the +following we show a simple state machine which can be in a state `On` or `Off`. +The machine can change state from `Off` to `On` with `turnedOn` only if it is +currently `Off`. This last constraint is captured with the `IsOff[S]` contextual +evidence which only exists for `IsOff[Off]`. For example, not allowing calling +`turnedOn` on in an `On` state as we would require an evidence of type +`IsOff[On]` that will not be found. + +```scala +sealed trait State +final class On extends State +final class Off extends State + +@implicitNotFound("State must be Off") +class IsOff[S <: State] +object IsOff: + given isOff: IsOff[Off] = new IsOff[Off] + +class Machine[S <: State]: + def turnedOn(using IsOff[S]): Machine[On] = new Machine[On] + +val m = new Machine[Off] +m.turnedOn +m.turnedOn.turnedOn // ERROR +// ^ +// State must be Off +``` + +Note that in the code above the actual context arguments for `IsOff` are never +used at runtime; they serve only to establish the right constraints at compile +time. As these terms are never used at runtime there is not real need to have +them around, but they still need to be present in some form in the generated +code to be able to do separate compilation and retain binary compatibility. We +introduce _erased terms_ to overcome this limitation: we are able to enforce the +right constrains on terms at compile time. These terms have no run time +semantics and they are completely erased. + +## How to define erased terms? + +Parameters of methods and functions can be declared as erased, placing `erased` +in front of a parameter list (like `given`). + +```scala +def methodWithErasedEv(erased ev: Ev): Int = 42 + +val lambdaWithErasedEv: erased Ev => Int = + (erased ev: Ev) => 42 +``` + +`erased` parameters will not be usable for computations, though they can be used +as arguments to other `erased` parameters. + +```scala +def methodWithErasedInt1(erased i: Int): Int = + i + 42 // ERROR: can not use i + +def methodWithErasedInt2(erased i: Int): Int = + methodWithErasedInt1(i) // OK +``` + +Not only parameters can be marked as erased, `val` and `def` can also be marked +with `erased`. These will also only be usable as arguments to `erased` +parameters. + +```scala +erased val erasedEvidence: Ev = ... +methodWithErasedEv(erasedEvidence) +``` + +## What happens with erased values at runtime? + +As `erased` are guaranteed not to be used in computations, they can and will be +erased. + +```scala +// becomes def methodWithErasedEv(): Int at runtime +def methodWithErasedEv(erased ev: Ev): Int = ... + +def evidence1: Ev = ... +erased def erasedEvidence2: Ev = ... // does not exist at runtime +erased val erasedEvidence3: Ev = ... // does not exist at runtime + +// evidence1 is not evaluated and no value is passed to methodWithErasedEv +methodWithErasedEv(evidence1) +``` + +## State machine with erased evidence example + +The following example is an extended implementation of a simple state machine +which can be in a state `On` or `Off`. The machine can change state from `Off` +to `On` with `turnedOn` only if it is currently `Off`, conversely from `On` to +`Off` with `turnedOff` only if it is currently `On`. These last constraint are +captured with the `IsOff[S]` and `IsOn[S]` given evidence only exist for +`IsOff[Off]` and `IsOn[On]`. For example, not allowing calling `turnedOff` on in +an `Off` state as we would require an evidence `IsOn[Off]` that will not be +found. + +As the given evidences of `turnedOn` and `turnedOff` are not used in the +bodies of those functions we can mark them as `erased`. This will remove the +evidence parameters at runtime, but we would still evaluate the `isOn` and +`isOff` givens that were found as arguments. As `isOn` and `isOff` are not +used except as `erased` arguments, we can mark them as `erased`, hence removing +the evaluation of the `isOn` and `isOff` evidences. + +```scala +import scala.annotation.implicitNotFound + +sealed trait State +final class On extends State +final class Off extends State + +@implicitNotFound("State must be Off") +class IsOff[S <: State] +object IsOff: + // will not be called at runtime for turnedOn, the + // compiler will only require that this evidence exists + given IsOff[Off] = new IsOff[Off] + +@implicitNotFound("State must be On") +class IsOn[S <: State] +object IsOn: + // will not exist at runtime, the compiler will only + // require that this evidence exists at compile time + erased given IsOn[On] = new IsOn[On] + +class Machine[S <: State] private (): + // ev will disappear from both functions + def turnedOn(using erased ev: IsOff[S]): Machine[On] = new Machine[On] + def turnedOff(using erased ev: IsOn[S]): Machine[Off] = new Machine[Off] + +object Machine: + def newMachine(): Machine[Off] = new Machine[Off] + +@main def test = + val m = Machine.newMachine() + m.turnedOn + m.turnedOn.turnedOff + + // m.turnedOff + // ^ + // State must be On + + // m.turnedOn.turnedOn + // ^ + // State must be Off +``` + +Note that in [Inline](../metaprogramming/inline.md) we discussed `erasedValue` and inline +matches. `erasedValue` is implemented with `erased`, so the state machine above +can be encoded as follows: + +```scala +import scala.compiletime.* + +sealed trait State +final class On extends State +final class Off extends State + +class Machine[S <: State]: + transparent inline def turnOn(): Machine[On] = + inline erasedValue[S] match + case _: Off => new Machine[On] + case _: On => error("Turning on an already turned on machine") + + transparent inline def turnOff(): Machine[Off] = + inline erasedValue[S] match + case _: On => new Machine[Off] + case _: Off => error("Turning off an already turned off machine") + +object Machine: + def newMachine(): Machine[Off] = + println("newMachine") + new Machine[Off] +end Machine + +@main def test = + val m = Machine.newMachine() + m.turnOn() + m.turnOn().turnOff() + m.turnOn().turnOn() // error: Turning on an already turned on machine +``` + +## Erased Classes + +`erased` can also be used as a modifier for a class. An erased class is intended to be used only in erased definitions. If the type of a val definition or parameter is +a (possibly aliased, refined, or instantiated) erased class, the definition is assumed to be `erased` itself. Likewise, a method with an erased class return type is assumed to be `erased` itself. Since given instances expand to vals and defs, they are also assumed to be erased if the type they produce is an erased class. Finally +function types with erased classes as arguments turn into erased function types. + +Example: +```scala +erased class CanRead + +val x: CanRead = ... // `x` is turned into an erased val +val y: CanRead => Int = ... // the function is turned into an erased function +def f(x: CanRead) = ... // `f` takes an erased parameter +def g(): CanRead = ... // `g` is turned into an erased def +given CanRead = ... // the anonymous given is assumed to be erased +``` +The code above expands to +```scala +erased class CanRead + +erased val x: CanRead = ... +val y: (erased CanRead) => Int = ... +def f(erased x: CanRead) = ... +erased def g(): CanRead = ... +erased given CanRead = ... +``` +After erasure, it is checked that no references to values of erased classes remain and that no instances of erased classes are created. So the following would be an error: +```scala +val err: Any = CanRead() // error: illegal reference to erased class CanRead +``` +Here, the type of `err` is `Any`, so `err` is not considered erased. Yet its initializing value is a reference to the erased class `CanRead`. + +[More Details](./erased-defs-spec.md) diff --git a/docs/_spec/TODOreference/experimental/explicit-nulls.md b/docs/_spec/TODOreference/experimental/explicit-nulls.md new file mode 100644 index 000000000000..b3fa53429cfe --- /dev/null +++ b/docs/_spec/TODOreference/experimental/explicit-nulls.md @@ -0,0 +1,543 @@ +--- +layout: doc-page +title: "Explicit Nulls" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/explicit-nulls.html +--- + +Explicit nulls is an opt-in feature that modifies the Scala type system, which makes reference types +(anything that extends [`AnyRef`](https://scala-lang.org/api/3.x/scala/AnyRef.html)) _non-nullable_. + +This means the following code will no longer typecheck: + +```scala +val x: String = null // error: found `Null`, but required `String` +``` + +Instead, to mark a type as nullable we use a [union type](../new-types/union-types.md) + +```scala +val x: String | Null = null // ok +``` + +A nullable type could have null value during runtime; hence, it is not safe to select a member without checking its nullity. + +```scala +x.trim // error: trim is not member of String | Null +``` + +Explicit nulls are enabled via a `-Yexplicit-nulls` flag. + +Read on for details. + +## New Type Hierarchy + +Originally, `Null` is a subtype of all reference types. + +!["Original Type Hierarchy"](images/explicit-nulls/scalaHierarchyWithMatchable.png) + +When explicit nulls is enabled, the type hierarchy changes so that `Null` is only +a subtype of `Any` and `Matchable`, as opposed to every reference type, +which means `null` is no longer a value of `AnyRef` and its subtypes. + +This is the new type hierarchy: + +!["Type Hierarchy for Explicit Nulls"](images/explicit-nulls/scalaHierarchyWithMatchableAndSafeNull.png) + +After erasure, `Null` remains a subtype of all reference types (as forced by the JVM). + +## Working with `Null` + +To make working with nullable values easier, we propose adding a few utilities to the standard library. +So far, we have found the following useful: + +- An extension method `.nn` to "cast away" nullability + + ```scala + extension [T](x: T | Null) + inline def nn: T = + assert(x != null) + x.asInstanceOf[T] + ``` + + This means that given `x: String | Null`, `x.nn` has type `String`, so we can call all the + usual methods on it. Of course, `x.nn` will throw a NPE if `x` is `null`. + + Don't use `.nn` on mutable variables directly, because it may introduce an unknown type into the type of the variable. + +- An [`unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$unsafeNulls$.html) language feature. + + When imported, `T | Null` can be used as `T`, similar to regular Scala (without explicit nulls). + + See [UnsafeNulls](#unsafenulls) section for more details. + +## Unsoundness + +The new type system is unsound with respect to `null`. This means there are still instances where an expression has a non-nullable type like `String`, but its value is actually `null`. + +The unsoundness happens because uninitialized fields in a class start out as `null`: + +```scala +class C: + val f: String = foo(f) + def foo(f2: String): String = f2 + +val c = new C() +// c.f == "field is null" +``` + +The unsoundness above can be caught by the compiler with the option `-Ysafe-init`. +More details can be found in [safe initialization](../other-new-features/safe-initialization.md). + +## Equality + +We don't allow the double-equal (`==` and `!=`) and reference (`eq` and `ne`) comparison between +`AnyRef` and `Null` anymore, since a variable with a non-nullable type cannot have `null` as value. +`null` can only be compared with `Null`, nullable union (`T | Null`), or `Any` type. + +For some reason, if we really want to compare `null` with non-null values, we have to provide a type hint (e.g. `: Any`). + +```scala +val x: String = ??? +val y: String | Null = ??? + +x == null // error: Values of types String and Null cannot be compared with == or != +x eq null // error +"hello" == null // error + +y == null // ok +y == x // ok + +(x: String | Null) == null // ok +(x: Any) == null // ok +``` + +## Java Interoperability + +The Scala compiler can load Java classes in two ways: from source or from bytecode. In either case, +when a Java class is loaded, we "patch" the type of its members to reflect that Java types +remain implicitly nullable. + +Specifically, we patch + +- the type of fields + +- the argument type and return type of methods + +We illustrate the rules with following examples: + +- The first two rules are easy: we nullify reference types but not value types. + + ```java + class C { + String s; + int x; + } + ``` + + ==> + + ```scala + class C: + val s: String | Null + val x: Int + ``` + +- We nullify type parameters because in Java a type parameter is always nullable, so the following code compiles. + + ```java + class C { T foo() { return null; } } + ``` + + ==> + + ```scala + class C[T] { def foo(): T | Null } + ``` + + Notice this is rule is sometimes too conservative, as witnessed by + + ```scala + class InScala: + val c: C[Bool] = ??? // C as above + val b: Bool = c.foo() // no longer typechecks, since foo now returns Bool | Null + ``` + +- We can reduce the number of redundant nullable types we need to add. Consider + + ```java + class Box { T get(); } + class BoxFactory { Box makeBox(); } + ``` + + ==> + + ```scala + class Box[T] { def get(): T | Null } + class BoxFactory[T] { def makeBox(): Box[T] | Null } + ``` + + Suppose we have a `BoxFactory[String]`. Notice that calling `makeBox()` on it returns a + `Box[String] | Null`, not a `Box[String | Null] | Null`. This seems at first + glance unsound ("What if the box itself has `null` inside?"), but is sound because calling + `get()` on a `Box[String]` returns a `String | Null`. + + Notice that we need to patch _all_ Java-defined classes that transitively appear in the + argument or return type of a field or method accessible from the Scala code being compiled. + Absent crazy reflection magic, we think that all such Java classes _must_ be visible to + the Typer in the first place, so they will be patched. + +- We will append `Null` to the type arguments if the generic class is defined in Scala. + + ```java + class BoxFactory { + Box makeBox(); // Box is Scala-defined + List>> makeCrazyBoxes(); // List is Java-defined + } + ``` + + ==> + + ```scala + class BoxFactory[T]: + def makeBox(): Box[T | Null] | Null + def makeCrazyBoxes(): java.util.List[Box[java.util.List[T] | Null]] | Null + ``` + + In this case, since `Box` is Scala-defined, we will get `Box[T | Null] | Null`. + This is needed because our nullability function is only applied (modularly) to the Java + classes, but not to the Scala ones, so we need a way to tell `Box` that it contains a + nullable value. + + The `List` is Java-defined, so we don't append `Null` to its type argument. But we + still need to nullify its inside. + +- We don't nullify _simple_ literal constant (`final`) fields, since they are known to be non-null + + ```java + class Constants { + final String NAME = "name"; + final int AGE = 0; + final char CHAR = 'a'; + + final String NAME_GENERATED = getNewName(); + } + ``` + + ==> + + ```scala + class Constants: + val NAME: String("name") = "name" + val AGE: Int(0) = 0 + val CHAR: Char('a') = 'a' + + val NAME_GENERATED: String | Null = getNewName() + ``` + +- We don't append `Null` to a field nor to a return type of a method which is annotated with a + `NotNull` annotation. + + ```java + class C { + @NotNull String name; + @NotNull List getNames(String prefix); // List is Java-defined + @NotNull Box getBoxedName(); // Box is Scala-defined + } + ``` + + ==> + + ```scala + class C: + val name: String + def getNames(prefix: String | Null): java.util.List[String] // we still need to nullify the paramter types + def getBoxedName(): Box[String | Null] // we don't append `Null` to the outmost level, but we still need to nullify inside + ``` + + The annotation must be from the list below to be recognized as `NotNull` by the compiler. + Check `Definitions.scala` for an updated list. + + ```scala + // A list of annotations that are commonly used to indicate + // that a field/method argument or return type is not null. + // These annotations are used by the nullification logic in + // JavaNullInterop to improve the precision of type nullification. + // We don't require that any of these annotations be present + // in the class path, but we want to create Symbols for the + // ones that are present, so they can be checked during nullification. + @tu lazy val NotNullAnnots: List[ClassSymbol] = ctx.getClassesIfDefined( + "javax.annotation.Nonnull" :: + "edu.umd.cs.findbugs.annotations.NonNull" :: + "androidx.annotation.NonNull" :: + "android.support.annotation.NonNull" :: + "android.annotation.NonNull" :: + "com.android.annotations.NonNull" :: + "org.eclipse.jdt.annotation.NonNull" :: + "org.checkerframework.checker.nullness.qual.NonNull" :: + "org.checkerframework.checker.nullness.compatqual.NonNullDecl" :: + "org.jetbrains.annotations.NotNull" :: + "lombok.NonNull" :: + "io.reactivex.annotations.NonNull" :: Nil map PreNamedString) + ``` + +### Override check + +When we check overriding between Scala classes and Java classes, the rules are relaxed for [`Null`](https://scala-lang.org/api/3.x/scala/Null.html) type with this feature, in order to help users to working with Java libraries. + +Suppose we have Java method `String f(String x)`, we can override this method in Scala in any of the following forms: + +```scala +def f(x: String | Null): String | Null + +def f(x: String): String | Null + +def f(x: String | Null): String + +def f(x: String): String +``` + +Note that some of the definitions could cause unsoundness. For example, the return type is not nullable, but a `null` value is actually returned. + +## Flow Typing + +We added a simple form of flow-sensitive type inference. The idea is that if `p` is a +stable path or a trackable variable, then we can know that `p` is non-null if it's compared +with `null`. This information can then be propagated to the `then` and `else` branches +of an if-statement (among other places). + +Example: + +```scala +val s: String | Null = ??? +if s != null then + // s: String + +// s: String | Null + +assert(s != null) +// s: String +``` + +A similar inference can be made for the `else` case if the test is `p == null` + +```scala +if s == null then + // s: String | Null +else + // s: String +``` + +`==` and `!=` is considered a comparison for the purposes of the flow inference. + +### Logical Operators + +We also support logical operators (`&&`, `||`, and `!`): + +```scala +val s: String | Null = ??? +val s2: String | Null = ??? +if s != null && s2 != null then + // s: String + // s2: String + +if s == null || s2 == null then + // s: String | Null + // s2: String | Null +else + // s: String + // s2: String +``` + +### Inside Conditions + +We also support type specialization _within_ the condition, taking into account that `&&` and `||` are short-circuiting: + +```scala +val s: String | Null = ??? + +if s != null && s.length > 0 then // s: String in `s.length > 0` + // s: String + +if s == null || s.length > 0 then // s: String in `s.length > 0` + // s: String | Null +else + // s: String +``` + +### Match Case + +The non-null cases can be detected in match statements. + +```scala +val s: String | Null = ??? + +s match + case _: String => // s: String + case _ => +``` + +### Mutable Variable + +We are able to detect the nullability of some local mutable variables. A simple example is: + +```scala +class C(val x: Int, val next: C | Null) + +var xs: C | Null = C(1, C(2, null)) +// xs is trackable, since all assignments are in the same method +while xs != null do + // xs: C + val xsx: Int = xs.x + val xscpy: C = xs + xs = xscpy // since xscpy is non-null, xs still has type C after this line + // xs: C + xs = xs.next // after this assignment, xs can be null again + // xs: C | Null +``` + +When dealing with local mutable variables, there are two questions: + +1. Whether to track a local mutable variable during flow typing. + We track a local mutable variable if the variable is not assigned in a closure. + For example, in the following code `x` is assigned to by the closure `y`, so we do not + do flow typing on `x`. + + ```scala + var x: String | Null = ??? + def y = + x = null + + if x != null then + // y can be called here, which would break the fact + val a: String = x // error: x is captured and mutated by the closure, not trackable + ``` + +2. Whether to generate and use flow typing on a specific _use_ of a local mutable variable. + We only want to do flow typing on a use that belongs to the same method as the definition + of the local variable. + For example, in the following code, even `x` is not assigned to by a closure, we can only + use flow typing in one of the occurrences (because the other occurrence happens within a + nested closure). + + ```scala + var x: String | Null = ??? + def y = + if x != null then + // not safe to use the fact (x != null) here + // since y can be executed at the same time as the outer block + val _: String = x + if x != null then + val a: String = x // ok to use the fact here + x = null + ``` + +See [more examples](https://github.com/lampepfl/dotty/blob/main/tests/explicit-nulls/neg/flow-varref-in-closure.scala). + +Currently, we are unable to track paths with a mutable variable prefix. +For example, `x.a` if `x` is mutable. + +### Unsupported Idioms + +We don't support: + +- flow facts not related to nullability (`if x == 0 then { // x: 0.type not inferred }`) +- tracking aliasing between non-nullable paths + + ```scala + val s: String | Null = ??? + val s2: String | Null = ??? + if s != null && s == s2 then + // s: String inferred + // s2: String not inferred + ``` + +### UnsafeNulls + +It is difficult to work with many nullable values, we introduce a language feature [`unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$unsafeNulls$.html). +Inside this "unsafe" scope, all `T | Null` values can be used as `T`. + +Users can import [`scala.language.unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$unsafeNulls$.html) to create such scopes, or use `-language:unsafeNulls` to enable this feature globally (for migration purpose only). + +Assume `T` is a reference type (a subtype of `AnyRef`), the following unsafe operation rules are +applied in this unsafe-nulls scope: + +1. the members of `T` can be found on `T | Null` + +2. a value with type `T` can be compared with `T | Null` and `Null` + +3. suppose `T1` is not a subtype of `T2` using explicit-nulls subtyping (where `Null` is a direct +subtype of Any), extension methods and implicit conversions designed for `T2` can be used for +`T1` if `T1` is a subtype of `T2` using regular subtyping rules (where `Null` is a subtype of every +reference type) + +4. suppose `T1` is not a subtype of `T2` using explicit-nulls subtyping, a value with type `T1` +can be used as `T2` if `T1` is a subtype of `T2` using regular subtyping rules + +Addtionally, `null` can be used as `AnyRef` (`Object`), which means you can select `.eq` or `.toString` on it. + +The program in [`unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$unsafeNulls$.html) will have a **similar** semantic as regular Scala, but not **equivalent**. + +For example, the following code cannot be compiled even using unsafe nulls. Because of the +Java interoperation, the type of the get method becomes `T | Null`. + +```scala +def head[T](xs: java.util.List[T]): T = xs.get(0) // error +``` + +Since the compiler doesn’t know whether `T` is a reference type, it is unable to cast `T | Null` +to `T`. A `.nn` need to be inserted after `xs.get(0)` by user manually to fix the error, which +strips the `Null` from its type. + +The intention of this [`unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$unsafeNulls$.html) is to give users a better migration path for explicit nulls. +Projects for Scala 2 or regular Scala 3 can try this by adding `-Yexplicit-nulls -language:unsafeNulls` +to the compile options. A small number of manual modifications are expected. To migrate to the full +explicit nulls feature in the future, `-language:unsafeNulls` can be dropped and add +`import scala.language.unsafeNulls` only when needed. + +```scala +def f(x: String): String = ??? +def nullOf[T >: Null]: T = null + +import scala.language.unsafeNulls + +val s: String | Null = ??? +val a: String = s // unsafely convert String | Null to String + +val b1 = s.trim // call .trim on String | Null unsafely +val b2 = b1.length + +f(s).trim // pass String | Null as an argument of type String unsafely + +val c: String = null // Null to String + +val d1: Array[String] = ??? +val d2: Array[String | Null] = d1 // unsafely convert Array[String] to Array[String | Null] +val d3: Array[String] = Array(null) // unsafe + +class C[T >: Null <: String] // define a type bound with unsafe conflict bound + +val n = nullOf[String] // apply a type bound unsafely +``` + +Without the [`unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$unsafeNulls$.html), all these unsafe operations will not be type-checked. + +[`unsafeNulls`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$unsafeNulls$.html) also works for extension methods and implicit search. + +```scala +import scala.language.unsafeNulls + +val x = "hello, world!".split(" ").map(_.length) + +given Conversion[String, Array[String]] = _ => ??? + +val y: String | Null = ??? +val z: Array[String | Null] = y +``` + +## Binary Compatibility + +Our strategy for binary compatibility with Scala binaries that predate explicit nulls +and new libraries compiled without `-Yexplicit-nulls` is to leave the types unchanged +and be compatible but unsound. + +[More details](https://dotty.epfl.ch/docs/internals/explicit-nulls.html) diff --git a/docs/_spec/TODOreference/experimental/fewer-braces.md b/docs/_spec/TODOreference/experimental/fewer-braces.md new file mode 100644 index 000000000000..eb454886ad03 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/fewer-braces.md @@ -0,0 +1,7 @@ +--- +layout: doc-page +title: "Fewer Braces" +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/fewer-braces.html +--- + +The documentation contained in this file is now part of [./indentation.html]. \ No newline at end of file diff --git a/docs/_spec/TODOreference/experimental/main-annotation.md b/docs/_spec/TODOreference/experimental/main-annotation.md new file mode 100644 index 000000000000..0c60e1050b87 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/main-annotation.md @@ -0,0 +1,97 @@ +--- +layout: doc-page +title: "MainAnnotation" +--- + +`MainAnnotation` provides a generic way to define main annotations such as `@main`. + +When a users annotates a method with an annotation that extends `MainAnnotation` a class with a `main` method will be generated. The main method will contain the code needed to parse the command line arguments and run the application. + +```scala +/** Sum all the numbers + * + * @param first Fist number to sum + * @param rest The rest of the numbers to sum + */ +@myMain def sum(first: Int, second: Int = 0, rest: Int*): Int = first + second + rest.sum +``` + +```scala +object foo { + def main(args: Array[String]): Unit = { + val mainAnnot = new myMain() + val info = new Info( + name = "foo.main", + documentation = "Sum all the numbers", + parameters = Seq( + new Parameter("first", "scala.Int", hasDefault=false, isVarargs=false, "Fist number to sum", Seq()), + new Parameter("second", "scala.Int", hasDefault=true, isVarargs=false, "", Seq()), + new Parameter("rest", "scala.Int" , hasDefault=false, isVarargs=true, "The rest of the numbers to sum", Seq()) + ) + ) + val mainArgsOpt = mainAnnot.command(info, args) + if mainArgsOpt.isDefined then + val mainArgs = mainArgsOpt.get + val args0 = mainAnnot.argGetter[Int](info.parameters(0), mainArgs(0), None) // using a parser of Int + val args1 = mainAnnot.argGetter[Int](info.parameters(1), mainArgs(1), Some(() => sum$default$1())) // using a parser of Int + val args2 = mainAnnot.varargGetter[Int](info.parameters(2), mainArgs.drop(2)) // using a parser of Int + mainAnnot.run(() => sum(args0(), args1(), args2()*)) + } +} +``` + +The implementation of the `main` method first instantiates the annotation and then call `command`. +When calling the `command`, the arguments can be checked and preprocessed. +Then it defines a series of argument getters calling `argGetter` for each parameter and `varargGetter` for the last one if it is a varargs. `argGetter` gets an optional lambda that computes the default argument. +Finally, the `run` method is called to run the application. It receives a by-name argument that contains the call the annotated method with the instantiations arguments (using the lambdas from `argGetter`/`varargGetter`). + + +Example of implementation of `myMain` that takes all arguments positionally. It used `util.CommandLineParser.FromString` and expects no default arguments. For simplicity, any errors in preprocessing or parsing results in crash. + +```scala +// Parser used to parse command line arguments +import scala.util.CommandLineParser.FromString[T] + +// Result type of the annotated method is Int and arguments are parsed using FromString +@experimental class myMain extends MainAnnotation[FromString, Int]: + import MainAnnotation.{ Info, Parameter } + + def command(info: Info, args: Seq[String]): Option[Seq[String]] = + if args.contains("--help") then + println(info.documentation) + None // do not parse or run the program + else if info.parameters.exists(_.hasDefault) then + println("Default arguments are not supported") + None + else if info.hasVarargs then + val numPlainArgs = info.parameters.length - 1 + if numPlainArgs > args.length then + println("Not enough arguments") + None + else + Some(args) + else + if info.parameters.length > args.length then + println("Not enough arguments") + None + else if info.parameters.length < args.length then + println("Too many arguments") + None + else + Some(args) + + def argGetter[T](param: Parameter, arg: String, defaultArgument: Option[() => T])(using parser: FromString[T]): () => T = + () => parser.fromString(arg) + + def varargGetter[T](param: Parameter, args: Seq[String])(using parser: FromString[T]): () => Seq[T] = + () => args.map(arg => parser.fromString(arg)) + + def run(program: () => Int): Unit = + println("executing program") + + val result = program() + println("result: " + result) + println("executed program") + +end myMain +``` diff --git a/docs/_spec/TODOreference/experimental/named-typeargs-spec.md b/docs/_spec/TODOreference/experimental/named-typeargs-spec.md new file mode 100644 index 000000000000..9e1113bbac86 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/named-typeargs-spec.md @@ -0,0 +1,41 @@ +--- +layout: doc-page +title: "Named Type Arguments - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/named-typeargs-spec.html +--- + +In this section we give more details about the [named type arguments](named-typeargs.md) (*experimental*). + +## Syntax + +The addition to the grammar is: + +``` +SimpleExpr1 ::= ... + | SimpleExpr (TypeArgs | NamedTypeArgs) +NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ +NamedTypeArg ::= id ‘=’ Type +``` + +Note in particular that named arguments cannot be passed to type constructors: + +``` scala +class C[T] + +val x: C[T = Int] = // error + new C[T = Int] // error + +class E extends C[T = Int] // error +``` + +## Compatibility considerations + +Named type arguments do not have an impact on binary compatibility, but they +have an impact on source compatibility: if the name of a method type parameter +is changed, any existing named reference to this parameter will break. This +means that the names of method type parameters are now part of the public API +of a library. + +(Unimplemented proposal: to mitigate this, +[`scala.deprecatedName`](https://www.scala-lang.org/api/current/scala/deprecatedName.html) +could be extended to also be applicable on method type parameters.) diff --git a/docs/_spec/TODOreference/experimental/named-typeargs.md b/docs/_spec/TODOreference/experimental/named-typeargs.md new file mode 100644 index 000000000000..4928a40f8a6a --- /dev/null +++ b/docs/_spec/TODOreference/experimental/named-typeargs.md @@ -0,0 +1,34 @@ +--- +layout: doc-page +title: "Named Type Arguments" +redirectFrom: /docs/reference/other-new-features/named-typeargs.html +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/named-typeargs.html +--- + +**Note:** This feature is implemented in Scala 3, but is not expected to be part of Scala 3.0. + +Type arguments of methods can now be specified by name as well as by position. Example: + +``` scala +def construct[Elem, Coll[_]](xs: Elem*): Coll[Elem] = ??? + +val xs1 = construct[Coll = List, Elem = Int](1, 2, 3) +val xs2 = construct[Coll = List](1, 2, 3) +``` + +Similar to a named value argument `(x = e)`, a named type argument +`[X = T]` instantiates the type parameter `X` to the type `T`. +Named type arguments do not have to be in order (see `xs1` above) and +unspecified arguments are inferred by the compiler (see `xs2` above). +Type arguments must be all named or un-named, mixtures of named and +positional type arguments are not supported. + +## Motivation + +The main benefit of named type arguments is that unlike positional arguments, +you are allowed to omit passing arguments for some parameters, like in the +definition of `xs2` above. A missing type argument is inferred as usual by +local type inference. This is particularly useful in situations where some type +arguments can be easily inferred from others. + +[More details](./named-typeargs-spec.md) diff --git a/docs/_spec/TODOreference/experimental/numeric-literals.md b/docs/_spec/TODOreference/experimental/numeric-literals.md new file mode 100644 index 000000000000..f493ef459265 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/numeric-literals.md @@ -0,0 +1,257 @@ +--- +layout: doc-page +title: "Numeric Literals" +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/numeric-literals.html +--- + +**Note**: This feature is not yet part of the Scala 3 language definition. It can be made available by a language import: + +```scala +import scala.language.experimental.genericNumberLiterals +``` + +In Scala 2, numeric literals were confined to the primitive numeric types `Int`, `Long`, `Float`, and `Double`. Scala 3 allows to write numeric literals also for user-defined types. Example: + +```scala +val x: Long = -10_000_000_000 +val y: BigInt = 0x123_abc_789_def_345_678_901 +val z: BigDecimal = 110_222_799_799.99 + +(y: BigInt) match + case 123_456_789_012_345_678_901 => +``` + +The syntax of numeric literals is the same as before, except there are no pre-set limits +how large they can be. + +## Meaning of Numeric Literals + +The meaning of a numeric literal is determined as follows: + +- If the literal ends with `l` or `L`, it is a `Long` integer (and must fit in its legal range). +- If the literal ends with `f` or `F`, it is a single precision floating point number of type `Float`. +- If the literal ends with `d` or `D`, it is a double precision floating point number of type `Double`. + +In each of these cases the conversion to a number is exactly as in Scala 2 or in Java. If a numeric literal does _not_ end in one of these suffixes, its meaning is determined by the expected type: + +1. If the expected type is `Int`, `Long`, `Float`, or `Double`, the literal is + treated as a standard literal of that type. +2. If the expected type is a fully defined type `T` that has a given instance of type + [`scala.util.FromDigits[T]`](https://scala-lang.org/api/3.x/scala/util/FromDigits.html), the literal is converted to a value of type `T` by passing it as an argument to + the `fromDigits` method of that instance (more details below). +3. Otherwise, the literal is treated as a `Double` literal (if it has a decimal point or an + exponent), or as an `Int` literal (if not). (This last possibility is again as in Scala 2 or Java.) + +With these rules, the definition + +```scala +val x: Long = -10_000_000_000 +``` + +is legal by rule (1), since the expected type is `Long`. The definitions + +```scala +val y: BigInt = 0x123_abc_789_def_345_678_901 +val z: BigDecimal = 111222333444.55 +``` + +are legal by rule (2), since both `BigInt` and `BigDecimal` have [`FromDigits`](https://scala-lang.org/api/3.x/scala/util/FromDigits.html) instances (which implement the `FromDigits` subclasses [`FromDigits.WithRadix`](https://scala-lang.org/api/3.x/scala/util/FromDigits$$WithRadix.html) and [`FromDigits.Decimal`](https://scala-lang.org/api/3.x/scala/util/FromDigits$$Decimal.html), respectively). On the other hand, + +```scala +val x = -10_000_000_000 +``` + +gives a type error, since without an expected type `-10_000_000_000` is treated by rule (3) as an `Int` literal, but it is too large for that type. + +## The `FromDigits` Trait + +To allow numeric literals, a type simply has to define a `given` instance of the +[`scala.util.FromDigits`](https://scala-lang.org/api/3.x/scala/util/FromDigits.html) type class, or one of its subclasses. `FromDigits` is defined as follows: + +```scala +trait FromDigits[T]: + def fromDigits(digits: String): T +``` + +Implementations of `fromDigits` convert strings of digits to the values of the +implementation type `T`. +The `digits` string consists of digits between `0` and `9`, possibly preceded by a +sign ("+" or "-"). Number separator characters `_` are filtered out before +the string is passed to `fromDigits`. + +The companion object [`FromDigits`](https://scala-lang.org/api/3.x/scala/util/FromDigits$.html) also defines subclasses of `FromDigits` for whole numbers with a given radix, for numbers with a decimal point, and for numbers that can have both a decimal point and an exponent: + +```scala +object FromDigits: + + /** A subclass of `FromDigits` that also allows to convert whole + * number literals with a radix other than 10 + */ + trait WithRadix[T] extends FromDigits[T]: + def fromDigits(digits: String): T = fromDigits(digits, 10) + def fromDigits(digits: String, radix: Int): T + + /** A subclass of `FromDigits` that also allows to convert number + * literals containing a decimal point ".". + */ + trait Decimal[T] extends FromDigits[T] + + /** A subclass of `FromDigits`that allows also to convert number + * literals containing a decimal point "." or an + * exponent `('e' | 'E')['+' | '-']digit digit*`. + */ + trait Floating[T] extends Decimal[T] +``` + +A user-defined number type can implement one of those, which signals to the compiler +that hexadecimal numbers, decimal points, or exponents are also accepted in literals +for this type. + +## Error Handling + +`FromDigits` implementations can signal errors by throwing exceptions of some subtype +of [`FromDigitsException`](https://scala-lang.org/api/3.x/scala/util/FromDigits$$FromDigitsException.html). `FromDigitsException` is defined with three subclasses in the +`FromDigits` object as follows: + +```scala +abstract class FromDigitsException(msg: String) extends NumberFormatException(msg) + +class NumberTooLarge (msg: String = "number too large") extends FromDigitsException(msg) +class NumberTooSmall (msg: String = "number too small") extends FromDigitsException(msg) +class MalformedNumber(msg: String = "malformed number literal") extends FromDigitsException(msg) +``` + +## Example + +As a fully worked out example, here is an implementation of a new numeric class, `BigFloat`, that accepts numeric literals. `BigFloat` is defined in terms of a `BigInt` mantissa and an `Int` exponent: + +```scala +case class BigFloat(mantissa: BigInt, exponent: Int): + override def toString = s"${mantissa}e${exponent}" +``` + +`BigFloat` literals can have a decimal point as well as an exponent. E.g. the following expression +should produce the `BigFloat` number `BigFloat(-123, 997)`: + +```scala +-0.123E+1000: BigFloat +``` + +The companion object of `BigFloat` defines an `apply` constructor method to construct a `BigFloat` +from a `digits` string. Here is a possible implementation: + +```scala +object BigFloat: + import scala.util.FromDigits + + def apply(digits: String): BigFloat = + val (mantissaDigits, givenExponent) = + digits.toUpperCase.split('E') match + case Array(mantissaDigits, edigits) => + val expo = + try FromDigits.intFromDigits(edigits) + catch case ex: FromDigits.NumberTooLarge => + throw FromDigits.NumberTooLarge(s"exponent too large: $edigits") + (mantissaDigits, expo) + case Array(mantissaDigits) => + (mantissaDigits, 0) + val (intPart, exponent) = + mantissaDigits.split('.') match + case Array(intPart, decimalPart) => + (intPart ++ decimalPart, givenExponent - decimalPart.length) + case Array(intPart) => + (intPart, givenExponent) + BigFloat(BigInt(intPart), exponent) +``` + +To accept `BigFloat` literals, all that's needed in addition is a `given` instance of type +`FromDigits.Floating[BigFloat]`: + +```scala + given FromDigits: FromDigits.Floating[BigFloat] with + def fromDigits(digits: String) = apply(digits) +end BigFloat +``` + +Note that the `apply` method does not check the format of the `digits` argument. It is +assumed that only valid arguments are passed. For calls coming from the compiler +that assumption is valid, since the compiler will first check whether a numeric +literal has the correct format before it gets passed on to a conversion method. + +## Compile-Time Errors + +With the setup of the previous section, a literal like + +```scala +1e10_0000_000_000: BigFloat +``` + +would be expanded by the compiler to + +```scala +BigFloat.FromDigits.fromDigits("1e100000000000") +``` + +Evaluating this expression throws a [`NumberTooLarge`](https://scala-lang.org/api/3.x/scala/util/FromDigits$$NumberTooLarge.html) exception at run time. We would like it to +produce a compile-time error instead. We can achieve this by tweaking the `BigFloat` class +with a small dose of metaprogramming. The idea is to turn the `fromDigits` method +into a macro, i.e. make it an inline method with a splice as right-hand side. +To do this, replace the `FromDigits` instance in the `BigFloat` object by the following two definitions: + +```scala +object BigFloat: + ... + + class FromDigits extends FromDigits.Floating[BigFloat]: + def fromDigits(digits: String) = apply(digits) + + given FromDigits with + override inline def fromDigits(digits: String) = ${ + fromDigitsImpl('digits) + } +``` + +Note that an inline method cannot directly fill in for an abstract method, since it produces +no code that can be executed at runtime. That is why we define an intermediary class +`FromDigits` that contains a fallback implementation which is then overridden by the inline +method in the `FromDigits` given instance. That method is defined in terms of a macro +implementation method `fromDigitsImpl`. Here is its definition: + +```scala + private def fromDigitsImpl(digits: Expr[String])(using ctx: Quotes): Expr[BigFloat] = + digits.value match + case Some(ds) => + try + val BigFloat(m, e) = apply(ds) + '{BigFloat(${Expr(m)}, ${Expr(e)})} + catch case ex: FromDigits.FromDigitsException => + ctx.error(ex.getMessage) + '{BigFloat(0, 0)} + case None => + '{apply($digits)} +end BigFloat +``` + +The macro implementation takes an argument of type `Expr[String]` and yields +a result of type `Expr[BigFloat]`. It tests whether its argument is a constant +string. If that is the case, it converts the string using the `apply` method +and lifts the resulting `BigFloat` back to `Expr` level. For non-constant +strings `fromDigitsImpl(digits)` is simply `apply(digits)`, i.e. everything is +evaluated at runtime in this case. + +The interesting part is the `catch` part of the case where `digits` is constant. +If the `apply` method throws a `FromDigitsException`, the exception's message is issued as a compile time error in the `ctx.error(ex.getMessage)` call. + +With this new implementation, a definition like + +```scala +val x: BigFloat = 1234.45e3333333333 +``` + +would give a compile time error message: + +```scala +3 | val x: BigFloat = 1234.45e3333333333 + | ^^^^^^^^^^^^^^^^^^ + | exponent too large: 3333333333 +``` diff --git a/docs/_spec/TODOreference/experimental/overview.md b/docs/_spec/TODOreference/experimental/overview.md new file mode 100644 index 000000000000..254f103896e4 --- /dev/null +++ b/docs/_spec/TODOreference/experimental/overview.md @@ -0,0 +1,29 @@ +--- +layout: doc-page +title: "Experimental" +nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/overview.html +redirectFrom: overview.html +--- + +## Experimental language features + +All experimental language features can be found under the `scala.language.experimental` package. +They are enabled by importing the feature or using the `-language` compiler flag. + +* [`erasedDefinitions`](./erased-defs.md): Enable support for `erased` modifier. +* `fewerBraces`: Enable support for using indentation for arguments. +* [`genericNumberLiterals`](./numeric-literals.md): Enable support for generic number literals. +* [`namedTypeArguments`](./named-typeargs.md): Enable support for named type arguments +* [`saferExceptions`](./canthrow.md): Enable support for checked exceptions. + +## Experimental language imports + +In general, experimental language features can be imported in an experimental scope (see [experimental definitions](../other-new-features/experimental-defs.md)). +They can be imported at the top-level if all top-level definitions are `@experimental`. + +## Experimental language features supported by special compiler options + +Some experimental language features that are still in research and development can be enabled with special compiler options. These include + +* [`-Yexplicit-nulls`](./explicit-nulls.md). Enable support for tracking null references in the type system. +* [`-Ycc`](./cc.md). Enable support for capture checking. diff --git a/docs/_spec/TODOreference/experimental/tupled-function.md b/docs/_spec/TODOreference/experimental/tupled-function.md new file mode 100644 index 000000000000..da108fc832ad --- /dev/null +++ b/docs/_spec/TODOreference/experimental/tupled-function.md @@ -0,0 +1,82 @@ +--- +layout: doc-page +title: "Tupled Function" +--- + +Tupled Function +---------------------- + +With functions bounded to arities up to 22 it was possible to generalize some operation on all function types using overloading. +Now that we have functions and tuples generalized to [arities above 22](../dropped-features/limit22.md) overloading is not an option anymore. +The type class `TupleFunction` provides a way to abstract directly over a function of any arity converting it to an equivalent function that receives all arguments in a single tuple. + +```scala +/** Type class relating a `FunctionN[..., R]` with an equivalent tupled function `Function1[TupleN[...], R]` + * + * @tparam F a function type + * @tparam G a tupled function type (function of arity 1 receiving a tuple as argument) + */ +@implicitNotFound("${F} cannot be tupled as ${G}") +sealed trait TupledFunction[F, G] { + def tupled(f: F): G + def untupled(g: G): F +} +``` + +The compiler will synthesize an instance of `TupledFunction[F, G]` if: + +* `F` is a function type of arity `N` +* `G` is a function with a single tuple argument of size `N` and its types are equal to the arguments of `F` +* The return type of `F` is equal to the return type of `G` +* `F` and `G` are the same sort of function (both are `(...) => R` or both are `(...) ?=> R`) +* If only one of `F` or `G` is instantiated the second one is inferred. + +Examples +-------- +`TupledFunction` can be used to generalize the `Function1.tupled`, ... `Function22.tupled` methods to functions of any arities. +The following defines `tupled` as [extension method](../contextual/extension-methods.html) ([full example](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-tupled.scala)). + +```scala +/** Creates a tupled version of this function: instead of N arguments, + * it accepts a single [[scala.Tuple]] with N elements as argument. + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ +extension [F, Args <: Tuple, R](f: F) + def tupled(using tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f) +``` + +`TupledFunction` can be used to generalize the `Function.untupled` to a function of any arities ([full example](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-untupled.scala)) + +```scala +/** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements, + * it accepts N arguments. + * + * This is a generalization of [[scala.Function.untupled]] that work on functions of any arity + * + * @tparam F the function type + * @tparam Args the tuple type with the same types as the function arguments of F + * @tparam R the return type of F + */ +extension [F, Args <: Tuple, R](f: Args => R) + def untupled(using tf: TupledFunction[F, Args => R]): F = tf.untupled(f) +``` + +`TupledFunction` can also be used to generalize the [`Tuple1.compose`](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-compose.scala) and [`Tuple1.andThen`](https://github.com/lampepfl/dotty/blob/main/tests/run/tupled-function-andThen.scala) methods to compose functions of larger arities and with functions that return tuples. + +```scala +/** Composes two instances of TupledFunction into a new TupledFunction, with this function applied last. + * + * @tparam F a function type + * @tparam G a function type + * @tparam FArgs the tuple type with the same types as the function arguments of F and return type of G + * @tparam GArgs the tuple type with the same types as the function arguments of G + * @tparam R the return type of F + */ +extension [F, G, FArgs <: Tuple, GArgs <: Tuple, R](f: F) + def compose(g: G)(using tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = { + (x: GArgs) => tf.tupled(f)(tg.tupled(g)(x)) +} +``` diff --git a/docs/_spec/TODOreference/features-classification.md b/docs/_spec/TODOreference/features-classification.md new file mode 100644 index 000000000000..36cea3b9e72d --- /dev/null +++ b/docs/_spec/TODOreference/features-classification.md @@ -0,0 +1,199 @@ +--- +layout: doc-page +title: "A Classification of Proposed Language Features" +nightlyOf: https://docs.scala-lang.org/scala3/reference/features-classification.html +--- + +This document provides an overview of the constructs proposed for Scala 3 with the aim to facilitate the discussion what to include and when to include it. It classifies features into eight groups: (1) essential foundations, (2) simplifications, (3) restrictions, (4) dropped features, (5) changed features, (6) new features, (7) features oriented towards metaprogramming with the aim to replace existing macros, and (8) changes to type checking and inference. + +Each group contains sections classifying the status (i.e. relative importance to be a part of Scala 3, and relative urgency when to decide this) and the migration cost +of the constructs in it. + +The current document reflects the state of things as of April, 2019. It will be updated to reflect any future changes in that status. + +## Essential Foundations + +These new constructs directly model core features of [DOT](https://www.scala-lang.org/blog/2016/02/03/essence-of-scala.html), higher-kinded types, and the [SI calculus for implicit resolution](https://infoscience.epfl.ch/record/229878/files/simplicitly_1.pdf). + + - [Intersection types](new-types/intersection-types.md), replacing compound types, + - [Union types](new-types/union-types.md), + - [Type lambdas](new-types/type-lambdas.md), + replacing encodings using structural types and type projection. + - [Context functions](contextual/context-functions.md) offering abstraction over given parameters. + +**Status: essential** + +These are essential core features of Scala 3. Without them, Scala 3 would be a completely different language, with different foundations. + +**Migration cost: none to low** + +Since these are additions, there's generally no migration cost for old code. An exception are intersection types which replace compound types with slightly cleaned-up semantics. But few programs would be affected by this change. + +## Simplifications + +These constructs replace existing constructs with the aim of making the language safer and simpler to use, and to promote uniformity in code style. + + - [Trait parameters](other-new-features/trait-parameters.md) replace [early initializers](dropped-features/early-initializers.md) with a more generally useful construct. + - [Given instances](contextual/givens.md) + replace implicit objects and defs, focussing on intent over mechanism. + - [Using clauses](contextual/using-clauses.md) replace implicit parameters, avoiding their ambiguities. + - [Extension methods](contextual/extension-methods.md) replace implicit classes with a clearer and simpler mechanism. + - [Opaque type aliases](other-new-features/opaques.md) replace most uses + of value classes while guaranteeing absence of boxing. + - [Top-level definitions](dropped-features/package-objects.md) replace package objects, dropping syntactic boilerplate. + - [Export clauses](other-new-features/export.md) + provide a simple and general way to express aggregation, which can replace the + previous facade pattern of package objects inheriting from classes. + - [Vararg splices](changed-features/vararg-splices.md) now use the form `*` instead of `@ _*`, mirroring vararg expressions, + - [Creator applications](other-new-features/creator-applications.md) allow using simple function call syntax + instead of `new` expressions. `new` expressions stay around as a fallback for + the cases where creator applications cannot be used. + +With the exception of early initializers and old-style vararg splices, all superseded constructs continue to be available in Scala 3.0. The plan is to deprecate and phase them out later. + +Value classes (superseded by opaque type aliases) are a special case. There are currently no deprecation plans for value classes, since we might bring them back in a more general form if they are supported natively by the JVM as is planned by project Valhalla. + +**Status: bimodal: now or never / can delay** + +These are essential simplifications. If we decide to adopt them, we should do it for 3.0. Otherwise we are faced with the awkward situation that the Scala 3 documentation has to describe an old feature that will be replaced or superseded by a simpler one in the future. + +On the other hand, we need to decide now only about the new features in this list. The decision to drop the superseded features can be delayed. Of course, adopting a new feature without deciding to drop the superseded feature will make the language larger. + +**Migration cost: moderate** + +For the next several versions, old features will remain available and deprecation and rewrite techniques can make any migration effort low and gradual. + + +## Restrictions + +These constructs are restricted to make the language safer. + + - [Implicit Conversions](contextual/conversions.md): there is only one way to define implicit conversions instead of many, and potentially surprising implicit conversions require a language import. + - [Given Imports](contextual/given-imports.md): implicits now require a special form of import, to make the import clearly visible. + - [Type Projection](dropped-features/type-projection.md): only classes can be used as prefix `C` of a type projection `C#A`. Type projection on abstract types is no longer supported since it is unsound. + - [Multiversal equality](contextual/multiversal-equality.md) implements an "opt-in" scheme to rule out nonsensical comparisons with `==` and `!=`. + - [infix](https://github.com/lampepfl/dotty/pull/5975) + makes method application syntax uniform across code bases. + +Unrestricted implicit conversions continue to be available in Scala 3.0, but will be deprecated and removed later. Unrestricted versions of the other constructs in the list above are available only under `-source 3.0-migration`. + +**Status: now or never** + +These are essential restrictions. If we decide to adopt them, we should do it for 3.0. Otherwise we are faced with the awkward situation that the Scala 3 documentation has to describe a feature that will be restricted in the future. + +**Migration cost: low to high** + + - _low_: multiversal equality rules out code that is nonsensical, so any rewrites required by its adoption should be classified as bug fixes. + - _moderate_: Restrictions to implicits can be accommodated by straightforward rewriting. + - _high_: Unrestricted type projection cannot always rewritten directly since it is unsound in general. + +## Dropped Constructs + +These constructs are proposed to be dropped without a new construct replacing them. The motivation for dropping these constructs is to simplify the language and its implementation. + + - [DelayedInit](dropped-features/delayed-init.md), + - [Existential types](dropped-features/existential-types.md), + - [Procedure syntax](dropped-features/procedure-syntax.md), + - [Class shadowing](dropped-features/class-shadowing.md), + - [XML literals](dropped-features/xml.md), + - [Symbol literals](dropped-features/symlits.md), + - [Auto application](dropped-features/auto-apply.md), + - [Weak conformance](dropped-features/weak-conformance.md), + - [Compound types](new-types/intersection-types.md), + - [Auto tupling](https://github.com/lampepfl/dotty/pull/4311) (implemented, but not merged). + +The date when these constructs are dropped varies. The current status is: + + - Not implemented at all: + - DelayedInit, existential types, weak conformance. + - Supported under `-source 3.0-migration`: + - procedure syntax, class shadowing, symbol literals, auto application, auto tupling in a restricted form. + - Supported in 3.0, to be deprecated and phased out later: + - XML literals, compound types. + +**Status: mixed** + +Currently unimplemented features would require considerable implementation effort which would in most cases make the compiler more buggy and fragile and harder to understand. If we do not decide to drop them, they will probably show up as "not yet implemented" in the Scala 3.0 release. + +Currently implemented features could stay around indefinitely. Updated docs may simply ignore them, in the expectation that they might go away eventually. So the decision about their removal can be delayed. + +**Migration cost: moderate to high** + +Dropped features require rewrites to avoid their use in programs. These rewrites can sometimes be automatic (e.g. for procedure syntax, symbol literals, auto application) +and sometimes need to be manual (e.g. class shadowing, auto tupling). Sometimes the rewrites would have to be non-local, affecting use sites as well as definition sites (e.g., in the case of `DelayedInit`, unless we find a solution). + +## Changes + +These constructs have undergone changes to make them more regular and useful. + + - [Structural Types](changed-features/structural-types.md): They now allow pluggable implementations, which greatly increases their usefulness. Some usage patterns are restricted compared to the status quo. + - [Name-based pattern matching](changed-features/pattern-matching.md): The existing undocumented Scala 2 implementation has been codified in a slightly simplified form. + - [Eta expansion](changed-features/eta-expansion.md) is now performed universally also in the absence of an expected type. The postfix `_` operator is thus made redundant. It will be deprecated and dropped after Scala 3.0. + - [Implicit Resolution](changed-features/implicit-resolution.md): The implicit resolution rules have been cleaned up to make them more useful and less surprising. Implicit scope is restricted to no longer include package prefixes. + +Most aspects of old-style implicit resolution are still available under `-source 3.0-migration`. The other changes in this list are applied unconditionally. + +**Status: strongly advisable** + +The features have been implemented in their new form in Scala 3.0's compiler. They provide clear improvements in simplicity and functionality compared to the status quo. Going back would require significant implementation effort for a net loss of functionality. + +**Migration cost: low to high** + +Only a few programs should require changes, but some necessary changes might be non-local (as in the case of restrictions to implicit scope). + +## New Constructs + +These are additions to the language that make it more powerful or pleasant to use. + + - [Enums](enums/enums.md) provide concise syntax for enumerations and [algebraic data types](enums/adts.md). + - [Parameter untupling](other-new-features/parameter-untupling.md) avoids having to use `case` for tupled parameter destructuring. + - [Dependent function types](new-types/dependent-function-types.md) generalize dependent methods to dependent function values and types. + - [Polymorphic function types](https://github.com/lampepfl/dotty/pull/4672) generalize polymorphic methods to dependent function values and types. _Current status_: There is a proposal, and a prototype implementation, but the implementation has not been finalized or merged yet. + - [Kind polymorphism](other-new-features/kind-polymorphism.md) allows the definition of operators working equally on types and type constructors. + +**Status: mixed** + +Enums offer an essential simplification of fundamental use patterns, so they should be adopted for Scala 3.0. Auto-parameter tupling is a very small change that removes some awkwardness, so it might as well be adopted now. The other features constitute more specialized functionality which could be introduced in later versions. On the other hand, except for polymorphic function types they are all fully implemented, so if the Scala 3.0 spec does not include them, they might be still made available under a language flag. + +**Migration cost: none** + +Being new features, existing code migrates without changes. To be sure, sometimes it would be attractive to rewrite code to make use of the new features in order to increase clarity and conciseness. + +## Metaprogramming + +The following constructs together aim to put metaprogramming in Scala on a new basis. So far, metaprogramming was achieved by a combination of macros and libraries such as [Shapeless](https://github.com/milessabin/shapeless) that were in turn based on some key macros. Current Scala 2 macro mechanisms are a thin veneer on top the current Scala 2 compiler, which makes them fragile and in many cases impossible to port to Scala 3. + +It's worth noting that macros were never included in the [Scala 2 language specification](https://scala-lang.org/files/archive/spec/2.13/) and were so far made available only under an `-experimental` flag. This has not prevented their widespread usage. + +To enable porting most uses of macros, we are experimenting with the advanced language constructs listed below. These designs are more provisional than the rest of the proposed language constructs for Scala 3.0. There might still be some changes until the final release. Stabilizing the feature set needed for metaprogramming is our first priority. + +- [Match types](new-types/match-types.md) allow computation on types. +- [Inline](metaprogramming/inline.md) provides +by itself a straightforward implementation of some simple macros and is at the same time an essential building block for the implementation of complex macros. +- [Quotes and splices](metaprogramming/macros.md) provide a principled way to express macros and staging with a unified set of abstractions. +- [Type class derivation](contextual/derivation.md) provides an in-language implementation of the `Gen` macro in Shapeless and other foundational libraries. The new implementation is more robust, efficient and easier to use than the macro. +- [Implicit by-name parameters](contextual/by-name-context-parameters.md) provide a more robust in-language implementation of the `Lazy` macro in Shapeless. + +**Status: not yet settled** + +We know we need a practical replacement for current macros. The features listed above are very promising in that respect, but we need more complete implementations and more use cases to reach a final verdict. + +**Migration cost: very high** + +Existing macro libraries will have to be rewritten from the ground up. In many cases the rewritten libraries will turn out to be simpler and more robust than the old ones, but that does not relieve one of the cost of the rewrites. It's currently unclear to what degree users of macro libraries will be affected. We aim to provide sufficient functionality so that core macros can be re-implemented fully, but given the vast feature set of the various macro extensions to Scala 2 it is difficult to arrive at a workable limitation of scope. + +## Changes to Type Checking and Inference + +The Scala 3 compiler uses a new algorithm for type inference, which relies on a general subtype constraint solver. The new algorithm often [works better than the old](https://contributors.scala-lang.org/t/better-type-inference-for-scala-send-us-your-problematic-cases/2410), but there are inevitably situations where the results of both algorithms differ, leading to errors diagnosed by Scala 3 for programs that the Scala 2 compiler accepts. + +**Status: essential** + +The new type-checking and inference algorithms are the essential core of the new compiler. They cannot be reverted without dropping the whole implementation of Scala 3. + +**Migration cost: high** + +Some existing programs will break and, given the complex nature of type inference, it will not always be clear what change caused the breakage and how to fix it. + +In our experience, macros and changes in type and implicit argument inference together cause the large majority of problems encountered when porting existing code to Scala 3. The latter source of problems could be addressed systematically by a tool that added all inferred types and implicit arguments to a Scala 2 source code file. Most likely such a tool would be implemented as a [Scala 2 compiler plugin](https://docs.scala-lang.org/overviews/plugins/index.html). The resulting code would have a greatly increased likelihood to compile under Scala 3, but would often be bulky to the point of being unreadable. A second part of the rewriting tool should then selectively and iteratively remove type and implicit annotations that were synthesized by the first part as long as they compile under Scala 3. This second part could be implemented as a program that invokes the Scala 3 compiler `scalac` programmatically. + +Several people have proposed such a tool for some time now. I believe it is time we find the will and the resources to actually implement it. diff --git a/docs/_spec/TODOreference/language-versions/binary-compatibility.md b/docs/_spec/TODOreference/language-versions/binary-compatibility.md new file mode 100644 index 000000000000..df1c19f97868 --- /dev/null +++ b/docs/_spec/TODOreference/language-versions/binary-compatibility.md @@ -0,0 +1,13 @@ +--- +layout: doc-page +title: "Binary Compatibility" +nightlyOf: https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html +--- + +In Scala 2 different minor versions of the compiler were free to change the way how they encode different language features in JVM bytecode so each bump of the compiler's minor version resulted in breaking binary compatibility and if a project had any Scala dependencies they all needed to be (cross-)compiled to the same minor Scala version that was used in that project itself. On the contrary, Scala 3 has a stable encoding into JVM bytecode. + +In addition to classfiles the compilation process in Scala 3 also produces files with `.tasty` extension. The [TASTy](https://docs.scala-lang.org/scala3/guides/tasty-overview.html) format is an intermediate representation of Scala code containing full information about sources together with information provided by the typer. Some of this information is lost during generation of bytecode so Scala 3 compilers read TASTy files during compilation in addition to classfiles to know the exact types of values, methods, etc. in already compiled classes (although compilation from TASTy files only is also possible). TASTy files are also typically distributed together with classfiles in published artifacts. + +TASTy format is extensible but it preserves backward compatibility and the evolution happens between minor releases of the language. This means a Scala compiler in version `3.x1.y1` is able to read TASTy files produced by another compiler in version `3.x2.y2` if `x1 >= x2` (assuming two stable versions of the compiler are considered - `SNAPSHOT` or `NIGHTLY` compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version; also compilers in stable versions cannot read TASTy generated by an unstable version). + +TASTy version number has the format of `.-` and the numbering changes in parallel to language releases in such a way that a bump in language minor version corresponds to a bump in TASTy minor version (e.g. for Scala `3.0.0` the TASTy version is `28.0-0`). Experimental version set to 0 signifies a stable version while others are considered unstable/experimental. TASTy version is not strictly bound to the data format itself - any changes to the API of the standard library also require a change in TASTy minor version. diff --git a/docs/_spec/TODOreference/language-versions/language-versions.md b/docs/_spec/TODOreference/language-versions/language-versions.md new file mode 100644 index 000000000000..2dfd04857cab --- /dev/null +++ b/docs/_spec/TODOreference/language-versions/language-versions.md @@ -0,0 +1,7 @@ +--- +layout: index +title: "Language Versions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/language-versions/index.html +--- + +Additional information on interoperability and migration between Scala 2 and 3 can be found [here](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html). diff --git a/docs/_spec/TODOreference/language-versions/source-compatibility.md b/docs/_spec/TODOreference/language-versions/source-compatibility.md new file mode 100644 index 000000000000..4d5b468ac8f2 --- /dev/null +++ b/docs/_spec/TODOreference/language-versions/source-compatibility.md @@ -0,0 +1,43 @@ +--- +layout: doc-page +title: "Source Compatibility" +nightlyOf: https://docs.scala-lang.org/scala3/reference/language-versions/source-compatibility.html +--- + +Scala 3 does NOT guarantee source compatibility between different minor language versions (e.g. some syntax valid in 3.x might get deprecated and then phased out in 3.y for y > x). There are also some syntax structures that were valid in Scala 2 but are not anymore in Scala 3. However the compiler provides a possibility to specify the desired version of syntax used in a particular file or globally for a run of the compiler to make migration between versions easier. + +The default Scala language syntax version currently supported by the Dotty compiler is [`3.2`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/2$.html). There are also other language versions that can be specified instead: + +- [`3.0-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0-migration$.html): Same as +`3.0` and `3.1`, but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it + + - flags some Scala 2 constructs that are disallowed in Scala 3 as migration warnings instead of hard errors, + - changes some rules to be more lenient and backwards compatible with Scala 2.13 + - gives some additional warnings where the semantics has changed between Scala 2.13 and 3.0 + - in conjunction with `-rewrite`, offer code rewrites from Scala 2.13 to 3.0. + +- [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html), [`3.1`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/1$.html): the default set of features included in scala versions `3.0.0` to `3.1.3`. +- [`3.2`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/2$.html): the same as `3.0` and `3.1`, but in addition: + - [stricter pattern bindings](https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html) are now enabled (part of `future` in earlier `3.x` releases), producing warnings for refutable patterns. These warnings can be silenced to achieve the same runtime behavior, but in `future` they become errors and refutable patterns will not compile. + - [Nonlocal returns](https://docs.scala-lang.org/scala3/reference/dropped-features/nonlocal-returns.html) now produce a warning upon usage (they are still an error under `future`). +- [`3.2-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/2-migration$.html): the same as `3.2`, but in conjunction with `-rewrite`, offer code rewrites from Scala `3.0/3.1` to `3.2`. +- [`future`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future$.html): A preview of changes that will be introduced in `3.x` versions after `3.2`. +Some Scala 2 specific idioms are dropped in this version. The feature set supported by this version may grow over time as features become stabilised for preview. + +- [`future-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$future-migration$.html): Same as `future` but with additional helpers to migrate from `3.2`. Similarly to the helpers available under `3.0-migration`, these include migration warnings and optional rewrites. + +There are two ways to specify a language version : + +- with a `-source` command line setting, e.g. `-source 3.0-migration`. +- with a `scala.language` import at the top of a source file, e.g: + +```scala +package p +import scala.language.`future-migration` + +class C { ... } +``` + +Language imports supersede command-line settings in the source files where they are specified. Only one language import specifying a source version is allowed in a source file, and it must come before any definitions in that file. + +**Note**: The [Scala 3 Migration Guide](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html) gives further information to help the Scala programmer moving from Scala 2.13 to Scala 3. diff --git a/docs/_spec/TODOreference/metaprogramming/compiletime-ops.md b/docs/_spec/TODOreference/metaprogramming/compiletime-ops.md new file mode 100644 index 000000000000..a43c941ae943 --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/compiletime-ops.md @@ -0,0 +1,294 @@ +--- +layout: doc-page +title: "Compile-time operations" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/compiletime-ops.html +--- + +## The `scala.compiletime` Package + +The [`scala.compiletime`](https://scala-lang.org/api/3.x/scala/compiletime.html) package contains helper definitions that provide support for compile-time operations over values. They are described in the following. + +### `constValue` and `constValueOpt` + +`constValue` is a function that produces the constant value represented by a +type. + +```scala +import scala.compiletime.constValue +import scala.compiletime.ops.int.S + +transparent inline def toIntC[N]: Int = + inline constValue[N] match + case 0 => 0 + case _: S[n1] => 1 + toIntC[n1] + +inline val ctwo = toIntC[2] +``` + +`constValueOpt` is the same as `constValue`, however returning an `Option[T]` +enabling us to handle situations where a value is not present. Note that `S` is +the type of the successor of some singleton type. For example the type `S[1]` is +the singleton type `2`. + +### `erasedValue` + +So far we have seen inline methods that take terms (tuples and integers) as +parameters. What if we want to base case distinctions on types instead? For +instance, one would like to be able to write a function `defaultValue`, that, +given a type `T`, returns optionally the default value of `T`, if it exists. +We can already express this using rewrite match expressions and a simple +helper function, `scala.compiletime.erasedValue`, which is defined as follows: + +```scala +def erasedValue[T]: T +``` + +The `erasedValue` function _pretends_ to return a value of its type argument `T`. +Calling this function will always result in a compile-time error unless the call +is removed from the code while inlining. + +Using `erasedValue`, we can then define `defaultValue` as follows: + +```scala +import scala.compiletime.erasedValue + +transparent inline def defaultValue[T] = + inline erasedValue[T] match + case _: Byte => Some(0: Byte) + case _: Char => Some(0: Char) + case _: Short => Some(0: Short) + case _: Int => Some(0) + case _: Long => Some(0L) + case _: Float => Some(0.0f) + case _: Double => Some(0.0d) + case _: Boolean => Some(false) + case _: Unit => Some(()) + case _ => None +``` + +Then: + +```scala +val dInt: Some[Int] = defaultValue[Int] +val dDouble: Some[Double] = defaultValue[Double] +val dBoolean: Some[Boolean] = defaultValue[Boolean] +val dAny: None.type = defaultValue[Any] +``` + +As another example, consider the type-level version of `toInt` below: +given a _type_ representing a Peano number, +return the integer _value_ corresponding to it. +Consider the definitions of numbers as in the _Inline +Match_ section above. Here is how `toIntT` can be defined: + +```scala +transparent inline def toIntT[N <: Nat]: Int = + inline scala.compiletime.erasedValue[N] match + case _: Zero.type => 0 + case _: Succ[n] => toIntT[n] + 1 + +inline val two = toIntT[Succ[Succ[Zero.type]]] +``` + +`erasedValue` is an `erased` method so it cannot be used and has no runtime +behavior. Since `toIntT` performs static checks over the static type of `N` we +can safely use it to scrutinize its return type (`S[S[Z]]` in this case). + +### `error` + +The `error` method is used to produce user-defined compile errors during inline expansion. +It has the following signature: + +```scala +inline def error(inline msg: String): Nothing +``` + +If an inline expansion results in a call `error(msgStr)` the compiler +produces an error message containing the given `msgStr`. + +```scala +import scala.compiletime.{error, codeOf} + +inline def fail() = + error("failed for a reason") + +fail() // error: failed for a reason +``` + +or + +```scala +inline def fail(inline p1: Any) = + error("failed on: " + codeOf(p1)) + +fail(identity("foo")) // error: failed on: identity[String]("foo") +``` + +### The `scala.compiletime.ops` package + +The [`scala.compiletime.ops`](https://scala-lang.org/api/3.x/scala/compiletime/ops.html) package contains types that provide support for +primitive operations on singleton types. For example, +`scala.compiletime.ops.int.*` provides support for multiplying two singleton +`Int` types, and `scala.compiletime.ops.boolean.&&` for the conjunction of two +`Boolean` types. When all arguments to a type in `scala.compiletime.ops` are +singleton types, the compiler can evaluate the result of the operation. + +```scala +import scala.compiletime.ops.int.* +import scala.compiletime.ops.boolean.* + +val conjunction: true && true = true +val multiplication: 3 * 5 = 15 +``` + +Many of these singleton operation types are meant to be used infix (as in [SLS §3.2.10](https://www.scala-lang.org/files/archive/spec/2.13/03-types.html#infix-types)). + +Since type aliases have the same precedence rules as their term-level +equivalents, the operations compose with the expected precedence rules: + +```scala +import scala.compiletime.ops.int.* +val x: 1 + 2 * 3 = 7 +``` + +The operation types are located in packages named after the type of the +left-hand side parameter: for instance, `scala.compiletime.ops.int.+` represents +addition of two numbers, while `scala.compiletime.ops.string.+` represents string +concatenation. To use both and distinguish the two types from each other, a +match type can dispatch to the correct implementation: + +```scala +import scala.compiletime.ops.* + +import scala.annotation.infix + +type +[X <: Int | String, Y <: Int | String] = (X, Y) match + case (Int, Int) => int.+[X, Y] + case (String, String) => string.+[X, Y] + +val concat: "a" + "b" = "ab" +val addition: 1 + 1 = 2 +``` + +## Summoning Implicits Selectively + +It is foreseen that many areas of typelevel programming can be done with rewrite +methods instead of implicits. But sometimes implicits are unavoidable. The +problem so far was that the Prolog-like programming style of implicit search +becomes viral: Once some construct depends on implicit search it has to be +written as a logic program itself. Consider for instance the problem of creating +a `TreeSet[T]` or a `HashSet[T]` depending on whether `T` has an `Ordering` or +not. We can create a set of implicit definitions like this: + +```scala +trait SetFor[T, S <: Set[T]] + +class LowPriority: + implicit def hashSetFor[T]: SetFor[T, HashSet[T]] = ... + +object SetsFor extends LowPriority: + implicit def treeSetFor[T: Ordering]: SetFor[T, TreeSet[T]] = ... +``` + +Clearly, this is not pretty. Besides all the usual indirection of implicit +search, we face the problem of rule prioritization where we have to ensure that +`treeSetFor` takes priority over `hashSetFor` if the element type has an +ordering. This is solved (clumsily) by putting `hashSetFor` in a superclass +`LowPriority` of the object `SetsFor` where `treeSetFor` is defined. Maybe the +boilerplate would still be acceptable if the crufty code could be contained. +However, this is not the case. Every user of the abstraction has to be +parameterized itself with a `SetFor` implicit. Considering the simple task _"I +want a `TreeSet[T]` if `T` has an ordering and a `HashSet[T]` otherwise"_, this +seems like a lot of ceremony. + +There are some proposals to improve the situation in specific areas, for +instance by allowing more elaborate schemes to specify priorities. But they all +keep the viral nature of implicit search programs based on logic programming. + +By contrast, the new `summonFrom` construct makes implicit search available +in a functional context. To solve the problem of creating the right set, one +would use it as follows: + +```scala +import scala.compiletime.summonFrom + +inline def setFor[T]: Set[T] = summonFrom { + case ord: Ordering[T] => new TreeSet[T]()(using ord) + case _ => new HashSet[T] +} +``` + +A `summonFrom` call takes a pattern matching closure as argument. All patterns +in the closure are type ascriptions of the form `identifier : Type`. + +Patterns are tried in sequence. The first case with a pattern `x: T` such that an implicit value of type `T` can be summoned is chosen. + +Alternatively, one can also use a pattern-bound given instance, which avoids the explicit using clause. For instance, `setFor` could also be formulated as follows: + +```scala +import scala.compiletime.summonFrom + +inline def setFor[T]: Set[T] = summonFrom { + case given Ordering[T] => new TreeSet[T] + case _ => new HashSet[T] +} +``` + +`summonFrom` applications must be reduced at compile time. + +Consequently, if we summon an `Ordering[String]` the code above will return a +new instance of `TreeSet[String]`. + +```scala +summon[Ordering[String]] + +println(setFor[String].getClass) // prints class scala.collection.immutable.TreeSet +``` + +**Note** `summonFrom` applications can raise ambiguity errors. Consider the following +code with two givens in scope of type `A`. The pattern match in `f` will raise +an ambiguity error of `f` is applied. + +```scala +class A +given a1: A = new A +given a2: A = new A + +inline def f: Any = summonFrom { + case given _: A => ??? // error: ambiguous givens +} +``` + +## `summonInline` + +The shorthand `summonInline` provides a simple way to write a `summon` that is delayed until the call is inlined. +Unlike `summonFrom`, `summonInline` also yields the implicit-not-found error, if a given instance of the summoned +type is not found. +```scala +import scala.compiletime.summonInline +import scala.annotation.implicitNotFound + +@implicitNotFound("Missing One") +trait Missing1 + +@implicitNotFound("Missing Two") +trait Missing2 + +trait NotMissing +given NotMissing = ??? + +transparent inline def summonInlineCheck[T <: Int](inline t : T) : Any = + inline t match + case 1 => summonInline[Missing1] + case 2 => summonInline[Missing2] + case _ => summonInline[NotMissing] + +val missing1 = summonInlineCheck(1) // error: Missing One +val missing2 = summonInlineCheck(2) // error: Missing Two +val notMissing : NotMissing = summonInlineCheck(3) +``` + +## Reference + +For more information about compile-time operations, see [PR #4768](https://github.com/lampepfl/dotty/pull/4768), +which explains how `summonFrom`'s predecessor (implicit matches) can be used for typelevel programming and code specialization and [PR #7201](https://github.com/lampepfl/dotty/pull/7201) which explains the new `summonFrom` syntax. diff --git a/docs/_spec/TODOreference/metaprogramming/inline.md b/docs/_spec/TODOreference/metaprogramming/inline.md new file mode 100644 index 000000000000..0c4800069bad --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/inline.md @@ -0,0 +1,390 @@ +--- +layout: doc-page +title: Inline +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/inline.html +--- + +## Inline Definitions + +`inline` is a new [soft modifier](../soft-modifier.md) that guarantees that a +definition will be inlined at the point of use. Example: + +```scala +object Config: + inline val logging = false + +object Logger: + + private var indent = 0 + + inline def log[T](msg: String, indentMargin: =>Int)(op: => T): T = + if Config.logging then + println(s"${" " * indent}start $msg") + indent += indentMargin + val result = op + indent -= indentMargin + println(s"${" " * indent}$msg = $result") + result + else op +end Logger +``` + +The `Config` object contains a definition of the **inline value** `logging`. +This means that `logging` is treated as a _constant value_, equivalent to its +right-hand side `false`. The right-hand side of such an `inline val` must itself +be a [constant expression](https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#constant-expressions). +Used in this way, `inline` is equivalent to Java and Scala 2's `final`. Note that `final`, meaning +_inlined constant_, is still supported in Scala 3, but will be phased out. + +The `Logger` object contains a definition of the **inline method** `log`. This +method will always be inlined at the point of call. + +In the inlined code, an `if-then-else` with a constant condition will be rewritten +to its `then`- or `else`-part. Consequently, in the `log` method above the +`if Config.logging` with `Config.logging == true` will get rewritten into its +`then`-part. + +Here's an example: + +```scala +var indentSetting = 2 + +def factorial(n: BigInt): BigInt = + log(s"factorial($n)", indentSetting) { + if n == 0 then 1 + else n * factorial(n - 1) + } +``` + +If `Config.logging == false`, this will be rewritten (simplified) to: + +```scala +def factorial(n: BigInt): BigInt = + if n == 0 then 1 + else n * factorial(n - 1) +``` + +As you notice, since neither `msg` or `indentMargin` were used, they do not +appear in the generated code for `factorial`. Also note the body of our `log` +method: the `else-` part reduces to just an `op`. In the generated code we do +not generate any closures because we only refer to a by-name parameter *once*. +Consequently, the code was inlined directly and the call was beta-reduced. + +In the `true` case the code will be rewritten to: + +```scala +def factorial(n: BigInt): BigInt = + val msg = s"factorial($n)" + println(s"${" " * indent}start $msg") + Logger.inline$indent_=(indent.+(indentSetting)) + val result = + if n == 0 then 1 + else n * factorial(n - 1) + Logger.inline$indent_=(indent.-(indentSetting)) + println(s"${" " * indent}$msg = $result") + result +``` + +Note that the by-value parameter `msg` is evaluated only once, per the usual Scala +semantics, by binding the value and reusing the `msg` through the body of +`factorial`. Also, note the special handling of the assignment to the private var +`indent`. It is achieved by generating a setter method `def inline$indent_=` and calling it instead. + +Inline methods always have to be fully applied. For instance, a call to +```scala +Logger.log[String]("some op", indentSetting) +``` +would be ill-formed and the compiler would complain that arguments are missing. +However, it is possible to pass wildcard arguments instead. For instance, +```scala +Logger.log[String]("some op", indentSetting)(_) +``` +would typecheck. + +### Recursive Inline Methods + +Inline methods can be recursive. For instance, when called with a constant +exponent `n`, the following method for `power` will be implemented by +straight inline code without any loop or recursion. + +```scala +inline def power(x: Double, n: Int): Double = + if n == 0 then 1.0 + else if n == 1 then x + else + val y = power(x, n / 2) + if n % 2 == 0 then y * y else y * y * x + +power(expr, 10) +// translates to +// +// val x = expr +// val y1 = x * x // ^2 +// val y2 = y1 * y1 // ^4 +// val y3 = y2 * x // ^5 +// y3 * y3 // ^10 +``` + +Parameters of inline methods can have an `inline` modifier as well. This means +that actual arguments to these parameters will be inlined in the body of the +`inline def`. `inline` parameters have call semantics equivalent to by-name parameters +but allow for duplication of the code in the argument. It is usually useful when constant +values need to be propagated to allow further optimizations/reductions. + +The following example shows the difference in translation between by-value, by-name and `inline` +parameters: + +```scala +inline def funkyAssertEquals(actual: Double, expected: =>Double, inline delta: Double): Unit = + if (actual - expected).abs > delta then + throw new AssertionError(s"difference between ${expected} and ${actual} was larger than ${delta}") + +funkyAssertEquals(computeActual(), computeExpected(), computeDelta()) +// translates to +// +// val actual = computeActual() +// def expected = computeExpected() +// if (actual - expected).abs > computeDelta() then +// throw new AssertionError(s"difference between ${expected} and ${actual} was larger than ${computeDelta()}") +``` + +### Rules for Overriding + +Inline methods can override other non-inline methods. The rules are as follows: + +1. If an inline method `f` implements or overrides another, non-inline method, the inline method can also be invoked at runtime. For instance, consider the scenario: + + ```scala + abstract class A: + def f: Int + def g: Int = f + + class B extends A: + inline def f = 22 + override inline def g = f + 11 + + val b = new B + val a: A = b + // inlined invocatons + assert(b.f == 22) + assert(b.g == 33) + // dynamic invocations + assert(a.f == 22) + assert(a.g == 33) + ``` + + The inlined invocations and the dynamically dispatched invocations give the same results. + +2. Inline methods are effectively final. + +3. Inline methods can also be abstract. An abstract inline method can be implemented only by other inline methods. It cannot be invoked directly: + + ```scala + abstract class A: + inline def f: Int + + object B extends A: + inline def f: Int = 22 + + B.f // OK + val a: A = B + a.f // error: cannot inline f in A. + ``` + +### Relationship to `@inline` + +Scala 2 also defines a `@inline` annotation which is used as a hint for the +backend to inline code. The `inline` modifier is a more powerful option: + +- expansion is guaranteed instead of best effort, +- expansion happens in the frontend instead of in the backend and +- expansion also applies to recursive methods. + + + +### The definition of constant expression + +Right-hand sides of inline values and of arguments for inline parameters must be +constant expressions in the sense defined by the [SLS §6.24](https://www.scala-lang.org/files/archive/spec/2.13/06-expressions.html#constant-expressions), +including _platform-specific_ extensions such as constant folding of pure +numeric computations. + +An inline value must have a literal type such as `1` or `true`. + +```scala +inline val four = 4 +// equivalent to +inline val four: 4 = 4 +``` + +It is also possible to have inline vals of types that do not have a syntax, such as `Short(4)`. + +```scala +trait InlineConstants: + inline val myShort: Short + +object Constants extends InlineConstants: + inline val myShort/*: Short(4)*/ = 4 +``` + +## Transparent Inline Methods + +Inline methods can additionally be declared `transparent`. +This means that the return type of the inline method can be +specialized to a more precise type upon expansion. Example: + +```scala +class A +class B extends A: + def m = true + +transparent inline def choose(b: Boolean): A = + if b then new A else new B + +val obj1 = choose(true) // static type is A +val obj2 = choose(false) // static type is B + +// obj1.m // compile-time error: `m` is not defined on `A` +obj2.m // OK +``` + +Here, the inline method `choose` returns an instance of either of the two types `A` or `B`. +If `choose` had not been declared to be `transparent`, the result +of its expansion would always be of type `A`, even though the computed value might be of the subtype `B`. +The inline method is a "blackbox" in the sense that details of its implementation do not leak out. +But if a `transparent` modifier is given, the expansion is the type of the expanded body. If the argument `b` +is `true`, that type is `A`, otherwise it is `B`. Consequently, calling `m` on `obj2` +type-checks since `obj2` has the same type as the expansion of `choose(false)`, which is `B`. +Transparent inline methods are "whitebox" in the sense that the type +of an application of such a method can be more specialized than its declared +return type, depending on how the method expands. + +In the following example, we see how the return type of `zero` is specialized to +the singleton type `0` permitting the addition to be ascribed with the correct +type `1`. + +```scala +transparent inline def zero: Int = 0 + +val one: 1 = zero + 1 +``` + +### Transparent vs. non-transparent inline + +As we already discussed, transparent inline methods may influence type checking at call site. +Technically this implies that transparent inline methods must be expanded during type checking of the program. +Other inline methods are inlined later after the program is fully typed. + +For example, the following two functions will be typed the same way but will be inlined at different times. + +```scala +inline def f1: T = ... +transparent inline def f2: T = (...): T +``` + +A noteworthy difference is the behavior of `transparent inline given`. +If there is an error reported when inlining that definition, it will be considered as an implicit search mismatch and the search will continue. +A `transparent inline given` can add a type ascription in its RHS (as in `f2` from the previous example) to avoid the precise type but keep the search behavior. +On the other hand, an `inline given` is taken as an implicit and then inlined after typing. +Any error will be emitted as usual. + +## Inline Conditionals + +An if-then-else expression whose condition is a constant expression can be simplified to +the selected branch. Prefixing an if-then-else expression with `inline` enforces that +the condition has to be a constant expression, and thus guarantees that the conditional will always +simplify. + +Example: + +```scala +inline def update(delta: Int) = + inline if delta >= 0 then increaseBy(delta) + else decreaseBy(-delta) +``` + +A call `update(22)` would rewrite to `increaseBy(22)`. But if `update` was called with +a value that was not a compile-time constant, we would get a compile time error like the one +below: + +```scala + | inline if delta >= 0 then ??? + | ^ + | cannot reduce inline if + | its condition + | delta >= 0 + | is not a constant value + | This location is in code that was inlined at ... +``` + +In a transparent inline, an `inline if` will force the inlining of any inline definition in its condition during type checking. + +## Inline Matches + +A `match` expression in the body of an `inline` method definition may be +prefixed by the `inline` modifier. If there is enough type information +at compile time to select a branch, the expression is reduced to that branch and the +type of the expression is the type of the right-hand side of that result. +If not, a compile-time error is raised that reports that the match cannot be reduced. + +The example below defines an inline method with a +single inline match expression that picks a case based on its static type: + +```scala +transparent inline def g(x: Any): Any = + inline x match + case x: String => (x, x) // Tuple2[String, String](x, x) + case x: Double => x + +g(1.0d) // Has type 1.0d which is a subtype of Double +g("test") // Has type (String, String) +``` + +The scrutinee `x` is examined statically and the inline match is reduced +accordingly returning the corresponding value (with the type specialized because `g` is declared `transparent`). +This example performs a simple type test over the scrutinee. +The type can have a richer structure like the simple ADT below. +`toInt` matches the structure of a number in [Church-encoding](https://en.wikipedia.org/wiki/Church_encoding) +and _computes_ the corresponding integer. + +```scala +trait Nat +case object Zero extends Nat +case class Succ[N <: Nat](n: N) extends Nat + +transparent inline def toInt(n: Nat): Int = + inline n match + case Zero => 0 + case Succ(n1) => toInt(n1) + 1 + +inline val natTwo = toInt(Succ(Succ(Zero))) +val intTwo: 2 = natTwo +``` + +`natTwo` is inferred to have the singleton type 2. + +## Reference + +For more information about the semantics of `inline`, see the [Scala 2020: Semantics-preserving inlining for metaprogramming](https://dl.acm.org/doi/10.1145/3426426.3428486) paper. diff --git a/docs/_spec/TODOreference/metaprogramming/macros-spec.md b/docs/_spec/TODOreference/metaprogramming/macros-spec.md new file mode 100644 index 000000000000..aa8f94a9a1f7 --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/macros-spec.md @@ -0,0 +1,254 @@ +--- +layout: doc-page +title: "Macros Spec" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/macros-spec.html +--- + +## Implementation + +### Syntax + +Compared to the [Scala 3 reference grammar](../syntax.md) +there are the following syntax changes: +``` +SimpleExpr ::= ... + | ‘'’ ‘{’ Block ‘}’ + | ‘'’ ‘[’ Type ‘]’ + | ‘$’ ‘{’ Block ‘}’ +SimpleType ::= ... + | ‘$’ ‘{’ Block ‘}’ +``` +In addition, an identifier `$x` starting with a `$` that appears inside +a quoted expression or type is treated as a splice `${x}` and a quoted identifier +`'x` that appears inside a splice is treated as a quote `'{x}` + +### Implementation in `scalac` + +Quotes and splices are primitive forms in the generated abstract syntax trees. +Top-level splices are eliminated during macro expansion while typing. On the +other hand, top-level quotes are eliminated in an expansion phase `PickleQuotes` +phase (after typing and pickling). PCP checking occurs while preparing the RHS +of an inline method for top-level splices and in the `Staging` phase (after +typing and before pickling). + +Macro-expansion works outside-in. If the outermost scope is a splice, +the spliced AST will be evaluated in an interpreter. A call to a +previously compiled method can be implemented as a reflective call to +that method. With the restrictions on splices that are currently in +place that’s all that’s needed. We might allow more interpretation in +splices in the future, which would allow us to loosen the +restriction. Quotes in spliced, interpreted code are kept as they +are, after splices nested in the quotes are expanded. + +If the outermost scope is a quote, we need to generate code that +constructs the quoted tree at run-time. We implement this by +serializing the tree as a TASTy structure, which is stored +in a string literal. At runtime, an unpickler method is called to +deserialize the string into a tree. + +Splices inside quoted code insert the spliced tree as is, after +expanding any quotes in the spliced code recursively. + +## Formalization + +The phase consistency principle can be formalized in a calculus that +extends simply-typed lambda calculus with quotes and splices. + +### Syntax + +The syntax of terms, values, and types is given as follows: +``` +Terms t ::= x variable + (x: T) => t lambda + t t application + 't quote + $t splice + +Values v ::= (x: T) => t lambda + 'u quote + +Simple terms u ::= x | (x: T) => u | u u | 't + +Types T ::= A base type + T -> T function type + expr T quoted +``` +Typing rules are formulated using a stack of environments +`Es`. Individual environments `E` consist as usual of variable +bindings `x: T`. Environments can be combined using the two +combinators `'` and `$`. +``` +Environment E ::= () empty + E, x: T + +Env. stack Es ::= () empty + E simple + Es * Es combined + +Separator * ::= ' + $ +``` +The two environment combinators are both associative with left and +right identity `()`. + +### Operational semantics + +We define a small step reduction relation `-->` with the following rules: +``` + ((x: T) => t) v --> [x := v]t + + ${'u} --> u + + t1 --> t2 + ----------------- + e[t1] --> e[t2] +``` +The first rule is standard call-by-value beta-reduction. The second +rule says that splice and quotes cancel each other out. The third rule +is a context rule; it says that reduction is allowed in the hole `[ ]` +position of an evaluation context. Evaluation contexts `e` and +splice evaluation context `e_s` are defined syntactically as follows: +``` +Eval context e ::= [ ] | e t | v e | 'e_s[${e}] +Splice context e_s ::= [ ] | (x: T) => e_s | e_s t | u e_s +``` + +### Typing rules + +Typing judgments are of the form `Es |- t: T`. There are two +substructural rules which express the fact that quotes and splices +cancel each other out: +``` + Es1 * Es2 |- t: T + --------------------------- + Es1 $ E1 ' E2 * Es2 |- t: T + + + Es1 * Es2 |- t: T + --------------------------- + Es1 ' E1 $ E2 * Es2 |- t: T +``` +The lambda calculus fragment of the rules is standard, except that we +use a stack of environments. The rules only interact with the topmost +environment of the stack. +``` + x: T in E + -------------- + Es * E |- x: T + + + Es * E, x: T1 |- t: T2 + ------------------------------- + Es * E |- (x: T1) => t: T -> T2 + + + Es |- t1: T2 -> T Es |- t2: T2 + --------------------------------- + Es |- t1 t2: T +``` +The rules for quotes and splices map between `expr T` and `T` by trading `'` and `$` between +environments and terms. +``` + Es $ () |- t: expr T + -------------------- + Es |- $t: T + + + Es ' () |- t: T + ---------------- + Es |- 't: expr T +``` +The meta theory of a slightly simplified 2-stage variant of this calculus +is studied [separately](./simple-smp.md). + +## Going Further + +The metaprogramming framework as presented and currently implemented is quite restrictive +in that it does not allow for the inspection of quoted expressions and +types. It’s possible to work around this by providing all necessary +information as normal, unquoted inline parameters. But we would gain +more flexibility by allowing for the inspection of quoted code with +pattern matching. This opens new possibilities. + +For instance, here is a version of `power` that generates the multiplications +directly if the exponent is statically known and falls back to the dynamic +implementation of `power` otherwise. +```scala +import scala.quoted.* + +inline def power(x: Double, n: Int): Double = + ${ powerExpr('x, 'n) } + +private def powerExpr(x: Expr[Double], n: Expr[Int]) + (using Quotes): Expr[Double] = + n.value match + case Some(m) => powerExpr(x, m) + case _ => '{ dynamicPower($x, $n) } + +private def powerExpr(x: Expr[Double], n: Int) + (using Quotes): Expr[Double] = + if n == 0 then '{ 1.0 } + else if n == 1 then x + else if n % 2 == 0 then '{ val y = $x * $x; ${ powerExpr('y, n / 2) } } + else '{ $x * ${ powerExpr(x, n - 1) } } + +private def dynamicPower(x: Double, n: Int): Double = + if n == 0 then 1.0 + else if n % 2 == 0 then dynamicPower(x * x, n / 2) + else x * dynamicPower(x, n - 1) +``` + +In the above, the method `.value` maps a constant expression of the type +`Expr[T]` to its value of the type `T`. + +With the right extractors, the "AsFunction" conversion +that maps expressions over functions to functions over expressions can +be implemented in user code: +```scala +given AsFunction1[T, U]: Conversion[Expr[T => U], Expr[T] => Expr[U]] with + def apply(f: Expr[T => U]): Expr[T] => Expr[U] = + (x: Expr[T]) => f match + case Lambda(g) => g(x) + case _ => '{ ($f)($x) } +``` +This assumes an extractor +```scala +object Lambda: + def unapply[T, U](x: Expr[T => U]): Option[Expr[T] => Expr[U]] +``` +Once we allow inspection of code via extractors, it’s tempting to also +add constructors that create typed trees directly without going +through quotes. Most likely, those constructors would work over `Expr` +types which lack a known type argument. For instance, an `Apply` +constructor could be typed as follows: +```scala +def Apply(fn: Expr[Any], args: List[Expr[Any]]): Expr[Any] +``` +This would allow constructing applications from lists of arguments +without having to match the arguments one-by-one with the +corresponding formal parameter types of the function. We then need "at +the end" a method to convert an `Expr[Any]` to an `Expr[T]` where `T` is +given from the outside. For instance, if `code` yields a `Expr[Any]`, then +`code.atType[T]` yields an `Expr[T]`. The `atType` method has to be +implemented as a primitive; it would check that the computed type +structure of `Expr` is a subtype of the type structure representing +`T`. + +Before going down that route, we should evaluate in detail the tradeoffs it +presents. Constructing trees that are only verified _a posteriori_ +to be type correct loses a lot of guidance for constructing the right +trees. So we should wait with this addition until we have more +use-cases that help us decide whether the loss in type-safety is worth +the gain in flexibility. In this context, it seems that deconstructing types is +less error-prone than deconstructing terms, so one might also +envisage a solution that allows the former but not the latter. + +## Conclusion + +Metaprogramming has a reputation of being difficult and confusing. +But with explicit `Expr/Type` types and quotes and splices it can become +downright pleasant. A simple strategy first defines the underlying quoted or unquoted +values using `Expr` and `Type` and then inserts quotes and splices to make the types +line up. Phase consistency is at the same time a great guideline +where to insert a splice or a quote and a vital sanity check that +the result makes sense. diff --git a/docs/_spec/TODOreference/metaprogramming/macros.md b/docs/_spec/TODOreference/metaprogramming/macros.md new file mode 100644 index 000000000000..8045794d1143 --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/macros.md @@ -0,0 +1,823 @@ +--- +layout: doc-page +title: "Macros" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/macros.html +--- + +> When developing macros enable `-Xcheck-macros` scalac option flag to have extra runtime checks. + +## Macros: Quotes and Splices + +Macros are built on two well-known fundamental operations: quotation and splicing. +Quotation is expressed as `'{...}` for expressions and splicing is expressed as `${ ... }`. +Additionally, within a quote or a splice we can quote or splice identifiers directly (i.e. `'e` and `$e`). +Readers may notice the resemblance of the two aforementioned syntactic +schemes with the familiar string interpolation syntax. + +```scala +println(s"Hello, $name, here is the result of 1 + 1 = ${1 + 1}") +``` + +In string interpolation we _quoted_ a string and then we _spliced_ into it, two others. The first, `name`, is a reference to a value of type [`String`](https://scala-lang.org/api/3.x/scala/Predef$.html#String-0), and the second is an arithmetic expression that will be _evaluated_ followed by the splicing of its string representation. + +Quotes and splices in this section allow us to treat code in a similar way, +effectively supporting macros. The entry point for macros is an inline method +with a top-level splice. We call it a top-level because it is the only occasion +where we encounter a splice outside a quote (consider as a quote the +compilation-unit at the call-site). For example, the code below presents an +`inline` method `assert` which calls at compile-time a method `assertImpl` with +a boolean expression tree as argument. `assertImpl` evaluates the expression and +prints it again in an error message if it evaluates to `false`. + +```scala +import scala.quoted.* + +inline def assert(inline expr: Boolean): Unit = + ${ assertImpl('expr) } + +def assertImpl(expr: Expr[Boolean])(using Quotes) = '{ + if !$expr then + throw AssertionError(s"failed assertion: ${${ showExpr(expr) }}") +} + +def showExpr(expr: Expr[Boolean])(using Quotes): Expr[String] = + '{ [actual implementation later in this document] } +``` + +If `e` is an expression, then `'{e}` represents the typed +abstract syntax tree representing `e`. If `T` is a type, then `Type.of[T]` +represents the type structure representing `T`. The precise +definitions of "typed abstract syntax tree" or "type-structure" do not +matter for now, the terms are used only to give some +intuition. Conversely, `${e}` evaluates the expression `e`, which must +yield a typed abstract syntax tree or type structure, and embeds the +result as an expression (respectively, type) in the enclosing program. + +Quotations can have spliced parts in them; in this case the embedded +splices are evaluated and embedded as part of the formation of the +quotation. + +Quotes and splices can also be applied directly to identifiers. An identifier +`$x` starting with a `$` that appears inside a quoted expression or type is treated as a +splice `${x}`. Analogously, an quoted identifier `'x` that appears inside a splice +is treated as a quote `'{x}`. See the Syntax section below for details. + +Quotes and splices are duals of each other. +For arbitrary expressions `e` we have: + +```scala +${'{e}} = e +'{${e}} = e +``` + +## Types for Quotations + +The type signatures of quotes and splices can be described using +two fundamental types: + +- `Expr[T]`: abstract syntax trees representing expressions of type `T` +- `Type[T]`: non erased representation of type `T`. + +Quoting takes expressions of type `T` to expressions of type `Expr[T]` +and it takes types `T` to expressions of type `Type[T]`. Splicing +takes expressions of type `Expr[T]` to expressions of type `T` and it +takes expressions of type `Type[T]` to types `T`. + +The two types can be defined in package [`scala.quoted`](https://scala-lang.org/api/3.x/scala/quoted.html) as follows: + +```scala +package scala.quoted + +sealed trait Expr[+T] +sealed trait Type[T] +``` + +Both `Expr` and `Type` are abstract and sealed, so all constructors for +these types are provided by the system. One way to construct values of +these types is by quoting, the other is by type-specific lifting +operations that will be discussed later on. + +## The Phase Consistency Principle + +A fundamental *phase consistency principle* (PCP) regulates accesses +to free variables in quoted and spliced code: + +- _For any free variable reference `x`, the number of quoted scopes and the number of spliced scopes between the reference to `x` and the definition of `x` must be equal_. + +Here, `this`-references count as free variables. On the other +hand, we assume that all imports are fully expanded and that `_root_` is +not a free variable. So references to global definitions are +allowed everywhere. + +The phase consistency principle can be motivated as follows: First, +suppose the result of a program `P` is some quoted text `'{ ... x +... }` that refers to a free variable `x` in `P`. This can be +represented only by referring to the original variable `x`. Hence, the +result of the program will need to persist the program state itself as +one of its parts. We don’t want to do this, hence this situation +should be made illegal. Dually, suppose a top-level part of a program +is a spliced text `${ ... x ... }` that refers to a free variable `x` +in `P`. This would mean that we refer during _construction_ of `P` to +a value that is available only during _execution_ of `P`. This is of +course impossible and therefore needs to be ruled out. Now, the +small-step evaluation of a program will reduce quotes and splices in +equal measure using the cancellation rules above. But it will neither +create nor remove quotes or splices individually. So the PCP ensures +that program elaboration will lead to neither of the two unwanted +situations described above. + +In what concerns the range of features it covers, this form of macros introduces +a principled metaprogramming framework that is quite close to the MetaML family of +languages. One difference is that MetaML does not have an equivalent of the PCP - +quoted code in MetaML _can_ access variables in its immediately enclosing +environment, with some restrictions and caveats since such accesses involve +serialization. However, this does not constitute a fundamental gain in +expressiveness. + +## From `Expr`s to Functions and Back + +It is possible to convert any `Expr[T => R]` into `Expr[T] => Expr[R]` and back. +These conversions can be implemented as follows: + +```scala +def to[T: Type, R: Type](f: Expr[T] => Expr[R])(using Quotes): Expr[T => R] = + '{ (x: T) => ${ f('x) } } + +def from[T: Type, R: Type](f: Expr[T => R])(using Quotes): Expr[T] => Expr[R] = + (x: Expr[T]) => '{ $f($x) } +``` + +Note how the fundamental phase consistency principle works in two +different directions here for `f` and `x`. In the method `to`, the reference to `f` is +legal because it is quoted, then spliced, whereas the reference to `x` +is legal because it is spliced, then quoted. + +They can be used as follows: + +```scala +val f1: Expr[Int => String] = + to((x: Expr[Int]) => '{ $x.toString }) // '{ (x: Int) => x.toString } + +val f2: Expr[Int] => Expr[String] = + from('{ (x: Int) => x.toString }) // (x: Expr[Int]) => '{ ((x: Int) => x.toString)($x) } +f2('{2}) // '{ ((x: Int) => x.toString)(2) } +``` + +One limitation of `from` is that it does not β-reduce when a lambda is called immediately, as evidenced in the code `{ ((x: Int) => x.toString)(2) }`. +In some cases we want to remove the lambda from the code, for this we provide the method `Expr.betaReduce` that turns a tree +describing a function into a function mapping trees to trees. + +```scala +object Expr: + ... + def betaReduce[...](...)(...): ... = ... +``` + +The definition of `Expr.betaReduce(f)(x)` is assumed to be functionally the same as +`'{($f)($x)}`, however it should optimize this call by returning the +result of beta-reducing `f(x)` if `f` is a known lambda expression. +`Expr.betaReduce` distributes applications of `Expr` over function arrows: + +```scala +Expr.betaReduce(_): Expr[(T1, ..., Tn) => R] => ((Expr[T1], ..., Expr[Tn]) => Expr[R]) +``` + +## Lifting Types + +Types are not directly affected by the phase consistency principle. +It is possible to use types defined at any level in any other level. +But, if a type is used in a subsequent stage it will need to be lifted to a `Type`. +Indeed, the definition of `to` above uses `T` in the next stage, there is a +quote but no splice between the parameter binding of `T` and its +usage. But the code can be rewritten by adding an explicit binding of a `Type[T]`: + +```scala +def to[T, R](f: Expr[T] => Expr[R])(using t: Type[T])(using Type[R], Quotes): Expr[T => R] = + '{ (x: t.Underlying) => ${ f('x) } } +``` + +In this version of `to`, the type of `x` is now the result of +inserting the type `Type[T]` and selecting its `Underlying`. + +To avoid clutter, the compiler converts any type reference to +a type `T` in subsequent phases to `summon[Type[T]].Underlying`. + +And to avoid duplication it does it once per type, and creates +an alias for that type at the start of the quote. + +For instance, the user-level definition of `to`: + +```scala +def to[T, R](f: Expr[T] => Expr[R])(using t: Type[T], r: Type[R])(using Quotes): Expr[T => R] = + '{ (x: T) => ${ f('x) } } +``` + +would be rewritten to + +```scala +def to[T, R](f: Expr[T] => Expr[R])(using t: Type[T], r: Type[R])(using Quotes): Expr[T => R] = + '{ + type T = t.Underlying + (x: T) => ${ f('x) } + } +``` + +The `summon` query succeeds because there is a given instance of +type `Type[T]` available (namely the given parameter corresponding +to the context bound `: Type`), and the reference to that value is +phase-correct. If that was not the case, the phase inconsistency for +`T` would be reported as an error. + +## Lifting Expressions + +Consider the following implementation of a staged interpreter that implements +a compiler through staging. + +```scala +import scala.quoted.* + +enum Exp: + case Num(n: Int) + case Plus(e1: Exp, e2: Exp) + case Var(x: String) + case Let(x: String, e: Exp, in: Exp) + +import Exp.* +``` + +The interpreted language consists of numbers `Num`, addition `Plus`, and variables +`Var` which are bound by `Let`. Here are two sample expressions in the language: + +```scala +val exp = Plus(Plus(Num(2), Var("x")), Num(4)) +val letExp = Let("x", Num(3), exp) +``` + +Here’s a compiler that maps an expression given in the interpreted +language to quoted Scala code of type `Expr[Int]`. +The compiler takes an environment that maps variable names to Scala `Expr`s. + +```scala +import scala.quoted.* + +def compile(e: Exp, env: Map[String, Expr[Int]])(using Quotes): Expr[Int] = + e match + case Num(n) => + Expr(n) + case Plus(e1, e2) => + '{ ${ compile(e1, env) } + ${ compile(e2, env) } } + case Var(x) => + env(x) + case Let(x, e, body) => + '{ val y = ${ compile(e, env) }; ${ compile(body, env + (x -> 'y)) } } +``` + +Running `compile(letExp, Map())` would yield the following Scala code: + +```scala +'{ val y = 3; (2 + y) + 4 } +``` + +The body of the first clause, `case Num(n) => Expr(n)`, looks suspicious. `n` +is declared as an `Int`, yet it is converted to an `Expr[Int]` with `Expr()`. +Shouldn’t `n` be quoted? In fact this would not +work since replacing `n` by `'n` in the clause would not be phase +correct. + +The `Expr.apply` method is defined in package `quoted`: + +```scala +package quoted + +object Expr: + ... + def apply[T: ToExpr](x: T)(using Quotes): Expr[T] = + summon[ToExpr[T]].toExpr(x) +``` + +This method says that values of types implementing the `ToExpr` type class can be +converted to `Expr` values using `Expr.apply`. + +Scala 3 comes with given instances of `ToExpr` for +several types including `Boolean`, `String`, and all primitive number +types. For example, `Int` values can be converted to `Expr[Int]` +values by wrapping the value in a `Literal` tree node. This makes use +of the underlying tree representation in the compiler for +efficiency. But the `ToExpr` instances are nevertheless not _magic_ +in the sense that they could all be defined in a user program without +knowing anything about the representation of `Expr` trees. For +instance, here is a possible instance of `ToExpr[Boolean]`: + +```scala +given ToExpr[Boolean] with + def toExpr(b: Boolean) = + if b then '{ true } else '{ false } +``` + +Once we can lift bits, we can work our way up. For instance, here is a +possible implementation of `ToExpr[Int]` that does not use the underlying +tree machinery: + +```scala +given ToExpr[Int] with + def toExpr(n: Int) = n match + case Int.MinValue => '{ Int.MinValue } + case _ if n < 0 => '{ - ${ toExpr(-n) } } + case 0 => '{ 0 } + case _ if n % 2 == 0 => '{ ${ toExpr(n / 2) } * 2 } + case _ => '{ ${ toExpr(n / 2) } * 2 + 1 } +``` + +Since `ToExpr` is a type class, its instances can be conditional. For example, +a `List` is liftable if its element type is: + +```scala +given [T: ToExpr : Type]: ToExpr[List[T]] with + def toExpr(xs: List[T]) = xs match + case head :: tail => '{ ${ Expr(head) } :: ${ toExpr(tail) } } + case Nil => '{ Nil: List[T] } +``` + +In the end, `ToExpr` resembles very much a serialization +framework. Like the latter it can be derived systematically for all +collections, case classes and enums. Note also that the synthesis +of _type-tag_ values of type `Type[T]` is essentially the type-level +analogue of lifting. + +Using lifting, we can now give the missing definition of `showExpr` in the introductory example: + +```scala +def showExpr[T](expr: Expr[T])(using Quotes): Expr[String] = + val code: String = expr.show + Expr(code) +``` + +That is, the `showExpr` method converts its `Expr` argument to a string (`code`), and lifts +the result back to an `Expr[String]` using `Expr.apply`. + +## Lifting Types + +The previous section has shown that the metaprogramming framework has +to be able to take a type `T` and convert it to a type tree of type +`Type[T]` that can be reified. This means that all free variables of +the type tree refer to types and values defined in the current stage. + +For a reference to a global class, this is easy: Just issue the fully +qualified name of the class. Members of reifiable types are handled by +just reifying the containing type together with the member name. But +what to do for references to type parameters or local type definitions +that are not defined in the current stage? Here, we cannot construct +the `Type[T]` tree directly, so we need to get it from a recursive +implicit search. For instance, to implement + +```scala +summon[Type[List[T]]] +``` + +where `T` is not defined in the current stage, we construct the type constructor +of `List` applied to the splice of the result of searching for a given instance for `Type[T]`: + +```scala +Type.of[ List[ summon[Type[T]].Underlying ] ] +``` + +This is exactly the algorithm that Scala 2 uses to search for type tags. +In fact Scala 2's type tag feature can be understood as a more ad-hoc version of +`quoted.Type`. As was the case for type tags, the implicit search for a `quoted.Type` +is handled by the compiler, using the algorithm sketched above. + +## Relationship with `inline` + +Seen by itself, principled metaprogramming looks more like a framework for +runtime metaprogramming than one for compile-time metaprogramming with macros. +But combined with Scala 3’s `inline` feature it can be turned into a compile-time +system. The idea is that macro elaboration can be understood as a combination of +a macro library and a quoted program. For instance, here’s the `assert` macro +again together with a program that calls `assert`. + +```scala +object Macros: + + inline def assert(inline expr: Boolean): Unit = + ${ assertImpl('expr) } + + def assertImpl(expr: Expr[Boolean])(using Quotes) = + val failMsg: Expr[String] = Expr("failed assertion: " + expr.show) + '{ if !($expr) then throw new AssertionError($failMsg) } + +@main def program = + val x = 1 + Macros.assert(x != 0) +``` + +Inlining the `assert` function would give the following program: + +```scala +@main def program = + val x = 1 + ${ Macros.assertImpl('{ x != 0}) } +``` + +The example is only phase correct because `Macros` is a global value and +as such not subject to phase consistency checking. Conceptually that’s +a bit unsatisfactory. If the PCP is so fundamental, it should be +applicable without the global value exception. But in the example as +given this does not hold since both `assert` and `program` call +`assertImpl` with a splice but no quote. + +However, one could argue that the example is really missing +an important aspect: The macro library has to be compiled in a phase +prior to the program using it, but in the code above, macro +and program are defined together. A more accurate view of +macros would be to have the user program be in a phase after the macro +definitions, reflecting the fact that macros have to be defined and +compiled before they are used. Hence, conceptually the program part +should be treated by the compiler as if it was quoted: + +```scala +@main def program = '{ + val x = 1 + ${ Macros.assertImpl('{ x != 0 }) } +} +``` + +If `program` is treated as a quoted expression, the call to +`Macro.assertImpl` becomes phase correct even if macro library and +program are conceptualized as local definitions. + +But what about the call from `assert` to `assertImpl`? Here, we need a +tweak of the typing rules. An inline function such as `assert` that +contains a splice operation outside an enclosing quote is called a +_macro_. Macros are supposed to be expanded in a subsequent phase, +i.e. in a quoted context. Therefore, they are also type checked as if +they were in a quoted context. For instance, the definition of +`assert` is typechecked as if it appeared inside quotes. This makes +the call from `assert` to `assertImpl` phase-correct, even if we +assume that both definitions are local. + +The `inline` modifier is used to declare a `val` that is +either a constant or is a parameter that will be a constant when instantiated. This +aspect is also important for macro expansion. + +To get values out of expressions containing constants `Expr` provides the method +`value` (or `valueOrError`). This will convert the `Expr[T]` into a `Some[T]` (or `T`) when the +expression contains value. Otherwise it will return `None` (or emit an error). +To avoid having incidental val bindings generated by the inlining of the `def` +it is recommended to use an inline parameter. To illustrate this, consider an +implementation of the `power` function that makes use of a statically known exponent: + +```scala +inline def power(x: Double, inline n: Int) = ${ powerCode('x, 'n) } + +private def powerCode(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] = + n.value match + case Some(m) => powerCode(x, m) + case None => '{ Math.pow($x, $n.toDouble) } + +private def powerCode(x: Expr[Double], n: Int)(using Quotes): Expr[Double] = + if n == 0 then '{ 1.0 } + else if n == 1 then x + else if n % 2 == 0 then '{ val y = $x * $x; ${ powerCode('y, n / 2) } } + else '{ $x * ${ powerCode(x, n - 1) } } +``` + +## Scope Extrusion + +Quotes and splices are duals as far as the PCP is concerned. But there is an +additional restriction that needs to be imposed on splices to guarantee +soundness: code in splices must be free of side effects. The restriction +prevents code like this: + +```scala +var x: Expr[T] = ... +'{ (y: T) => ${ x = 'y; 1 } } +``` + +This code, if it was accepted, would _extrude_ a reference to a quoted variable +`y` from its scope. This would subsequently allow access to a variable outside the +scope where it is defined, which is likely problematic. The code is clearly +phase consistent, so we cannot use PCP to rule it out. Instead, we postulate a +future effect system that can guarantee that splices are pure. In the absence of +such a system we simply demand that spliced expressions are pure by convention, +and allow for undefined compiler behavior if they are not. This is analogous to +the status of pattern guards in Scala, which are also required, but not +verified, to be pure. + +[Multi-Stage Programming](./staging.md) introduces one additional method where +you can expand code at runtime with a method `run`. There is also a problem with +that invocation of `run` in splices. Consider the following expression: + +```scala +'{ (x: Int) => ${ run('x); 1 } } +``` + +This is again phase correct, but will lead us into trouble. Indeed, evaluating +the splice will reduce the expression `run('x)` to `x`. But then the result + +```scala +'{ (x: Int) => ${ x; 1 } } +``` + +is no longer phase correct. To prevent this soundness hole it seems easiest to +classify `run` as a side-effecting operation. It would thus be prevented from +appearing in splices. In a base language with side effects we would have to do this +anyway: Since `run` runs arbitrary code it can always produce a side effect if +the code it runs produces one. + +## Example Expansion + +Assume we have two methods, one `map` that takes an `Expr[Array[T]]` and a +function `f` and one `sum` that performs a sum by delegating to `map`. + +```scala +object Macros: + + def map[T](arr: Expr[Array[T]], f: Expr[T] => Expr[Unit]) + (using Type[T], Quotes): Expr[Unit] = '{ + var i: Int = 0 + while i < ($arr).length do + val element: T = ($arr)(i) + ${f('element)} + i += 1 + } + + def sum(arr: Expr[Array[Int]])(using Quotes): Expr[Int] = '{ + var sum = 0 + ${ map(arr, x => '{sum += $x}) } + sum + } + + inline def sum_m(arr: Array[Int]): Int = ${sum('arr)} + +end Macros +``` + +A call to `sum_m(Array(1,2,3))` will first inline `sum_m`: + +```scala +val arr: Array[Int] = Array.apply(1, [2,3 : Int]:Int*) +${_root_.Macros.sum('arr)} +``` + +then it will splice `sum`: + +```scala +val arr: Array[Int] = Array.apply(1, [2,3 : Int]:Int*) + +var sum = 0 +${ map('arr, x => '{sum += $x}) } +sum +``` + +then it will inline `map`: + +```scala +val arr: Array[Int] = Array.apply(1, [2,3 : Int]:Int*) + +var sum = 0 +val f = x => '{sum += $x} +${ _root_.Macros.map('arr, 'f)(Type.of[Int])} +sum +``` + +then it will expand and splice inside quotes `map`: + +```scala +val arr: Array[Int] = Array.apply(1, [2,3 : Int]:Int*) + +var sum = 0 +val f = x => '{sum += $x} +var i: Int = 0 +while i < arr.length do + val element: Int = (arr)(i) + sum += element + i += 1 +sum +``` + +Finally cleanups and dead code elimination: + +```scala +val arr: Array[Int] = Array.apply(1, [2,3 : Int]:Int*) +var sum = 0 +var i: Int = 0 +while i < arr.length do + val element: Int = arr(i) + sum += element + i += 1 +sum +``` + +## Find implicits within a macro + +Similarly to the `summonFrom` construct, it is possible to make implicit search available +in a quote context. For this we simply provide `scala.quoted.Expr.summon`: + +```scala +import scala.collection.immutable.{ TreeSet, HashSet } +inline def setFor[T]: Set[T] = ${ setForExpr[T] } + +def setForExpr[T: Type](using Quotes): Expr[Set[T]] = + Expr.summon[Ordering[T]] match + case Some(ord) => '{ new TreeSet[T]()($ord) } + case _ => '{ new HashSet[T] } +``` + +## Relationship with Transparent Inline + +[Inline](./inline.md) documents inlining. The code below introduces a transparent +inline method that can calculate either a value of type `Int` or a value of type +`String`. + +```scala +transparent inline def defaultOf(inline str: String) = + ${ defaultOfImpl('str) } + +def defaultOfImpl(strExpr: Expr[String])(using Quotes): Expr[Any] = + strExpr.valueOrError match + case "int" => '{1} + case "string" => '{"a"} + +// in a separate file +val a: Int = defaultOf("int") +val b: String = defaultOf("string") + +``` + +## Defining a macro and using it in a single project + +It is possible to define macros and use them in the same project as long as the implementation +of the macros does not have run-time dependencies on code in the file where it is used. +It might still have compile-time dependencies on types and quoted code that refers to the use-site file. + +To provide this functionality Scala 3 provides a transparent compilation mode where files that +try to expand a macro but fail because the macro has not been compiled yet are suspended. +If there are any suspended files when the compilation ends, the compiler will automatically restart +compilation of the suspended files using the output of the previous (partial) compilation as macro classpath. +In case all files are suspended due to cyclic dependencies the compilation will fail with an error. + +## Pattern matching on quoted expressions + +It is possible to deconstruct or extract values out of `Expr` using pattern matching. + +`scala.quoted` contains objects that can help extracting values from `Expr`. + +- `scala.quoted.Expr`/`scala.quoted.Exprs`: matches an expression of a value (or list of values) and returns the value (or list of values). +- `scala.quoted.Const`/`scala.quoted.Consts`: Same as `Expr`/`Exprs` but only works on primitive values. +- `scala.quoted.Varargs`: matches an explicit sequence of expressions and returns them. These sequences are useful to get individual `Expr[T]` out of a varargs expression of type `Expr[Seq[T]]`. + +These could be used in the following way to optimize any call to `sum` that has statically known values. + +```scala +inline def sum(inline args: Int*): Int = ${ sumExpr('args) } +private def sumExpr(argsExpr: Expr[Seq[Int]])(using Quotes): Expr[Int] = + argsExpr match + case Varargs(args @ Exprs(argValues)) => + // args is of type Seq[Expr[Int]] + // argValues is of type Seq[Int] + Expr(argValues.sum) // precompute result of sum + case Varargs(argExprs) => // argExprs is of type Seq[Expr[Int]] + val staticSum: Int = argExprs.map(_.value.getOrElse(0)).sum + val dynamicSum: Seq[Expr[Int]] = argExprs.filter(_.value.isEmpty) + dynamicSum.foldLeft(Expr(staticSum))((acc, arg) => '{ $acc + $arg }) + case _ => + '{ $argsExpr.sum } +``` + +### Quoted patterns + +Quoted pattens allow deconstructing complex code that contains a precise structure, types or methods. +Patterns `'{ ... }` can be placed in any location where Scala expects a pattern. + +For example + +```scala +optimize { + sum(sum(1, a, 2), 3, b) +} // should be optimized to 6 + a + b +``` + +```scala +def sum(args: Int*): Int = args.sum +inline def optimize(inline arg: Int): Int = ${ optimizeExpr('arg) } +private def optimizeExpr(body: Expr[Int])(using Quotes): Expr[Int] = + body match + // Match a call to sum without any arguments + case '{ sum() } => Expr(0) + // Match a call to sum with an argument $n of type Int. + // n will be the Expr[Int] representing the argument. + case '{ sum($n) } => n + // Match a call to sum and extracts all its args in an `Expr[Seq[Int]]` + case '{ sum(${Varargs(args)}: _*) } => sumExpr(args) + case body => body + +private def sumExpr(args1: Seq[Expr[Int]])(using Quotes): Expr[Int] = + def flatSumArgs(arg: Expr[Int]): Seq[Expr[Int]] = arg match + case '{ sum(${Varargs(subArgs)}: _*) } => subArgs.flatMap(flatSumArgs) + case arg => Seq(arg) + val args2 = args1.flatMap(flatSumArgs) + val staticSum: Int = args2.map(_.value.getOrElse(0)).sum + val dynamicSum: Seq[Expr[Int]] = args2.filter(_.value.isEmpty) + dynamicSum.foldLeft(Expr(staticSum))((acc, arg) => '{ $acc + $arg }) +``` + +### Recovering precise types using patterns + +Sometimes it is necessary to get a more precise type for an expression. This can be achieved using the following pattern match. + +```scala +def f(expr: Expr[Any])(using Quotes) = expr match + case '{ $x: t } => + // If the pattern match succeeds, then there is + // some type `t` such that + // - `x` is bound to a variable of type `Expr[t]` + // - `t` is bound to a new type `t` and a given + // instance `Type[t]` is provided for it + // That is, we have `x: Expr[t]` and `given Type[t]`, + // for some (unknown) type `t`. +``` + +This might be used to then perform an implicit search as in: + +```scala +extension (inline sc: StringContext) + inline def showMe(inline args: Any*): String = ${ showMeExpr('sc, 'args) } + +private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using Quotes): Expr[String] = + import quotes.reflect.report + argsExpr match + case Varargs(argExprs) => + val argShowedExprs = argExprs.map { + case '{ $arg: tp } => + Expr.summon[Show[tp]] match + case Some(showExpr) => + '{ $showExpr.show($arg) } + case None => + report.error(s"could not find implicit for ${Type.show[Show[tp]]}", arg); '{???} + } + val newArgsExpr = Varargs(argShowedExprs) + '{ $sc.s($newArgsExpr: _*) } + case _ => + // `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."` + report.error(s"Args must be explicit", argsExpr) + '{???} + +trait Show[-T]: + def show(x: T): String + +// in a different file +given Show[Boolean] with + def show(b: Boolean) = "boolean!" + +println(showMe"${true}") +``` + +### Open code patterns + +Quoted pattern matching also provides higher-order patterns to match open terms. If a quoted term contains a definition, +then the rest of the quote can refer to this definition. + +```scala +'{ + val x: Int = 4 + x * x +} +``` + +To match such a term we need to match the definition and the rest of the code, but we need to explicitly state that the rest of the code may refer to this definition. + +```scala +case '{ val y: Int = $x; $body(y): Int } => +``` + +Here `$x` will match any closed expression while `$body(y)` will match an expression that is closed under `y`. Then +the subexpression of type `Expr[Int]` is bound to `body` as an `Expr[Int => Int]`. The extra argument represents the references to `y`. Usually this expression is used in combination with `Expr.betaReduce` to replace the extra argument. + +```scala +inline def eval(inline e: Int): Int = ${ evalExpr('e) } + +private def evalExpr(e: Expr[Int])(using Quotes): Expr[Int] = e match + case '{ val y: Int = $x; $body(y): Int } => + // body: Expr[Int => Int] where the argument represents + // references to y + evalExpr(Expr.betaReduce('{$body(${evalExpr(x)})})) + case '{ ($x: Int) * ($y: Int) } => + (x.value, y.value) match + case (Some(a), Some(b)) => Expr(a * b) + case _ => e + case _ => e +``` + +```scala +eval { // expands to the code: (16: Int) + val x: Int = 4 + x * x +} +``` + +We can also close over several bindings using `$b(a1, a2, ..., an)`. +To match an actual application we can use braces on the function part `${b}(a1, a2, ..., an)`. + +## More details + +[More details](./macros-spec.md) diff --git a/docs/_spec/TODOreference/metaprogramming/metaprogramming.md b/docs/_spec/TODOreference/metaprogramming/metaprogramming.md new file mode 100644 index 000000000000..3bce2d7c922e --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/metaprogramming.md @@ -0,0 +1,47 @@ +--- +layout: index +title: "Metaprogramming" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming.html +--- + +The following pages introduce the redesign of metaprogramming in Scala. They +introduce the following fundamental facilities: + +1. [`inline`](./inline.md) is a new modifier that guarantees that + a definition will be inlined at the point of use. The primary motivation + behind inline is to reduce the overhead behind function calls and access to + values. The expansion will be performed by the Scala compiler during the + `Typer` compiler phase. As opposed to inlining in some other ecosystems, + inlining in Scala is not merely a request to the compiler but is a + _command_. The reason is that inlining in Scala can drive other compile-time + operations, like inline pattern matching (enabling type-level + programming), macros (enabling compile-time, generative, metaprogramming) and + runtime code generation (multi-stage programming). + +2. [Compile-time ops](./compiletime-ops.md) are helper definitions in the + standard library that provide support for compile-time operations over values and types. + +3. [Macros](./macros.md) are built on two well-known fundamental + operations: quotation and splicing. Quotation converts program code to + data, specifically, a (tree-like) representation of this code. It is + expressed as `'{...}` for expressions and as `'[...]` for types. Splicing, + expressed as `${ ... }`, goes the other way: it converts a program's representation + to program code. Together with `inline`, these two abstractions allow + to construct program code programmatically. + +4. [Runtime Staging](./staging.md) Where macros construct code at _compile-time_, + staging lets programs construct new code at _runtime_. That way, + code generation can depend not only on static data but also on data available at runtime. This splits the evaluation of the program in two or more phases or ... + stages. Consequently, this method of generative programming is called "Multi-Stage Programming". Staging is built on the same foundations as macros. It uses + quotes and splices, but leaves out `inline`. + +5. [Reflection](./reflection.md) Quotations are a "black-box" + representation of code. They can be parameterized and composed using + splices, but their structure cannot be analyzed from the outside. TASTy + reflection gives a way to analyze code structure by partly revealing the representation type of a piece of code in a standard API. The representation + type is a form of typed abstract syntax tree, which gives rise to the `TASTy` + moniker. + +6. [TASTy Inspection](./tasty-inspect.md) Typed abstract syntax trees are serialized + in a custom compressed binary format stored in `.tasty` files. TASTy inspection allows + to load these files and analyze their content's tree structure. diff --git a/docs/_spec/TODOreference/metaprogramming/reflection.md b/docs/_spec/TODOreference/metaprogramming/reflection.md new file mode 100644 index 000000000000..b2d492657a4e --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/reflection.md @@ -0,0 +1,131 @@ +--- +layout: doc-page +title: "Reflection" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/reflection.html +--- + +Reflection enables inspection and construction of Typed Abstract Syntax Trees +(Typed-AST). It may be used on quoted expressions (`quoted.Expr`) and quoted +types (`quoted.Type`) from [Macros](./macros.md) or on full TASTy files. + +If you are writing macros, please first read [Macros](./macros.md). +You may find all you need without using quote reflection. + +## API: From quotes and splices to TASTy reflect trees and back + +With `quoted.Expr` and `quoted.Type` we can compute code but also analyze code +by inspecting the ASTs. [Macros](./macros.md) provide the guarantee that the +generation of code will be type-correct. Using quote reflection will break these +guarantees and may fail at macro expansion time, hence additional explicit +checks must be done. + +To provide reflection capabilities in macros we need to add an implicit parameter +of type `scala.quoted.Quotes` and import `quotes.reflect.*` from it in the scope +where it is used. + +```scala +import scala.quoted.* + +inline def natConst(inline x: Int): Int = ${natConstImpl('{x})} + +def natConstImpl(x: Expr[Int])(using Quotes): Expr[Int] = + import quotes.reflect.* + ... +``` + +### Extractors + +`import quotes.reflect.*` will provide all extractors and methods on `quotes.reflect.Tree`s. +For example the `Literal(_)` extractor used below. + +```scala +def natConstImpl(x: Expr[Int])(using Quotes): Expr[Int] = + import quotes.reflect.* + val tree: Term = x.asTerm + tree match + case Inlined(_, _, Literal(IntConstant(n))) => + if n <= 0 then + report.error("Parameter must be natural number") + '{0} + else + tree.asExprOf[Int] + case _ => + report.error("Parameter must be a known constant") + '{0} +``` + +We can easily know which extractors are needed using `Printer.TreeStructure.show`, +which returns the string representation the structure of the tree. Other printers +can also be found in the `Printer` module. + +```scala +tree.show(using Printer.TreeStructure) +// or +Printer.TreeStructure.show(tree) +``` + +The methods `quotes.reflect.Term.{asExpr, asExprOf}` provide a way to go back to +a `quoted.Expr`. Note that `asExpr` returns a `Expr[Any]`. On the other hand +`asExprOf[T]` returns a `Expr[T]`, if the type does not conform to it an exception +will be thrown at runtime. + +### Positions + +The `Position` in the context provides an `ofMacroExpansion` value. It corresponds +to the expansion site for macros. The macro authors can obtain various information +about that expansion site. The example below shows how we can obtain position +information such as the start line, the end line or even the source code at the +expansion point. + +```scala +def macroImpl()(quotes: Quotes): Expr[Unit] = + import quotes.reflect.* + val pos = Position.ofMacroExpansion + + val path = pos.sourceFile.jpath.toString + val start = pos.start + val end = pos.end + val startLine = pos.startLine + val endLine = pos.endLine + val startColumn = pos.startColumn + val endColumn = pos.endColumn + val sourceCode = pos.sourceCode + ... +``` + +### Tree Utilities + +`quotes.reflect` contains three facilities for tree traversal and +transformation. + +`TreeAccumulator` ties the knot of a traversal. By calling `foldOver(x, tree)(owner)` +we can dive into the `tree` node and start accumulating values of type `X` (e.g., +of type `List[Symbol]` if we want to collect symbols). The code below, for +example, collects the `val` definitions in the tree. + +```scala +def collectPatternVariables(tree: Tree)(using ctx: Context): List[Symbol] = + val acc = new TreeAccumulator[List[Symbol]]: + def foldTree(syms: List[Symbol], tree: Tree)(owner: Symbol): List[Symbol] = tree match + case ValDef(_, _, rhs) => + val newSyms = tree.symbol :: syms + foldTree(newSyms, body)(tree.symbol) + case _ => + foldOverTree(syms, tree)(owner) + acc(Nil, tree) +``` + +A `TreeTraverser` extends a `TreeAccumulator` and performs the same traversal +but without returning any value. Finally, a `TreeMap` performs a transformation. + +#### ValDef.let + +`quotes.reflect.ValDef` also offers a method `let` that allows us to bind the `rhs` (right-hand side) to a `val` and use it in `body`. +Additionally, `lets` binds the given `terms` to names and allows to use them in the `body`. +Their type definitions are shown below: + +```scala +def let(rhs: Term)(body: Ident => Term): Term = ... + +def lets(terms: List[Term])(body: List[Term] => Term): Term = ... +``` diff --git a/docs/_spec/TODOreference/metaprogramming/simple-smp.md b/docs/_spec/TODOreference/metaprogramming/simple-smp.md new file mode 100644 index 000000000000..2ba0155ad329 --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/simple-smp.md @@ -0,0 +1,232 @@ +--- +layout: doc-page +title: "The Meta-theory of Symmetric Metaprogramming" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/simple-smp.html +--- + +This note presents a simplified variant of +[principled metaprogramming](./macros.md) +and sketches its soundness proof. The variant treats only dialogues +between two stages. A program can have quotes which can contain +splices (which can contain quotes, which can contain splices, and so +on). Or the program could start with a splice with embedded +quotes. The essential restriction is that (1) a term can contain top-level +quotes or top-level splices, but not both, and (2) quotes cannot appear +directly inside quotes and splices cannot appear directly inside +splices. In other words, the universe is restricted to two phases +only. + +Under this restriction we can simplify the typing rules so that there are +always exactly two environments instead of having a stack of environments. +The variant presented here differs from the full calculus also in that we +replace evaluation contexts with contextual typing rules. While this +is more verbose, it makes it easier to set up the meta theory. + +## Syntax +``` +Terms t ::= x variable + (x: T) => t lambda + t t application + ’t quote + ~t splice + +Simple terms u ::= x | (x: T) => u | u u + +Values v ::= (x: T) => t lambda + ’u quoted value + +Types T ::= A base type + T -> T function type + ’T quoted type +``` +## Operational semantics + +### Evaluation +``` + ((x: T) => t) v --> [x := v]t + + t1 --> t2 + --------------- + t1 t --> t2 t + + t1 --> t2 + --------------- + v t1 --> v t2 + + t1 ==> t2 + ------------- + ’t1 --> ’t2 +``` + +### Splicing +``` + ~’u ==> u + + t1 ==> t2 + ------------------------------- + (x: T) => t1 ==> (x: T) => t2 + + t1 ==> t2 + --------------- + t1 t ==> t2 t + + t1 ==> t2 + --------------- + u t1 ==> u t2 + + t1 --> t2 + ------------- + ~t1 ==> ~t2 + +``` +## Typing Rules + +Typing judgments are of the form `E1 * E2 |- t: T` where `E1, E2` are environments and +`*` is one of `~` and `’`. +``` + x: T in E2 + --------------- + E1 * E2 |- x: T + + + E1 * E2, x: T1 |- t: T2 + -------------------------------- + E1 * E2 |- (x: T1) => t: T -> T2 + + + E1 * E2 |- t1: T2 -> T E1 * E2 |- t2: T2 + ------------------------------------------- + E1 * E2 |- t1 t2: T + + + E2 ’ E1 |- t: T + ----------------- + E1 ~ E2 |- ’t: ’T + + + E2 ~ E1 |- t: ’T + ---------------- + E1 ’ E2 |- ~t: T +``` + +(Curiously, this looks a bit like a Christmas tree). + +## Soundness + +The meta-theory typically requires mutual inductions over two judgments. + +### Progress Theorem + + 1. If `E1 ~ |- t: T` then either `t = v` for some value `v` or `t --> t2` for some term `t2`. + 2. If ` ’ E2 |- t: T` then either `t = u` for some simple term `u` or `t ==> t2` for some term `t2`. + +Proof by structural induction over terms. + +To prove (1): + + - the cases for variables, lambdas and applications are as in [STLC](https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus). + - If `t = ’t2`, then by inversion we have ` ’ E1 |- t2: T2` for some type `T2`. + By the second [induction hypothesis](https://en.wikipedia.org/wiki/Mathematical_induction) (I.H.), we have one of: + - `t2 = u`, hence `’t2` is a value, + - `t2 ==> t3`, hence `’t2 --> ’t3`. + - The case `t = ~t2` is not typable. + +To prove (2): + + - If `t = x` then `t` is a simple term. + - If `t = (x: T) => t2`, then either `t2` is a simple term, in which case `t` is as well. + Or by the second I.H. `t2 ==> t3`, in which case `t ==> (x: T) => t3`. + - If `t = t1 t2` then one of three cases applies: + + - `t1` and `t2` are a simple term, then `t` is as well a simple term. + - `t1` is not a simple term. Then by the second I.H., `t1 ==> t12`, hence `t ==> t12 t2`. + - `t1` is a simple term but `t2` is not. Then by the second I.H. `t2 ==> t22`, hence `t ==> t1 t22`. + + - The case `t = ’t2` is not typable. + - If `t = ~t2` then by inversion we have `E2 ~ |- t2: ’T2`, for some type `T2`. + By the first I.H., we have one of + + - `t2 = v`. Since `t2: ’T2`, we must have `v = ’u`, for some simple term `u`, hence `t = ~’u`. + By quote-splice reduction, `t ==> u`. + - `t2 --> t3`. Then by the context rule for `’t`, `t ==> ’t3`. + + +### Substitution Lemma + + 1. If `E1 ~ E2 |- s: S` and `E1 ~ E2, x: S |- t: T` then `E1 ~ E2 |- [x := s]t: T`. + 2. If `E1 ~ E2 |- s: S` and `E2, x: S ’ E1 |- t: T` then `E2 ’ E1 |- [x := s]t: T`. + +The proofs are by induction on typing derivations for `t`, analogous +to the proof for STL (with (2) a bit simpler than (1) since we do not +need to swap lambda bindings with the bound variable `x`). The +arguments that link the two hypotheses are as follows. + +To prove (1), let `t = ’t1`. Then `T = ’T1` for some type `T1` and the last typing rule is +``` + E2, x: S ’ E1 |- t1: T1 + ------------------------- + E1 ~ E2, x: S |- ’t1: ’T1 +``` +By the second I.H. `E2 ’ E1 |- [x := s]t1: T1`. By typing, `E1 ~ E2 |- ’[x := s]t1: ’T1`. +Since `[x := s]t = [x := s](’t1) = ’[x := s]t1` we get `[x := s]t: ’T1`. + +To prove (2), let `t = ~t1`. Then the last typing rule is +``` + E1 ~ E2, x: S |- t1: ’T + ----------------------- + E2, x: S ’ E1 |- ~t1: T +``` +By the first I.H., `E1 ~ E2 |- [x := s]t1: ’T`. By typing, `E2 ’ E1 |- ~[x := s]t1: T`. +Since `[x := s]t = [x := s](~t1) = ~[x := s]t1` we get `[x := s]t: T`. + + +### Preservation Theorem + + 1. If `E1 ~ E2 |- t1: T` and `t1 --> t2` then `E1 ~ E2 |- t2: T`. + 2. If `E1 ’ E2 |- t1: T` and `t1 ==> t2` then `E1 ’ E2 |- t2: T`. + +The proof is by structural induction on evaluation derivations. The proof of (1) is analogous +to the proof for STL, using the substitution lemma for the beta reduction case, with the addition of reduction of quoted terms, which goes as follows: + + - Assume the last rule was + ``` + t1 ==> t2 + ------------- + ’t1 --> ’t2 + ``` + By inversion of typing rules, we must have `T = ’T1` for some type `T1` such that `t1: T1`. + By the second I.H., `t2: T1`, hence `’t2: `T1`. + + +To prove (2): + + - Assume the last rule was `~’u ==> u`. The typing proof of `~’u` must have the form + + ``` + E1 ’ E2 |- u: T + ----------------- + E1 ~ E2 |- ’u: ’T + ----------------- + E1 ’ E2 |- ~’u: T + ``` + Hence, `E1 ’ E2 |- u: T`. + + - Assume the last rule was + ``` + t1 ==> t2 + ------------------------------- + (x: S) => t1 ==> (x: T) => t2 + ``` + By typing inversion, `E1 ' E2, x: S |- t1: T1` for some type `T1` such that `T = S -> T1`. + By the I.H, `t2: T1`. By the typing rule for lambdas the result follows. + + - The context rules for applications are equally straightforward. + + - Assume the last rule was + ``` + t1 ==> t2 + ------------- + ~t1 ==> ~t2 + ``` + By inversion of typing rules, we must have `t1: ’T`. + By the first I.H., `t2: ’T`, hence `~t2: T`. diff --git a/docs/_spec/TODOreference/metaprogramming/staging.md b/docs/_spec/TODOreference/metaprogramming/staging.md new file mode 100644 index 000000000000..e74d491402b5 --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/staging.md @@ -0,0 +1,121 @@ +--- +layout: doc-page +title: "Runtime Multi-Stage Programming" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/staging.html +--- + +The framework expresses at the same time compile-time metaprogramming and +multi-stage programming. We can think of compile-time metaprogramming as a +two stage compilation process: one that we write the code in top-level splices, +that will be used for code generation (macros) and one that will perform all +necessary evaluations at compile-time and an object program that we will run +as usual. What if we could synthesize code at run-time and offer one extra stage +to the programmer? Then we can have a value of type `Expr[T]` at run-time that we +can essentially treat as a typed-syntax tree that we can either _show_ as a +string (pretty-print) or compile and run. If the number of quotes exceeds the +number of splices by more than one (effectively handling at run-time values of type +`Expr[Expr[T]]`, `Expr[Expr[Expr[T]]]`, ...) then we talk about Multi-Stage +Programming. + +The motivation behind this _paradigm_ is to let runtime information affect or +guide code-generation. + +Intuition: The phase in which code is run is determined by the difference +between the number of splice scopes and quote scopes in which it is embedded. + + - If there are more splices than quotes, the code is run at compile-time i.e. + as a macro. In the general case, this means running an interpreter that + evaluates the code, which is represented as a typed abstract syntax tree. The + interpreter can fall back to reflective calls when evaluating an application + of a previously compiled method. If the splice excess is more than one, it + would mean that a macro’s implementation code (as opposed to the code it + expands to) invokes other macros. If macros are realized by interpretation, + this would lead to towers of interpreters, where the first interpreter would + itself interpret an interpreter code that possibly interprets another + interpreter and so on. + + - If the number of splices equals the number of quotes, the code is compiled + and run as usual. + + - If the number of quotes exceeds the number of splices, the code is staged. + That is, it produces a typed abstract syntax tree or type structure at + run-time. A quote excess of more than one corresponds to multi-staged + programming. + +Providing an interpreter for the full language is quite difficult, and it is +even more difficult to make that interpreter run efficiently. So we currently +impose the following restrictions on the use of splices. + + 1. A top-level splice must appear in an inline method (turning that method + into a macro) + + 2. The splice must call a previously compiled + method passing quoted arguments, constant arguments or inline arguments. + + 3. Splices inside splices (but no intervening quotes) are not allowed. + + +## API + +The framework as discussed so far allows code to be staged, i.e. be prepared +to be executed at a later stage. To run that code, there is another method +in class `Expr` called `run`. Note that `$` and `run` both map from `Expr[T]` +to `T` but only `$` is subject to the [PCP](./macros.md#the-phase-consistency-principle), whereas `run` is just a normal method. +`scala.quoted.staging.run` provides a `Quotes` that can be used to show the expression in its scope. +On the other hand `scala.quoted.staging.withQuotes` provides a `Quotes` without evaluating the expression. + +```scala +package scala.quoted.staging + +def run[T](expr: Quotes ?=> Expr[T])(using Compiler): T = ... + +def withQuotes[T](thunk: Quotes ?=> T)(using Compiler): T = ... +``` + +## Create a new Scala 3 project with staging enabled + +```shell +sbt new scala/scala3-staging.g8 +``` + +From [`scala/scala3-staging.g8`](https://github.com/scala/scala3-staging.g8). + +It will create a project with the necessary dependencies and some examples. + +In case you prefer to create the project on your own, make sure to define the following dependency in your [`build.sbt` build definition](https://www.scala-sbt.org/1.x/docs/Basic-Def.html) + +```scala +libraryDependencies += "org.scala-lang" %% "scala3-staging" % scalaVersion.value +``` + +and in case you use `scalac`/`scala` directly, then use the `-with-compiler` flag for both: + +```shell +scalac -with-compiler -d out Test.scala +scala -with-compiler -classpath out Test +``` + +## Example + +Now take exactly the same example as in [Macros](./macros.md). Assume that we +do not want to pass an array statically but generate code at run-time and pass +the value, also at run-time. Note, how we make a future-stage function of type +`Expr[Array[Int] => Int]` in line 6 below. Using `staging.run { ... }` we can evaluate an +expression at runtime. Within the scope of `staging.run` we can also invoke `show` on an expression +to get a source-like representation of the expression. + +```scala +import scala.quoted.* + +// make available the necessary compiler for runtime code generation +given staging.Compiler = staging.Compiler.make(getClass.getClassLoader) + +val f: Array[Int] => Int = staging.run { + val stagedSum: Expr[Array[Int] => Int] = + '{ (arr: Array[Int]) => ${sum('arr)}} + println(stagedSum.show) // Prints "(arr: Array[Int]) => { var sum = 0; ... }" + stagedSum +} + +f.apply(Array(1, 2, 3)) // Returns 6 +``` diff --git a/docs/_spec/TODOreference/metaprogramming/tasty-inspect.md b/docs/_spec/TODOreference/metaprogramming/tasty-inspect.md new file mode 100644 index 000000000000..e643775243e0 --- /dev/null +++ b/docs/_spec/TODOreference/metaprogramming/tasty-inspect.md @@ -0,0 +1,57 @@ +--- +layout: doc-page +title: "TASTy Inspection" +nightlyOf: https://docs.scala-lang.org/scala3/reference/metaprogramming/tasty-inspect.html +--- + +```scala +libraryDependencies += "org.scala-lang" %% "scala3-tasty-inspector" % scalaVersion.value +``` + +TASTy files contain the full typed tree of a class including source positions +and documentation. This is ideal for tools that analyze or extract semantic +information from the code. To avoid the hassle of working directly with the TASTy +file we provide the `Inspector` which loads the contents and exposes it +through the TASTy reflect API. + +## Inspecting TASTy files + +To inspect the trees of a TASTy file a consumer can be defined in the following way. + +```scala +import scala.quoted.* +import scala.tasty.inspector.* + +class MyInspector extends Inspector: + def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit = + import quotes.reflect.* + for tasty <- tastys do + val tree = tasty.ast + // Do something with the tree +``` + +Then the consumer can be instantiated with the following code to get the tree of the `foo/Bar.tasty` file. + +```scala +object Test: + def main(args: Array[String]): Unit = + val tastyFiles = List("foo/Bar.tasty") + TastyInspector.inspectTastyFiles(tastyFiles)(new MyInspector) +``` + +Note that if we need to run the main (in the example below defined in an object called `Test`) after compilation we need to make the compiler available to the runtime: + +```shell +scalac -d out Test.scala +scala -with-compiler -classpath out Test +``` + +## Template project + +Using sbt version `1.1.5+`, do: + +```shell +sbt new scala/scala3-tasty-inspector.g8 +``` + +in the folder where you want to clone the template. diff --git a/docs/_spec/TODOreference/new-types/dependent-function-types-spec.md b/docs/_spec/TODOreference/new-types/dependent-function-types-spec.md new file mode 100644 index 000000000000..f3237ddf7b9a --- /dev/null +++ b/docs/_spec/TODOreference/new-types/dependent-function-types-spec.md @@ -0,0 +1,125 @@ +--- +layout: doc-page +title: "Dependent Function Types - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/dependent-function-types-spec.html +--- + +Initial implementation in [PR #3464](https://github.com/lampepfl/dotty/pull/3464). + +## Syntax + +``` +FunArgTypes ::= InfixType + | ‘(’ [ FunArgType {',' FunArgType } ] ‘)’ + | ‘(’ TypedFunParam {',' TypedFunParam } ‘)’ +TypedFunParam ::= id ‘:’ Type +``` + +Dependent function types associate to the right, e.g. +`(s: S) => (t: T) => U` is the same as `(s: S) => ((t: T) => U)`. + +## Implementation + +Dependent function types are shorthands for class types that define `apply` +methods with a dependent result type. Dependent function types desugar to +refinement types of `scala.FunctionN`. A dependent function type +`(x1: K1, ..., xN: KN) => R` of arity `N` translates to: + +```scala +FunctionN[K1, ..., Kn, R']: + def apply(x1: K1, ..., xN: KN): R +``` + +where the result type parameter `R'` is the least upper approximation of the +precise result type `R` without any reference to value parameters `x1, ..., xN`. + +The syntax and semantics of anonymous dependent functions is identical to the +one of regular functions. Eta expansion is naturally generalized to produce +dependent function types for methods with dependent result types. + +Dependent functions can be implicit, and generalize to arity `N > 22` in the +same way that other functions do, see +[the corresponding documentation](../dropped-features/limit22.md). + +## Examples + +The example below defines a trait `C` and the two dependent function types +`DF` and `IDF` and prints the results of the respective function applications: + +[depfuntype.scala]: https://github.com/lampepfl/dotty/blob/main/tests/pos/depfuntype.scala + +```scala +trait C { type M; val m: M } + +type DF = (x: C) => x.M + +type IDF = (x: C) ?=> x.M + +@main def test = + val c = new C { type M = Int; val m = 3 } + + val depfun: DF = (x: C) => x.m + val t = depfun(c) + println(s"t=$t") // prints "t=3" + + val idepfun: IDF = summon[C].m + val u = idepfun(using c) + println(s"u=$u") // prints "u=3" + +``` + +In the following example the depend type `f.Eff` refers to the effect type `CanThrow`: + +[eff-dependent.scala]: https://github.com/lampepfl/dotty/blob/main/tests/run/eff-dependent.scala + +```scala +trait Effect + +// Type X => Y +abstract class Fun[-X, +Y]: + type Eff <: Effect + def apply(x: X): Eff ?=> Y + +class CanThrow extends Effect +class CanIO extends Effect + +given ct: CanThrow = new CanThrow +given ci: CanIO = new CanIO + +class I2S extends Fun[Int, String]: + type Eff = CanThrow + def apply(x: Int) = x.toString + +class S2I extends Fun[String, Int]: + type Eff = CanIO + def apply(x: String) = x.length + +// def map(f: A => B)(xs: List[A]): List[B] +def map[A, B](f: Fun[A, B])(xs: List[A]): f.Eff ?=> List[B] = + xs.map(f.apply) + +// def mapFn[A, B]: (A => B) -> List[A] -> List[B] +def mapFn[A, B]: (f: Fun[A, B]) => List[A] => f.Eff ?=> List[B] = + f => xs => map(f)(xs) + +// def compose(f: A => B)(g: B => C)(x: A): C +def compose[A, B, C](f: Fun[A, B])(g: Fun[B, C])(x: A): + f.Eff ?=> g.Eff ?=> C = + g(f(x)) + +// def composeFn: (A => B) -> (B => C) -> A -> C +def composeFn[A, B, C]: + (f: Fun[A, B]) => (g: Fun[B, C]) => A => f.Eff ?=> g.Eff ?=> C = + f => g => x => compose(f)(g)(x) + +@main def test = + val i2s = new I2S + val s2i = new S2I + + assert(mapFn(i2s)(List(1, 2, 3)).mkString == "123") + assert(composeFn(i2s)(s2i)(22) == 2) +``` + +## Type Checking + +After desugaring no additional typing rules are required for dependent function types. diff --git a/docs/_spec/TODOreference/new-types/dependent-function-types.md b/docs/_spec/TODOreference/new-types/dependent-function-types.md new file mode 100644 index 000000000000..adbee1d8b3c8 --- /dev/null +++ b/docs/_spec/TODOreference/new-types/dependent-function-types.md @@ -0,0 +1,49 @@ +--- +layout: doc-page +title: "Dependent Function Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/dependent-function-types.html +--- + +A dependent function type is a function type whose result depends +on the function's parameters. For example: + +```scala +trait Entry { type Key; val key: Key } + +def extractKey(e: Entry): e.Key = e.key // a dependent method + +val extractor: (e: Entry) => e.Key = extractKey // a dependent function value +// ^^^^^^^^^^^^^^^^^^^ +// a dependent function type +``` + +Scala already has _dependent methods_, i.e. methods where the result +type refers to some of the parameters of the method. Method +`extractKey` is an example. Its result type, `e.Key` refers to its +parameter `e` (we also say, `e.Key` _depends_ on `e`). But so far it +was not possible to turn such methods into function values, so that +they can be passed as parameters to other functions, or returned as +results. Dependent methods could not be turned into functions simply +because there was no type that could describe them. + +In Scala 3 this is now possible. The type of the `extractor` value above is + +```scala +(e: Entry) => e.Key +``` + +This type describes function values that take any argument `e` of type +`Entry` and return a result of type `e.Key`. + +Recall that a normal function type `A => B` is represented as an +instance of the [`Function1` trait](https://scala-lang.org/api/3.x/scala/Function1.html) +(i.e. `Function1[A, B]`) and analogously for functions with more parameters. Dependent functions +are also represented as instances of these traits, but they get an additional +refinement. In fact, the dependent function type above is just syntactic sugar for + +```scala +Function1[Entry, Entry#Key]: + def apply(e: Entry): e.Key +``` + +[More details](./dependent-function-types-spec.md) diff --git a/docs/_spec/TODOreference/new-types/intersection-types-spec.md b/docs/_spec/TODOreference/new-types/intersection-types-spec.md new file mode 100644 index 000000000000..346c57c004f0 --- /dev/null +++ b/docs/_spec/TODOreference/new-types/intersection-types-spec.md @@ -0,0 +1,108 @@ +--- +layout: doc-page +title: "Intersection Types - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/intersection-types-spec.html +--- + +## Syntax + +Syntactically, the type `S & T` is an infix type, where the infix operator is `&`. +The operator `&` is a normal identifier +with the usual precedence and subject to usual resolving rules. +Unless shadowed by another definition, it resolves to the type `scala.&`, +which acts as a type alias to an internal representation of intersection types. + +``` +Type ::= ...| InfixType +InfixType ::= RefinedType {id [nl] RefinedType} +``` + +## Subtyping Rules + +``` +T <: A T <: B +---------------- + T <: A & B + + A <: T +---------------- + A & B <: T + + B <: T +---------------- + A & B <: T +``` + +From the rules above, we can show that `&` is _commutative_: `A & B <: B & A` for any type `A` and `B`. + +``` + B <: B A <: A +---------- ----------- +A & B <: B A & B <: A +--------------------------- + A & B <: B & A +``` + +In another word, `A & B` is the same type as `B & A`, in the sense that the two types +have the same values and are subtypes of each other. + +If `C` is a type constructor, then `C[A] & C[B]` can be simplified using the following three rules: + +- If `C` is covariant, `C[A] & C[B] ~> C[A & B]` +- If `C` is contravariant, `C[A] & C[B] ~> C[A | B]` +- If `C` is non-variant, emit a compile error + +When `C` is covariant, `C[A & B] <: C[A] & C[B]` can be derived: + +``` + A <: A B <: B + ---------- --------- + A & B <: A A & B <: B +--------------- ----------------- +C[A & B] <: C[A] C[A & B] <: C[B] +------------------------------------------ + C[A & B] <: C[A] & C[B] +``` + +When `C` is contravariant, `C[A | B] <: C[A] & C[B]` can be derived: + +``` + A <: A B <: B + ---------- --------- + A <: A | B B <: A | B +------------------- ---------------- +C[A | B] <: C[A] C[A | B] <: C[B] +-------------------------------------------------- + C[A | B] <: C[A] & C[B] +``` + +## Erasure + +The erased type for `S & T` is the erased _glb_ (greatest lower bound) of the +erased type of `S` and `T`. The rules for erasure of intersection types are given +below in pseudocode: + +``` +|S & T| = glb(|S|, |T|) + +glb(JArray(A), JArray(B)) = JArray(glb(A, B)) +glb(JArray(T), _) = JArray(T) +glb(_, JArray(T)) = JArray(T) +glb(A, B) = A if A extends B +glb(A, B) = B if B extends A +glb(A, _) = A if A is not a trait +glb(_, B) = B if B is not a trait +glb(A, _) = A // use first +``` + +In the above, `|T|` means the erased type of `T`, `JArray` refers to +the type of Java Array. + +See also: [`TypeErasure#erasedGlb`](https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/core/TypeErasure.scala#L289). + +## Relationship with Compound Type (`with`) + +Intersection types `A & B` replace compound types `A with B` in Scala 2. For the +moment, the syntax `A with B` is still allowed and interpreted as `A & B`, but +its usage as a type (as opposed to in a `new` or `extends` clause) will be +deprecated and removed in the future. diff --git a/docs/_spec/TODOreference/new-types/intersection-types.md b/docs/_spec/TODOreference/new-types/intersection-types.md new file mode 100644 index 000000000000..a4eedeb000f6 --- /dev/null +++ b/docs/_spec/TODOreference/new-types/intersection-types.md @@ -0,0 +1,68 @@ +--- +layout: doc-page +title: "Intersection Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/intersection-types.html +--- + +Used on types, the `&` operator creates an intersection type. + +## Type Checking + +The type `S & T` represents values that are of the type `S` and `T` at the same time. + +```scala +trait Resettable: + def reset(): Unit + +trait Growable[T]: + def add(t: T): Unit + +def f(x: Resettable & Growable[String]) = + x.reset() + x.add("first") +``` + +The parameter `x` is required to be _both_ a `Resettable` and a +`Growable[String]`. + +The members of an intersection type `A & B` are all the members of `A` and all +the members of `B`. For instance `Resettable & Growable[String]` +has member methods `reset` and `add`. + +`&` is _commutative_: `A & B` is the same type as `B & A`. + +If a member appears in both `A` and `B`, its type in `A & B` is the intersection +of its type in `A` and its type in `B`. For instance, assume the definitions: + +```scala +trait A: + def children: List[A] + +trait B: + def children: List[B] + +val x: A & B = new C +val ys: List[A & B] = x.children +``` + +The type of `children` in `A & B` is the intersection of `children`'s +type in `A` and its type in `B`, which is `List[A] & List[B]`. This +can be further simplified to `List[A & B]` because `List` is +covariant. + +One might wonder how the compiler could come up with a definition for +`children` of type `List[A & B]` since what is given are `children` +definitions of type `List[A]` and `List[B]`. The answer is the compiler does not +need to. `A & B` is just a type that represents a set of requirements for +values of the type. At the point where a value is _constructed_, one +must make sure that all inherited members are correctly defined. +So if one defines a class `C` that inherits `A` and `B`, one needs +to give at that point a definition of a `children` method with the required type. + +```scala +class C extends A, B: + def children: List[A & B] = ??? +``` + + +[More details](./intersection-types-spec.md) diff --git a/docs/_spec/TODOreference/new-types/match-types.md b/docs/_spec/TODOreference/new-types/match-types.md new file mode 100644 index 000000000000..d646dd11880b --- /dev/null +++ b/docs/_spec/TODOreference/new-types/match-types.md @@ -0,0 +1,247 @@ +--- +layout: doc-page +title: "Match Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/match-types.html +--- + +A match type reduces to one of its right-hand sides, depending on the type of +its scrutinee. For example: + +```scala +type Elem[X] = X match + case String => Char + case Array[t] => t + case Iterable[t] => t +``` + +This defines a type that reduces as follows: + +```scala +Elem[String] =:= Char +Elem[Array[Int]] =:= Int +Elem[List[Float]] =:= Float +Elem[Nil.type] =:= Nothing +``` + +Here `=:=` is understood to mean that left and right-hand sides are mutually +subtypes of each other. + +In general, a match type is of the form + +```scala +S match { P1 => T1 ... Pn => Tn } +``` + +where `S`, `T1`, ..., `Tn` are types and `P1`, ..., `Pn` are type patterns. Type +variables in patterns start with a lower case letter, as usual. + +Match types can form part of recursive type definitions. Example: + +```scala +type LeafElem[X] = X match + case String => Char + case Array[t] => LeafElem[t] + case Iterable[t] => LeafElem[t] + case AnyVal => X +``` + +Recursive match type definitions can also be given an upper bound, like this: + +```scala +type Concat[Xs <: Tuple, +Ys <: Tuple] <: Tuple = Xs match + case EmptyTuple => Ys + case x *: xs => x *: Concat[xs, Ys] +``` + +In this definition, every instance of `Concat[A, B]`, whether reducible or not, +is known to be a subtype of `Tuple`. This is necessary to make the recursive +invocation `x *: Concat[xs, Ys]` type check, since `*:` demands a `Tuple` as its +right operand. + +## Dependent Typing + +Match types can be used to define dependently typed methods. For instance, here +is the value level counterpart to the `LeafElem` type defined above (note the +use of the match type as the return type): + +```scala +def leafElem[X](x: X): LeafElem[X] = x match + case x: String => x.charAt(0) + case x: Array[t] => leafElem(x(0)) + case x: Iterable[t] => leafElem(x.head) + case x: AnyVal => x +``` + +This special mode of typing for match expressions is only used when the +following conditions are met: + +1. The match expression patterns do not have guards +2. The match expression scrutinee's type is a subtype of the match type + scrutinee's type +3. The match expression and the match type have the same number of cases +4. The match expression patterns are all [Typed Patterns](https://scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#typed-patterns), + and these types are `=:=` to their corresponding type patterns in the match + type + +So you know, while the case body will be expected to have the type on the right-hand +side of the corresponding match type case, that doesn't imply the match type argument +is constrained. Using the example, the last case body must conform to X, but that +doesn't constrain X to be AnyVal, and therefore a LeafElem[X] inside the body wouldn't +reduce; it would remain stuck, and as such just an abstract type. + +## Representation of Match Types + +The internal representation of a match type +``` +S match { P1 => T1 ... Pn => Tn } +``` +is `Match(S, C1, ..., Cn) <: B` where each case `Ci` is of the form +``` +[Xs] =>> P => T +``` + +Here, `[Xs]` is a type parameter clause of the variables bound in pattern `Pi`. +If there are no bound type variables in a case, the type parameter clause is +omitted and only the function type `P => T` is kept. So each case is either a +unary function type or a type lambda over a unary function type. + +`B` is the declared upper bound of the match type, or `Any` if no such bound is +given. We will leave it out in places where it does not matter for the +discussion. The scrutinee, bound, and pattern types must all be first-order +types. + +## Match Type Reduction + +Match type reduction follows the semantics of match expressions, that is, a +match type of the form `S match { P1 => T1 ... Pn => Tn }` reduces to `Ti` if +and only if `s: S match { _: P1 => T1 ... _: Pn => Tn }` evaluates to a value of +type `Ti` for all `s: S`. + +The compiler implements the following reduction algorithm: + +- If the scrutinee type `S` is an empty set of values (such as `Nothing` or + `String & Int`), do not reduce. +- Sequentially consider each pattern `Pi` + - If `S <: Pi` reduce to `Ti`. + - Otherwise, try constructing a proof that `S` and `Pi` are disjoint, or, in + other words, that no value `s` of type `S` is also of type `Pi`. + - If such proof is found, proceed to the next case (`Pi+1`), otherwise, do + not reduce. + +Disjointness proofs rely on the following properties of Scala types: + +1. Single inheritance of classes +2. Final classes cannot be extended +3. Constant types with distinct values are nonintersecting +4. Singleton paths to distinct values are nonintersecting, such as `object` definitions or singleton enum cases. + +Type parameters in patterns are minimally instantiated when computing `S <: Pi`. +An instantiation `Is` is _minimal_ for `Xs` if all type variables in `Xs` that +appear covariantly and nonvariantly in `Is` are as small as possible and all +type variables in `Xs` that appear contravariantly in `Is` are as large as +possible. Here, "small" and "large" are understood with respect to `<:`. + +For simplicity, we have omitted constraint handling so far. The full formulation +of subtyping tests describes them as a function from a constraint and a pair of +types to either _success_ and a new constraint or _failure_. In the context of +reduction, the subtyping test `S <: [Xs := Is] P` is understood to leave the +bounds of all variables in the input constraint unchanged, i.e. existing +variables in the constraint cannot be instantiated by matching the scrutinee +against the patterns. + +## Subtyping Rules for Match Types + +The following rules apply to match types. For simplicity, we omit environments +and constraints. + +1. The first rule is a structural comparison between two match types: + + ``` + S match { P1 => T1 ... Pm => Tm } <: T match { Q1 => U1 ... Qn => Un } + ``` + + if + + ``` + S =:= T, m >= n, Pi =:= Qi and Ti <: Ui for i in 1..n + ``` + + I.e. scrutinees and patterns must be equal and the corresponding bodies must + be subtypes. No case re-ordering is allowed, but the subtype can have more + cases than the supertype. + +2. The second rule states that a match type and its redux are mutual subtypes. + + ``` + S match { P1 => T1 ... Pn => Tn } <: U + U <: S match { P1 => T1 ... Pn => Tn } + ``` + + if + + `S match { P1 => T1 ... Pn => Tn }` reduces to `U` + +3. The third rule states that a match type conforms to its upper bound: + + ``` + (S match { P1 => T1 ... Pn => Tn } <: B) <: B + ``` + +## Termination + +Match type definitions can be recursive, which means that it's possible to run +into an infinite loop while reducing match types. + +Since reduction is linked to subtyping, we already have a cycle detection +mechanism in place. As a result, the following will already give a reasonable +error message: + +```scala +type L[X] = X match + case Int => L[X] + +def g[X]: L[X] = ??? +``` + +```scala + | val x: Int = g[Int] + | ^ + |Recursion limit exceeded. + |Maybe there is an illegal cyclic reference? + |If that's not the case, you could also try to + |increase the stacksize using the -Xss JVM option. + |A recurring operation is (inner to outer): + | + | subtype LazyRef(Test.L[Int]) <:< Int +``` + +Internally, the Scala compiler detects these cycles by turning selected stack overflows into +type errors. If there is a stack overflow during subtyping, the exception will +be caught and turned into a compile-time error that indicates a trace of the +subtype tests that caused the overflow without showing a full stack trace. + + +## Match Types Variance + +All type positions in a match type (scrutinee, patterns, bodies) are considered invariant. + +## Related Work + +Match types have similarities with +[closed type families](https://wiki.haskell.org/GHC/Type_families) in Haskell. +Some differences are: + +- Subtyping instead of type equalities. +- Match type reduction does not tighten the underlying constraint, whereas type + family reduction does unify. This difference in approach mirrors the + difference between local type inference in Scala and global type inference in + Haskell. + +Match types are also similar to Typescript's +[conditional types](https://github.com/Microsoft/TypeScript/pull/21316). The +main differences here are: + + - Conditional types only reduce if both the scrutinee and pattern are ground, + whereas match types also work for type parameters and abstract types. + - Match types support direct recursion. + - Conditional types distribute through union types. diff --git a/docs/_spec/TODOreference/new-types/new-types.md b/docs/_spec/TODOreference/new-types/new-types.md new file mode 100644 index 000000000000..84c157495d6f --- /dev/null +++ b/docs/_spec/TODOreference/new-types/new-types.md @@ -0,0 +1,7 @@ +--- +layout: index +title: "New Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/index.html +--- + +This chapter documents the new types introduced in Scala 3. diff --git a/docs/_spec/TODOreference/new-types/polymorphic-function-types.md b/docs/_spec/TODOreference/new-types/polymorphic-function-types.md new file mode 100644 index 000000000000..1754bf844831 --- /dev/null +++ b/docs/_spec/TODOreference/new-types/polymorphic-function-types.md @@ -0,0 +1,94 @@ +--- +layout: doc-page +title: "Polymorphic Function Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/polymorphic-function-types.html +--- + +A polymorphic function type is a function type which accepts type parameters. +For example: + +```scala +// A polymorphic method: +def foo[A](xs: List[A]): List[A] = xs.reverse + +// A polymorphic function value: +val bar: [A] => List[A] => List[A] +// ^^^^^^^^^^^^^^^^^^^^^^^^^ +// a polymorphic function type + = [A] => (xs: List[A]) => foo[A](xs) +``` + +Scala already has _polymorphic methods_, i.e. methods which accepts type parameters. +Method `foo` above is an example, accepting a type parameter `A`. +So far, it +was not possible to turn such methods into polymorphic function values like `bar` above, +which can be passed as parameters to other functions, or returned as results. + +In Scala 3 this is now possible. The type of the `bar` value above is + +```scala +[A] => List[A] => List[A] +``` + +This type describes function values which take a type `A` as a parameter, +then take a list of type `List[A]`, and return a list of the same type `List[A]`. + +[More details](https://github.com/lampepfl/dotty/pull/4672) + + +## Example Usage + +Polymorphic function type are particularly useful +when callers of a method are required to provide a +function which has to be polymorphic, +meaning that it should accept arbitrary types as part of its inputs. + +For instance, consider the situation where we have +a data type to represent the expressions of a simple language +(consisting only of variables and function applications) +in a strongly-typed way: + +```scala +enum Expr[A]: + case Var(name: String) + case Apply[A, B](fun: Expr[B => A], arg: Expr[B]) extends Expr[A] +``` + +We would like to provide a way for users to map a function +over all immediate subexpressions of a given `Expr`. +This requires the given function to be polymorphic, +since each subexpression may have a different type. +Here is how to implement this using polymorphic function types: + +```scala +def mapSubexpressions[A](e: Expr[A])(f: [B] => Expr[B] => Expr[B]): Expr[A] = + e match + case Apply(fun, arg) => Apply(f(fun), f(arg)) + case Var(n) => Var(n) +``` + +And here is how to use this function to _wrap_ each subexpression +in a given expression with a call to some `wrap` function, +defined as a variable: + +```scala +val e0 = Apply(Var("f"), Var("a")) +val e1 = mapSubexpressions(e0)( + [B] => (se: Expr[B]) => Apply(Var[B => B]("wrap"), se)) +println(e1) // Apply(Apply(Var(wrap),Var(f)),Apply(Var(wrap),Var(a))) +``` + +## Relationship With Type Lambdas + +Polymorphic function types are not to be confused with +[_type lambdas_](type-lambdas.md). +While the former describes the _type_ of a polymorphic _value_, +the latter is an actual function value _at the type level_. + +A good way of understanding the difference is to notice that +**_type lambdas are applied in types, +whereas polymorphic functions are applied in terms_**: +One would call the function `bar` above +by passing it a type argument `bar[Int]` _within a method body_. +On the other hand, given a type lambda such as `type F = [A] =>> List[A]`, +one would call `F` _within a type expression_, as in `type Bar = F[Int]`. diff --git a/docs/_spec/TODOreference/new-types/type-lambdas-spec.md b/docs/_spec/TODOreference/new-types/type-lambdas-spec.md new file mode 100644 index 000000000000..52f88dab4217 --- /dev/null +++ b/docs/_spec/TODOreference/new-types/type-lambdas-spec.md @@ -0,0 +1,116 @@ +--- +layout: doc-page +title: "Type Lambdas - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/type-lambdas-spec.html +--- + +## Syntax + +``` +Type ::= ... | TypeParamClause ‘=>>’ Type +TypeParamClause ::= ‘[’ TypeParam {‘,’ TypeParam} ‘]’ +TypeParam ::= {Annotation} (id [HkTypeParamClause] | ‘_’) TypeBounds +TypeBounds ::= [‘>:’ Type] [‘<:’ Type] +``` + +## Type Checking + +A type lambda such as `[X] =>> F[X]` defines a function from types to types. The parameter(s) may carry bounds. +If a parameter is bounded, as in `[X >: L <: U] =>> F[X]` it is checked that arguments to the parameters conform to the bounds `L` and `U`. +Only the upper bound `U` can be F-bounded, i.e. `X` can appear in it. + +## Subtyping Rules + +Assume two type lambdas +```scala +type TL1 = [X >: L1 <: U1] =>> R1 +type TL2 = [X >: L2 <: U2] =>> R2 +``` +Then `TL1 <: TL2`, if + + - the type interval `L2..U2` is contained in the type interval `L1..U1` (i.e. +`L1 <: L2` and `U2 <: U1`), + - `R1 <: R2` + +Here we have relied on [alpha renaming](https://en.wikipedia.org/wiki/Lambda_calculus#%CE%B1-conversion) to match the two bound types `X`. + +A partially applied type constructor such as `List` is assumed to be equivalent to +its eta expansion. I.e, `List = [X] =>> List[X]`. This allows type constructors to be compared with type lambdas. + +## Relationship with Parameterized Type Definitions + +A parameterized type definition +```scala +type T[X] = R +``` +is regarded as a shorthand for an unparameterized definition with a type lambda as right-hand side: +```scala +type T = [X] =>> R +``` +If the type definition carries `+` or `-` variance annotations, +it is checked that the variance annotations are satisfied by the type lambda. +For instance, +```scala +type F2[A, +B] = A => B +``` +expands to +```scala +type F2 = [A, B] =>> A => B +``` +and at the same time it is checked that the parameter `B` appears covariantly in `A => B`. + +A parameterized abstract type +```scala +type T[X] >: L <: U +``` +is regarded as shorthand for an unparameterized abstract type with type lambdas as bounds. +```scala +type T >: ([X] =>> L) <: ([X] =>> U) +``` +However, if `L` is `Nothing` it is not parameterized, since `Nothing` is treated as a bottom type for all kinds. For instance, +```scala +type T[X] <: X => X +``` +is expanded to +```scala +type T >: Nothing <: ([X] =>> X => X) +``` +instead of +```scala +type T >: ([X] =>> Nothing) <: ([X] =>> X => X) +``` + +The same expansions apply to type parameters. For instance, +```scala +[F[X] <: Coll[X]] +``` +is treated as a shorthand for +```scala +[F >: Nothing <: [X] =>> Coll[X]] +``` +Abstract types and opaque type aliases remember the variances they were created with. So the type +```scala +type F2[-A, +B] +``` +is known to be contravariant in `A` and covariant in `B` and can be instantiated only +with types that satisfy these constraints. Likewise +```scala +opaque type O[X] = List[X] +``` +`O` is known to be invariant (and not covariant, as its right-hand side would suggest). On the other hand, a transparent alias +```scala +type O2[X] = List[X] +``` +would be treated as covariant, `X` is used covariantly on its right-hand side. + +**Note**: The decision to treat `Nothing` as universal bottom type is provisional, and might be changed after further discussion. + +**Note**: Scala 2 and 3 differ in that Scala 2 also treats `Any` as universal top-type. This is not done in Scala 3. See also the discussion on [kind polymorphism](../other-new-features/kind-polymorphism.md) + +## Curried Type Parameters + +The body of a type lambda can again be a type lambda. Example: +```scala +type TL = [X] =>> [Y] =>> (X, Y) +``` +Currently, no special provision is made to infer type arguments to such curried type lambdas. This is left for future work. diff --git a/docs/_spec/TODOreference/new-types/type-lambdas.md b/docs/_spec/TODOreference/new-types/type-lambdas.md new file mode 100644 index 000000000000..ba88e28f5d56 --- /dev/null +++ b/docs/_spec/TODOreference/new-types/type-lambdas.md @@ -0,0 +1,17 @@ +--- +layout: doc-page +title: "Type Lambdas" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/type-lambdas.html +--- + +A _type lambda_ lets one express a higher-kinded type directly, without +a type definition. + +```scala +[X, Y] =>> Map[Y, X] +``` + +For instance, the type above defines a binary type constructor, which maps arguments `X` and `Y` to `Map[Y, X]`. +Type parameters of type lambdas can have bounds, but they cannot carry `+` or `-` variance annotations. + +[More details](./type-lambdas-spec.md) diff --git a/docs/_spec/TODOreference/new-types/union-types-spec.md b/docs/_spec/TODOreference/new-types/union-types-spec.md new file mode 100644 index 000000000000..d250d3f11713 --- /dev/null +++ b/docs/_spec/TODOreference/new-types/union-types-spec.md @@ -0,0 +1,172 @@ +--- +layout: doc-page +title: "Union Types - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/union-types-spec.html +--- + +## Syntax + +Syntactically, unions follow the same rules as intersections, but have a lower precedence, see +[Intersection Types - More Details](./intersection-types-spec.md). + +### Interaction with pattern matching syntax +`|` is also used in pattern matching to separate pattern alternatives and has +lower precedence than `:` as used in typed patterns, this means that: + +```scala +case _: A | B => ... +``` + +is still equivalent to: + +```scala +case (_: A) | B => ... +``` + +and not to: + +```scala +case _: (A | B) => ... +``` + +## Subtyping Rules + +- `A` is always a subtype of `A | B` for all `A`, `B`. +- If `A <: C` and `B <: C` then `A | B <: C` +- Like `&`, `|` is commutative and associative: + + ```scala + A | B =:= B | A + A | (B | C) =:= (A | B) | C + ``` + +- `&` is distributive over `|`: + + ```scala + A & (B | C) =:= A & B | A & C + ``` + +From these rules it follows that the _least upper bound_ (LUB) of a set of types +is the union of these types. This replaces the +[definition of least upper bound in the Scala 2 specification](https://www.scala-lang.org/files/archive/spec/2.13/03-types.html#least-upper-bounds-and-greatest-lower-bounds). + +## Motivation + +The primary reason for introducing union types in Scala is that they allow us to +guarantee that for every set of types, we can always form a finite LUB. This is +both useful in practice (infinite LUBs in Scala 2 were approximated in an ad-hoc +way, resulting in imprecise and sometimes incredibly long types) and in theory +(the type system of Scala 3 is based on the +[DOT calculus](https://infoscience.epfl.ch/record/227176/files/soundness_oopsla16.pdf), +which has union types). + +Additionally, union types are a useful construct when trying to give types to existing +dynamically typed APIs, this is why they're [an integral part of TypeScript](https://www.typescriptlang.org/docs/handbook/advanced-types.html#union-types) +and have even been [partially implemented in Scala.js](https://github.com/scala-js/scala-js/blob/master/library/src/main/scala/scala/scalajs/js/Union.scala). + +## Join of a union type + +In some situation described below, a union type might need to be widened to +a non-union type, for this purpose we define the _join_ of a union type `T1 | +... | Tn` as the smallest intersection type of base class instances of +`T1`,...,`Tn`. Note that union types might still appear as type arguments in the +resulting type, this guarantees that the join is always finite. + +### Example + +Given + +```scala +trait C[+T] +trait D +trait E +class A extends C[A] with D +class B extends C[B] with D with E +``` + +The join of `A | B` is `C[A | B] & D` + +## Type inference + +When inferring the result type of a definition (`val`, `var`, or `def`) and the +type we are about to infer is a union type, then we replace it by its join. +Similarly, when instantiating a type argument, if the corresponding type +parameter is not upper-bounded by a union type and the type we are about to +instantiate is a union type, we replace it by its join. This mirrors the +treatment of singleton types which are also widened to their underlying type +unless explicitly specified. The motivation is the same: inferring types +which are "too precise" can lead to unintuitive typechecking issues later on. + +**Note:** Since this behavior limits the usability of union types, it might +be changed in the future. For example by not widening unions that have been +explicitly written down by the user and not inferred, or by not widening a type +argument when the corresponding type parameter is covariant. + +See [PR #2330](https://github.com/lampepfl/dotty/pull/2330) and +[Issue #4867](https://github.com/lampepfl/dotty/issues/4867) for further discussions. + +### Example + +```scala +import scala.collection.mutable.ListBuffer +val x = ListBuffer(Right("foo"), Left(0)) +val y: ListBuffer[Either[Int, String]] = x +``` + +This code typechecks because the inferred type argument to `ListBuffer` in the +right-hand side of `x` was `Left[Int, Nothing] | Right[Nothing, String]` which +was widened to `Either[Int, String]`. If the compiler hadn't done this widening, +the last line wouldn't typecheck because `ListBuffer` is invariant in its +argument. + + +## Members + +The members of a union type are the members of its join. + +### Example + +The following code does not typecheck, because method `hello` is not a member of +`AnyRef` which is the join of `A | B`. + +```scala +trait A { def hello: String } +trait B { def hello: String } + +def test(x: A | B) = x.hello // error: value `hello` is not a member of A | B +``` + +On the other hand, the following would be allowed + +```scala +trait C { def hello: String } +trait A extends C with D +trait B extends C with E + +def test(x: A | B) = x.hello // ok as `hello` is a member of the join of A | B which is C +``` + +## Exhaustivity checking + +If the selector of a pattern match is a union type, the match is considered +exhaustive if all parts of the union are covered. + +## Erasure + +The erased type for `A | B` is the _erased least upper bound_ of the erased +types of `A` and `B`. Quoting from the documentation of `TypeErasure#erasedLub`, +the erased LUB is computed as follows: + +- if both argument are arrays of objects, an array of the erased LUB of the element types +- if both arguments are arrays of same primitives, an array of this primitive +- if one argument is array of primitives and the other is array of objects, + [`Object`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html) +- if one argument is an array, [`Object`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html) +- otherwise a common superclass or trait S of the argument classes, with the + following two properties: + * S is minimal: no other common superclass or trait derives from S + * S is last : in the linearization of the first argument type `|A|` + there are no minimal common superclasses or traits that + come after S. + The reason to pick last is that we prefer classes over traits that way, + which leads to more predictable bytecode and (?) faster dynamic dispatch. diff --git a/docs/_spec/TODOreference/new-types/union-types.md b/docs/_spec/TODOreference/new-types/union-types.md new file mode 100644 index 000000000000..ebc4565e36fb --- /dev/null +++ b/docs/_spec/TODOreference/new-types/union-types.md @@ -0,0 +1,46 @@ +--- +layout: doc-page +title: "Union Types" +nightlyOf: https://docs.scala-lang.org/scala3/reference/new-types/union-types.html +--- + +A union type `A | B` has as values all values of type `A` and also all values of type `B`. + + +```scala +case class UserName(name: String) +case class Password(hash: Hash) + +def help(id: UserName | Password) = + val user = id match + case UserName(name) => lookupName(name) + case Password(hash) => lookupPassword(hash) + ... +``` + +Union types are duals of intersection types. `|` is _commutative_: +`A | B` is the same type as `B | A`. + +The compiler will assign a union type to an expression only if such a +type is explicitly given. This can be seen in the following [REPL](https://docs.scala-lang.org/overviews/repl/overview.html) transcript: + +```scala +scala> val password = Password(123) +val password: Password = Password(123) + +scala> val name = UserName("Eve") +val name: UserName = UserName(Eve) + +scala> if true then name else password +val res2: Object = UserName(Eve) + +scala> val either: Password | UserName = if true then name else password +val either: Password | UserName = UserName(Eve) +``` + +The type of `res2` is `Object & Product`, which is a supertype of +`UserName` and `Password`, but not the least supertype `Password | +UserName`. If we want the least supertype, we have to give it +explicitly, as is done for the type of `either`. + +[More details](./union-types-spec.md) diff --git a/docs/_spec/TODOreference/other-new-features/control-syntax.md b/docs/_spec/TODOreference/other-new-features/control-syntax.md new file mode 100644 index 000000000000..92204690f0b7 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/control-syntax.md @@ -0,0 +1,47 @@ +--- +layout: doc-page +title: New Control Syntax +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/control-syntax.html +--- + +Scala 3 has a new "quiet" syntax for control expressions that does not rely on +enclosing the condition in parentheses, and also allows to drop parentheses or braces +around the generators of a `for`-expression. Examples: +```scala +if x < 0 then + "negative" +else if x == 0 then + "zero" +else + "positive" + +if x < 0 then -x else x + +while x >= 0 do x = f(x) + +for x <- xs if x > 0 +yield x * x + +for + x <- xs + y <- ys +do + println(x + y) + +try body +catch case ex: IOException => handle +``` + +The rules in detail are: + + - The condition of an `if`-expression can be written without enclosing parentheses if it is followed by a `then`. + - The condition of a `while`-loop can be written without enclosing parentheses if it is followed by a `do`. + - The enumerators of a `for`-expression can be written without enclosing parentheses or braces if they are followed by a `yield` or `do`. + - A `do` in a `for`-expression expresses a `for`-loop. + - A `catch` can be followed by a single case on the same line. + If there are multiple cases, these have to appear within braces (just like in Scala 2) + or an indented block. +## Rewrites + +The Scala 3 compiler can rewrite source code from old syntax to new syntax and back. +When invoked with options `-rewrite -new-syntax` it will rewrite from old to new syntax, dropping parentheses and braces in conditions and enumerators. When invoked with options `-rewrite -old-syntax` it will rewrite in the reverse direction, inserting parentheses and braces as needed. diff --git a/docs/_spec/TODOreference/other-new-features/creator-applications.md b/docs/_spec/TODOreference/other-new-features/creator-applications.md new file mode 100644 index 000000000000..81f09d897955 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/creator-applications.md @@ -0,0 +1,57 @@ +--- +layout: doc-page +title: "Universal Apply Methods" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/creator-applications.html +--- + +Scala case classes generate apply methods, so that values of case classes can be created using simple +function application, without needing to write `new`. + +Scala 3 generalizes this scheme to all concrete classes. Example: + +```scala +class StringBuilder(s: String): + def this() = this("") + +StringBuilder("abc") // old: new StringBuilder("abc") +StringBuilder() // old: new StringBuilder() +``` + +This works since a companion object with two `apply` methods +is generated together with the class. The object looks like this: + +```scala +object StringBuilder: + inline def apply(s: String): StringBuilder = new StringBuilder(s) + inline def apply(): StringBuilder = new StringBuilder() +``` + +The synthetic object `StringBuilder` and its `apply` methods are called _constructor proxies_. +Constructor proxies are generated even for Java classes and classes coming from Scala 2. +The precise rules are as follows: + + 1. A constructor proxy companion object `object C` is created for a concrete class `C`, + provided the class does not have already a companion, and there is also no other value + or method named `C` defined or inherited in the scope where `C` is defined. + + 2. Constructor proxy `apply` methods are generated for a concrete class provided + + - the class has a companion object (which might have been generated in step 1), and + - that companion object does not already define a member named `apply`. + + Each generated `apply` method forwards to one constructor of the class. It has the + same type and value parameters as the constructor. + +Constructor proxy companions cannot be used as values by themselves. A proxy companion object must +be selected with `apply` (or be applied to arguments, in which case the `apply` is implicitly +inserted). + +Constructor proxies are also not allowed to shadow normal definitions. That is, +if an identifier resolves to a constructor proxy, and the same identifier is also +defined or imported in some other scope, an ambiguity is reported. + +## Motivation + +Leaving out `new` hides an implementation detail and makes code more pleasant to read. Even though +it requires a new rule, it will likely increase the perceived regularity of the language, since case +classes already provide function call creation syntax (and are often defined for this reason alone). diff --git a/docs/_spec/TODOreference/other-new-features/experimental-defs.md b/docs/_spec/TODOreference/other-new-features/experimental-defs.md new file mode 100644 index 000000000000..225b61161652 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/experimental-defs.md @@ -0,0 +1,318 @@ +--- +layout: doc-page +title: "Experimental Definitions" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/experimental-defs.html +--- + +The [`@experimental`](https://scala-lang.org/api/3.x/scala/annotation/experimental.html) annotation allows the definition of an API that is not guaranteed backward binary or source compatibility. +This annotation can be placed on term or type definitions. + +## References to experimental definitions + +Experimental definitions can only be referenced in an experimental scope. Experimental scopes are defined as follows: + +1. The RHS of an experimental `def`, `val`, `var`, `given` or `type` is an experimental scope. Examples: + +
      + Example 1 + + ```scala + import scala.annotation.experimental + + @experimental + def x = () + + def d1 = x // error: value x is marked @experimental and therefore ... + @experimental def d2 = x + + val v1 = x // error: value x is marked @experimental and therefore ... + @experimental val v2 = x + + var vr1 = x // error: value x is marked @experimental and therefore ... + @experimental var vr2 = x + + lazy val lv1 = x // error: value x is marked @experimental and therefore ... + @experimental lazy val lv2 = x + ``` +
      + +
      + Example 2 + + ```scala + import scala.annotation.experimental + + @experimental + val x = () + + @experimental + def f() = () + + @experimental + object X: + def fx() = 1 + + def test1: Unit = + f() // error: def f is marked @experimental and therefore ... + x // error: value x is marked @experimental and therefore ... + X.fx() // error: object X is marked @experimental and therefore ... + import X.fx + fx() // error: object X is marked @experimental and therefore ... + + @experimental + def test2: Unit = + // references to f, x and X are ok because `test2` is experimental + f() + x + X.fx() + import X.fx + fx() + ``` +
      + +
      + Example 3 + + ```scala + import scala.annotation.experimental + + @experimental type E + + type A = E // error type E is marked @experimental and therefore ... + @experimental type B = E + ``` +
      + +
      + Example 4 + + ```scala + import scala.annotation.experimental + + @experimental class A + @experimental type X + @experimental type Y = Int + @experimental opaque type Z = Int + + def test: Unit = + new A // error: class A is marked @experimental and therefore ... + val i0: A = ??? // error: class A is marked @experimental and therefore ... + val i1: X = ??? // error: type X is marked @experimental and therefore ... + val i2: Y = ??? // error: type Y is marked @experimental and therefore ... + val i2: Z = ??? // error: type Y is marked @experimental and therefore ... + () + ``` +
      + +
      + Example 5 + + ```scala + @experimental + trait ExpSAM { + def foo(x: Int): Int + } + def bar(f: ExpSAM): Unit = {} // error: error form rule 2 + + def test: Unit = + bar(x => x) // error: reference to experimental SAM + () + ``` +
      + +2. The signatures of an experimental `def`, `val`, `var`, `given` and `type`, or constructors of `class` and `trait` are experimental scopes. Examples: + +
      + Example 1 + + ```scala + import scala.annotation.experimental + + @experimental def x = 2 + @experimental class A + @experimental type X + @experimental type Y = Int + @experimental opaque type Z = Int + + def test1( + p1: A, // error: class A is marked @experimental and therefore ... + p2: List[A], // error: class A is marked @experimental and therefore ... + p3: X, // error: type X is marked @experimental and therefore ... + p4: Y, // error: type Y is marked @experimental and therefore ... + p5: Z, // error: type Z is marked @experimental and therefore ... + p6: Any = x // error: def x is marked @experimental and therefore ... + ): A = ??? // error: class A is marked @experimental and therefore ... + + @experimental def test2( + p1: A, + p2: List[A], + p3: X, + p4: Y, + p5: Z, + p6: Any = x + ): A = ??? + + class Test1( + p1: A, // error + p2: List[A], // error + p3: X, // error + p4: Y, // error + p5: Z, // error + p6: Any = x // error + ) {} + + @experimental class Test2( + p1: A, + p2: List[A], + p3: X, + p4: Y, + p5: Z, + p6: Any = x + ) {} + + trait Test1( + p1: A, // error + p2: List[A], // error + p3: X, // error + p4: Y, // error + p5: Z, // error + p6: Any = x // error + ) {} + + @experimental trait Test2( + p1: A, + p2: List[A], + p3: X, + p4: Y, + p5: Z, + p6: Any = x + ) {} + ``` +
      + +3. The `extends` clause of an experimental `class`, `trait` or `object` is an experimental scope. Examples: + +
      + Example 1 + + ```scala + import scala.annotation.experimental + + @experimental def x = 2 + + @experimental class A1(x: Any) + class A2(x: Any) + + + @experimental class B1 extends A1(1) + class B2 extends A1(1) // error: class A1 is marked @experimental and therefore marked @experimental and therefore ... + + @experimental class C1 extends A2(x) + class C2 extends A2(x) // error def x is marked @experimental and therefore + ``` +
      + +4. The body of an experimental `class`, `trait` or `object` is an experimental scope. Examples: + +
      + Example 1 + + ```scala + import scala.annotation.experimental + + @experimental def x = 2 + + @experimental class A { + def f = x // ok because A is experimental + } + + @experimental class B { + def f = x // ok because A is experimental + } + + @experimental object C { + def f = x // ok because A is experimental + } + + @experimental class D { + def f = { + object B { + x // ok because A is experimental + } + } + } + ``` + +
      + +5. Annotations of an experimental definition are in experimental scopes. Examples: + +
      + Example 1 + + ```scala + import scala.annotation.experimental + + @experimental class myExperimentalAnnot extends scala.annotation.Annotation + + @myExperimentalAnnot // error + def test: Unit = () + + @experimental + @myExperimentalAnnot + def test: Unit = () + ``` + +
      + +6. Any code compiled using a [_Nightly_](https://search.maven.org/artifact/org.scala-lang/scala3-compiler_3) or _Snapshot_ version of the compiler is considered to be in an experimental scope. +Can use the `-Yno-experimental` compiler flag to disable it and run as a proper release. + +In any other situation, a reference to an experimental definition will cause a compilation error. + +## Experimental inheritance + +All subclasses of an experimental `class` or `trait` must be marked as [`@experimental`](https://scala-lang.org/api/3.x/scala/annotation/experimental.html) even if they are in an experimental scope. +Anonymous classes and SAMs of experimental classes are considered experimental. + +We require explicit annotations to make sure we do not have completion or cycles issues with nested classes. This restriction could be relaxed in the future. + +## Experimental overriding + +For an overriding member `M` and overridden member `O`, if `O` is non-experimental then `M` must be non-experimental. + +This makes sure that we cannot have accidental binary incompatibilities such as the following change. +```diff +class A: + def f: Any = 1 +class B extends A: +- @experimental def f: Int = 2 +``` + +## Test frameworks + +Tests can be defined as experimental. Tests frameworks can execute tests using reflection even if they are in an experimental class, object or method. Examples: + +
      +Example 1 + +Test that touch experimental APIs can be written as follows + +```scala +import scala.annotation.experimental + +@experimental def x = 2 + +class MyTests { + /*@Test*/ def test1 = x // error + @experimental /*@Test*/ def test2 = x +} + +@experimental +class MyExperimentalTests { + /*@Test*/ def test1 = x + /*@Test*/ def test2 = x +} +``` + +
      diff --git a/docs/_spec/TODOreference/other-new-features/export.md b/docs/_spec/TODOreference/other-new-features/export.md new file mode 100644 index 000000000000..40e2ad9df248 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/export.md @@ -0,0 +1,234 @@ +--- +layout: doc-page +title: "Export Clauses" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/export.html +--- + +An export clause defines aliases for selected members of an object. Example: + +```scala +class BitMap +class InkJet + +class Printer: + type PrinterType + def print(bits: BitMap): Unit = ??? + def status: List[String] = ??? + +class Scanner: + def scan(): BitMap = ??? + def status: List[String] = ??? + +class Copier: + private val printUnit = new Printer { type PrinterType = InkJet } + private val scanUnit = new Scanner + + export scanUnit.scan + export printUnit.{status as _, *} + + def status: List[String] = printUnit.status ++ scanUnit.status +``` + +The two `export` clauses define the following _export aliases_ in class `Copier`: + +```scala +final def scan(): BitMap = scanUnit.scan() +final def print(bits: BitMap): Unit = printUnit.print(bits) +final type PrinterType = printUnit.PrinterType +``` + +They can be accessed inside `Copier` as well as from outside: + +```scala +val copier = new Copier +copier.print(copier.scan()) +``` + +An `export` clause has the same format as an import clause. Its general form is: + +```scala +export path . { sel_1, ..., sel_n } +``` + +It consists of a qualifier expression `path`, which must be a stable identifier, followed by +one or more selectors `sel_i` that identify what gets an alias. Selectors can be +of one of the following forms: + + - A _simple selector_ `x` creates aliases for all eligible members of `path` that are named `x`. + - A _renaming selector_ `x as y` creates aliases for all eligible members of `path` that are named `x`, but the alias is named `y` instead of `x`. + - An _omitting selector_ `x as _` prevents `x` from being aliased by a subsequent + wildcard selector. + - A _given selector_ `given x` has an optional type bound `x`. It creates aliases for all eligible given instances that conform to either `x`, or `Any` if `x` is omitted, except for members that are named by a previous simple, renaming, or omitting selector. + - A _wildcard selector_ `*` creates aliases for all eligible members of `path` except for given instances, + synthetic members generated by the compiler and those members that are named by a previous simple, renaming, or omitting selector. + \ + Notes: + - eligible construtor proxies are also included, even though they are synthetic members. + - members created by an export are also included. They are created by the compiler, but are not considered synthetic. + +A member is _eligible_ if all of the following holds: + + - its owner is not a base class of the class[(\*)](#note_class) containing the export clause, + - the member does not override a concrete definition that has as owner + a base class of the class containing the export clause. + - it is accessible at the export clause, + - it is not a constructor, nor the (synthetic) class part of an object, + - it is a given instance (declared with `given`) if and only if the export is from a _given selector_. + +It is a compile-time error if a simple or renaming selector does not identify +any eligible members. + +It is a compile-time error if a simple or renaming selector does not identify any eligible members. + +Type members are aliased by type definitions, and term members are aliased by method definitions. For instance: +```scala +object O: + class C(val x: Int) + def m(c: C): Int = c.x + 1 +export O.* + // generates + // type C = O.C + // def m(c: O.C): Int = O.m(c) +``` + +Export aliases copy the type and value parameters of the members they refer to. +Export aliases are always `final`. Aliases of given instances are again defined as givens (and aliases of old-style implicits are `implicit`). Aliases of extensions are again defined as extensions. Aliases of inline methods or values are again defined `inline`. There are no other modifiers that can be given to an alias. This has the following consequences for overriding: + + - Export aliases cannot be overridden, since they are final. + - Export aliases cannot override concrete members in base classes, since they are + not marked `override`. + - However, export aliases can implement deferred members of base classes. + +Export aliases for public value definitions that are accessed without +referring to private values in the qualifier path +are marked by the compiler as "stable" and their result types are the singleton types of the aliased definitions. This means that they can be used as parts of stable identifier paths, even though they are technically methods. For instance, the following is OK: +```scala +class C { type T } +object O { val c: C = ... } +export O.c +def f: c.T = ... +``` + + +**Restrictions:** + + 1. Export clauses can appear in classes or they can appear at the top-level. An export clause cannot appear as a statement in a block. + 1. If an export clause contains a wildcard or given selector, it is forbidden for its qualifier path to refer to a package. This is because it is not yet known how to safely track wildcard dependencies to a package for the purposes of incremental compilation. + 1. An export renaming hides un-renamed exports matching the target name. For instance, the following + clause would be invalid since `B` is hidden by the renaming `A as B`. + ```scala + export {A as B, B} // error: B is hidden + ``` + + 1. Renamings in an export clause must have pairwise different target names. For instance, the following clause would be invalid: + ```scala + export {A as C, B as C} // error: duplicate renaming + + 1. Simple renaming exports like + ```scala + export status as stat + ``` + are not supported yet. They would run afoul of the restriction that the + exported `a` cannot be already a member of the object containing the export. + This restriction might be lifted in the future. + + +(\*) **Note:** Unless otherwise stated, the term "class" in this discussion also includes object and trait definitions. + +## Motivation + +It is a standard recommendation to prefer composition over inheritance. This is really an application of the principle of least power: Composition treats components as blackboxes whereas inheritance can affect the internal workings of components through overriding. Sometimes the close coupling implied by inheritance is the best solution for a problem, but where this is not necessary the looser coupling of composition is better. + +So far, object-oriented languages including Scala made it much easier to use inheritance than composition. Inheritance only requires an `extends` clause whereas composition required a verbose elaboration of a sequence of forwarders. So in that sense, object-oriented languages are pushing +programmers to a solution that is often too powerful. Export clauses redress the balance. They make composition relationships as concise and easy to express as inheritance relationships. Export clauses also offer more flexibility than extends clauses since members can be renamed or omitted. + +Export clauses also fill a gap opened by the shift from package objects to top-level definitions. One occasionally useful idiom that gets lost in this shift is a package object inheriting from some class. The idiom is often used in a facade like pattern, to make members +of internal compositions available to users of a package. Top-level definitions are not wrapped in a user-defined object, so they can't inherit anything. However, top-level definitions can be export clauses, which supports the facade design pattern in a safer and +more flexible way. + +## Export Clauses in Extensions + +An export clause may also appear in an extension. + +Example: +```scala +class StringOps(x: String): + def *(n: Int): String = ... + def capitalize: String = ... + +extension (x: String) + def take(n: Int): String = x.substring(0, n) + def drop(n: Int): String = x.substring(n) + private def moreOps = new StringOps(x) + export moreOps.* +``` +In this case the qualifier expression must be an identifier that refers to a unique parameterless extension method in the same extension clause. The export will create +extension methods for all accessible term members +in the result of the qualifier path. For instance, the extension above would be expanded to +```scala +extension (x: String) + def take(n: Int): String = x.substring(0, n) + def drop(n: Int): String = x.substring(n) + private def moreOps = StringOps(x) + def *(n: Int): String = moreOps.*(n) + def capitalize: String = moreOps.capitalize +``` + +## Syntax changes: + +``` +TemplateStat ::= ... + | Export +TopStat ::= ... + | Export +ExtMethod ::= ... + | Export +Export ::= ‘export’ ImportExpr {‘,’ ImportExpr} +ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec +ImportSpec ::= NamedSelector + | WildcardSelector + | ‘{’ ImportSelectors) ‘}’ +NamedSelector ::= id [‘as’ (id | ‘_’)] +WildCardSelector ::= ‘*’ | ‘given’ [InfixType] +ImportSelectors ::= NamedSelector [‘,’ ImportSelectors] + | WildCardSelector {‘,’ WildCardSelector} +``` + +## Elaboration of Export Clauses + +Export clauses raise questions about the order of elaboration during type checking. +Consider the following example: + +```scala +class B { val c: Int } +object a { val b = new B } +export a.* +export b.* +``` + +Is the `export b.*` clause legal? If yes, what does it export? Is it equivalent to `export a.b.*`? What about if we swap the last two clauses? + +``` +export b.* +export a.* +``` + +To avoid tricky questions like these, we fix the elaboration order of exports as follows. + +Export clauses are processed when the type information of the enclosing object or class is completed. Completion so far consisted of the following steps: + + 1. Elaborate any annotations of the class. + 2. Elaborate the parameters of the class. + 3. Elaborate the self type of the class, if one is given. + 4. Enter all definitions of the class as class members, with types to be completed + on demand. + 5. Determine the types of all parents of the class. + + With export clauses, the following steps are added: + + 6. Compute the types of all paths in export clauses. + 7. Enter export aliases for the eligible members of all paths in export clauses. + +It is important that steps 6 and 7 are done in sequence: We first compute the types of _all_ +paths in export clauses and only after this is done we enter any export aliases as class members. This means that a path of an export clause cannot refer to an alias made available +by another export clause of the same class. diff --git a/docs/_spec/TODOreference/other-new-features/indentation.md b/docs/_spec/TODOreference/other-new-features/indentation.md new file mode 100644 index 000000000000..e931030ab696 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/indentation.md @@ -0,0 +1,509 @@ +--- +layout: doc-page +title: "Optional Braces" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/indentation.html +--- + +Scala 3 enforces some rules on indentation and allows some occurrences of braces `{...}` to be optional: + +- First, some badly indented programs are flagged with warnings. +- Second, some occurrences of braces `{...}` are made optional. Generally, the rule + is that adding a pair of optional braces will not change the meaning of a well-indented program. + +These changes can be turned off with the compiler flag `-no-indent`. + +## Indentation Rules + +The compiler enforces two rules for well-indented programs, flagging violations as warnings. + + 1. In a brace-delimited region, no statement is allowed to start to the left + of the first statement after the opening brace that starts a new line. + + This rule is helpful for finding missing closing braces. It prevents errors like: + + ```scala + if (x < 0) { + println(1) + println(2) + + println("done") // error: indented too far to the left + ``` + + 2. If significant indentation is turned off (i.e. under Scala 2 mode or under `-no-indent`) and we are at the start of an indented sub-part of an expression, and the indented part ends in a newline, the next statement must start at an indentation width less than the sub-part. This prevents errors where an opening brace was forgotten, as in + + ```scala + if (x < 0) + println(1) + println(2) // error: missing `{` + ``` + +These rules still leave a lot of leeway how programs should be indented. For instance, they do not impose +any restrictions on indentation within expressions, nor do they require that all statements of an indentation block line up exactly. + +The rules are generally helpful in pinpointing the root cause of errors related to missing opening or closing braces. These errors are often quite hard to diagnose, in particular in large programs. + +## Optional Braces + +The compiler will insert `` or `` +tokens at certain line breaks. Grammatically, pairs of `` and `` tokens have the same effect as pairs of braces `{` and `}`. + +The algorithm makes use of a stack `IW` of previously encountered indentation widths. The stack initially holds a single element with a zero indentation width. The _current indentation width_ is the indentation width of the top of the stack. + +There are two rules: + + 1. An `` is inserted at a line break, if + + - An indentation region can start at the current position in the source, and + - the first token on the next line has an indentation width strictly greater + than the current indentation width + + An indentation region can start + + - after the leading parameters of an `extension`, or + - after a `with` in a given instance, or + - after a `:` at the start of a template body (see discussion of `` below), or + - after one of the following tokens: + + ``` + = => ?=> <- catch do else finally for + if match return then throw try while yield + ``` + + - after the closing `)` of a condition in an old-style `if` or `while`. + - after the closing `)` or `}` of the enumerations of an old-style `for` loop without a `do`. + + If an `` is inserted, the indentation width of the token on the next line + is pushed onto `IW`, which makes it the new current indentation width. + + 2. An `` is inserted at a line break, if + + - the first token on the next line has an indentation width strictly less + than the current indentation width, and + - the last token on the previous line is not one of the following tokens + which indicate that the previous statement continues: + ``` + then else do catch finally yield match + ``` + - if the first token on the next line is a + [leading infix operator](../changed-features/operators.md). + then its indentation width is less then the current indentation width, + and it either matches a previous indentation width or is also less + than the enclosing indentation width. + + If an `` is inserted, the top element is popped from `IW`. + If the indentation width of the token on the next line is still less than the new current indentation width, step (2) repeats. Therefore, several `` tokens + may be inserted in a row. + + The following two additional rules support parsing of legacy code with ad-hoc layout. They might be withdrawn in future language versions: + + - An `` is also inserted if the next token following a statement sequence starting with an `` closes an indentation region, i.e. is one of `then`, `else`, `do`, `catch`, `finally`, `yield`, `}`, `)`, `]` or `case`. + + - An `` is finally inserted in front of a comma that follows a statement sequence starting with an `` if the indented region is itself enclosed in parentheses. + +It is an error if the indentation width of the token following an `` does not match the indentation of some previous line in the enclosing indentation region. For instance, the following would be rejected. + +```scala +if x < 0 then + -x + else // error: `else` does not align correctly + x +``` + +Indentation tokens are only inserted in regions where newline statement separators are also inferred: +at the top-level, inside braces `{...}`, but not inside parentheses `(...)`, patterns or types. + +**Note:** The rules for leading infix operators above are there to make sure that +```scala + one + + two.match + case 1 => b + case 2 => c + + three +``` +is parsed as `one + (two.match ...) + three`. Also, that +```scala +if x then + a + + b + + c +else d +``` +is parsed as `if x then a + b + c else d`. + +## Optional Braces Around Template Bodies + +The Scala grammar uses the term _template body_ for the definitions of a class, trait, or object that are normally enclosed in braces. The braces around a template body can also be omitted by means of the following rule. + +A template body can alternatively consist of a colon followed by one or more indented statements. To this purpose we introduce a new `` token that reads as +the standard colon "`:`" but is generated instead of it where `` +is legal according to the context free syntax, but only if the previous token +is an alphanumeric identifier, a backticked identifier, or one of the tokens `this`, `super`, "`)`", and "`]`". + +An indentation region can start after a ``. A template body may be either enclosed in braces, or it may start with +` ` and end with ``. +Analogous rules apply for enum bodies, type refinements, and local packages containing nested definitions. + +With these new rules, the following constructs are all valid: + +```scala +trait A: + def f: Int + +class C(x: Int) extends A: + def f = x + +object O: + def f = 3 + +enum Color: + case Red, Green, Blue + +new A: + def f = 3 + +package p: + def a = 1 + +package q: + def b = 2 +``` + +In each case, the `:` at the end of line can be replaced without change of meaning by a pair of braces that enclose the following indented definition(s). + +The syntax changes allowing this are as follows: + +Define for an arbitrary sequence of tokens or non-terminals `TS`: + +``` +:<<< TS >>> ::= ‘{’ TS ‘}’ + | +``` +Then the grammar changes as follows: +``` +TemplateBody ::= :<<< [SelfType] TemplateStat {semi TemplateStat} >>> +EnumBody ::= :<<< [SelfType] EnumStat {semi EnumStat} >>> +Refinement ::= :<<< [RefineDcl] {semi [RefineDcl]} >>> +Packaging ::= ‘package’ QualId :<<< TopStats >>> +``` + +## Spaces vs Tabs + +Indentation prefixes can consist of spaces and/or tabs. Indentation widths are the indentation prefixes themselves, ordered by the string prefix relation. So, so for instance "2 tabs, followed by 4 spaces" is strictly less than "2 tabs, followed by 5 spaces", but "2 tabs, followed by 4 spaces" is incomparable to "6 tabs" or to "4 spaces, followed by 2 tabs". It is an error if the indentation width of some line is incomparable with the indentation width of the region that's current at that point. To avoid such errors, it is a good idea not to mix spaces and tabs in the same source file. + +## Indentation and Braces + +Indentation can be mixed freely with braces `{...}`, as well as brackets `[...]` and parentheses `(...)`. For interpreting indentation inside such regions, the following rules apply. + + 1. The assumed indentation width of a multiline region enclosed in braces is the + indentation width of the first token that starts a new line after the opening brace. + + 2. The assumed indentation width of a multiline region inside brackets or parentheses is: + + - if the opening bracket or parenthesis is at the end of a line, the indentation width of token following it, + - otherwise, the indentation width of the enclosing region. + + 3. On encountering a closing brace `}`, bracket `]` or parenthesis `)`, as many `` tokens as necessary are inserted to close all open nested indentation regions. + +For instance, consider: +```scala +{ + val x = f(x: Int, y => + x * ( + y + 1 + ) + + (x + + x) + ) +} +``` + - Here, the indentation width of the region enclosed by the braces is 3 (i.e. the indentation width of the +statement starting with `val`). + - The indentation width of the region in parentheses that follows `f` is also 3, since the opening + parenthesis is not at the end of a line. + - The indentation width of the region in parentheses around `y + 1` is 9 + (i.e. the indentation width of `y + 1`). + - Finally, the indentation width of the last region in parentheses starting with `(x` is 6 (i.e. the indentation width of the indented region following the `=>`. + +## Special Treatment of Case Clauses + +The indentation rules for `match` expressions and `catch` clauses are refined as follows: + +- An indentation region is opened after a `match` or `catch` also if the following `case` + appears at the indentation width that's current for the `match` itself. +- In that case, the indentation region closes at the first token at that + same indentation width that is not a `case`, or at any token with a smaller + indentation width, whichever comes first. + +The rules allow to write `match` expressions where cases are not indented themselves, as in the example below: + +```scala +x match +case 1 => print("I") +case 2 => print("II") +case 3 => print("III") +case 4 => print("IV") +case 5 => print("V") + +println(".") +``` + +## Using Indentation to Signal Statement Continuation + +Indentation is used in some situations to decide whether to insert a virtual semicolon between +two consecutive lines or to treat them as one statement. Virtual semicolon insertion is +suppressed if the second line is indented more relative to the first one, and either the second line +starts with "`(`", "`[`", or "`{`" or the first line ends with `return`. Examples: + +```scala +f(x + 1) + (2, 3) // equivalent to `f(x + 1)(2, 3)` + +g(x + 1) +(2, 3) // equivalent to `g(x + 1); (2, 3)` + +h(x + 1) + {} // equivalent to `h(x + 1){}` + +i(x + 1) +{} // equivalent to `i(x + 1); {}` + +if x < 0 then return + a + b // equivalent to `if x < 0 then return a + b` + +if x < 0 then return +println(a + b) // equivalent to `if x < 0 then return; println(a + b)` +``` +In Scala 2, a line starting with "`{`" always continues the function call on the preceding line, +irrespective of indentation, whereas a virtual semicolon is inserted in all other cases. +The Scala-2 behavior is retained under source `-no-indent` or `-source 3.0-migration`. + + + +## The End Marker + +Indentation-based syntax has many advantages over other conventions. But one possible problem is that it makes it hard to discern when a large indentation region ends, since there is no specific token that delineates the end. Braces are not much better since a brace by itself also contains no information about what region is closed. + +To solve this problem, Scala 3 offers an optional `end` marker. Example: + +```scala +def largeMethod(...) = + ... + if ... then ... + else + ... // a large block + end if + ... // more code +end largeMethod +``` + +An `end` marker consists of the identifier `end` and a follow-on specifier token that together constitute all the tokes of a line. Possible specifier tokens are +identifiers or one of the following keywords + +```scala +if while for match try new this val given +``` + +End markers are allowed in statement sequences. The specifier token `s` of an end marker must correspond to the statement that precedes it. This means: + +- If the statement defines a member `x` then `s` must be the same identifier `x`. +- If the statement defines a constructor then `s` must be `this`. +- If the statement defines an anonymous given, then `s` must be `given`. +- If the statement defines an anonymous extension, then `s` must be `extension`. +- If the statement defines an anonymous class, then `s` must be `new`. +- If the statement is a `val` definition binding a pattern, then `s` must be `val`. +- If the statement is a package clause that refers to package `p`, then `s` must be the same identifier `p`. +- If the statement is an `if`, `while`, `for`, `try`, or `match` statement, then `s` must be that same token. + +For instance, the following end markers are all legal: + +```scala +package p1.p2: + + abstract class C(): + + def this(x: Int) = + this() + if x > 0 then + val a :: b = + x :: Nil + end val + var y = + x + end y + while y > 0 do + println(y) + y -= 1 + end while + try + x match + case 0 => println("0") + case _ => + end match + finally + println("done") + end try + end if + end this + + def f: String + end C + + object C: + given C = + new C: + def f = "!" + end f + end new + end given + end C + + extension (x: C) + def ff: String = x.f ++ x.f + end extension + +end p2 +``` + +### When to Use End Markers + +It is recommended that `end` markers are used for code where the extent of an indentation region is not immediately apparent "at a glance". People will have different preferences what this means, but one can nevertheless give some guidelines that stem from experience. An end marker makes sense if + +- the construct contains blank lines, or +- the construct is long, say 15-20 lines or more, +- the construct ends heavily indented, say 4 indentation levels or more. + +If none of these criteria apply, it's often better to not use an end marker since the code will be just as clear and more concise. If there are several ending regions that satisfy one of the criteria above, we usually need an end marker only for the outermost closed region. So cascades of end markers as in the example above are usually better avoided. + +### Syntax + +``` +EndMarker ::= ‘end’ EndMarkerTag -- when followed by EOL +EndMarkerTag ::= id | ‘if’ | ‘while’ | ‘for’ | ‘match’ | ‘try’ + | ‘new’ | ‘this’ | ‘given’ | ‘extension’ | ‘val’ +BlockStat ::= ... | EndMarker +TemplateStat ::= ... | EndMarker +TopStat ::= ... | EndMarker +``` + +## Example + +Here is a (somewhat meta-circular) example of code using indentation. It provides a concrete representation of indentation widths as defined above together with efficient operations for constructing and comparing indentation widths. + +```scala +enum IndentWidth: + case Run(ch: Char, n: Int) + case Conc(l: IndentWidth, r: Run) + + def <= (that: IndentWidth): Boolean = this match + case Run(ch1, n1) => + that match + case Run(ch2, n2) => n1 <= n2 && (ch1 == ch2 || n1 == 0) + case Conc(l, r) => this <= l + case Conc(l1, r1) => + that match + case Conc(l2, r2) => l1 == l2 && r1 <= r2 + case _ => false + + def < (that: IndentWidth): Boolean = + this <= that && !(that <= this) + + override def toString: String = + this match + case Run(ch, n) => + val kind = ch match + case ' ' => "space" + case '\t' => "tab" + case _ => s"'$ch'-character" + val suffix = if n == 1 then "" else "s" + s"$n $kind$suffix" + case Conc(l, r) => + s"$l, $r" + +object IndentWidth: + private inline val MaxCached = 40 + + private val spaces = IArray.tabulate(MaxCached + 1)(new Run(' ', _)) + private val tabs = IArray.tabulate(MaxCached + 1)(new Run('\t', _)) + + def Run(ch: Char, n: Int): Run = + if n <= MaxCached && ch == ' ' then + spaces(n) + else if n <= MaxCached && ch == '\t' then + tabs(n) + else + new Run(ch, n) + end Run + + val Zero = Run(' ', 0) +end IndentWidth +``` + +## Settings and Rewrites + +Significant indentation is enabled by default. It can be turned off by giving any of the options `-no-indent`, `-old-syntax` and `-source 3.0-migration`. If indentation is turned off, it is nevertheless checked that indentation conforms to the logical program structure as defined by braces. If that is not the case, the compiler issues a warning. + +The Scala 3 compiler can rewrite source code to indented code and back. +When invoked with options `-rewrite -indent` it will rewrite braces to +indented regions where possible. When invoked with options `-rewrite -no-indent` it will rewrite in the reverse direction, inserting braces for indentation regions. +The `-indent` option only works on [new-style syntax](./control-syntax.md). So to go from old-style syntax to new-style indented code one has to invoke the compiler twice, first with options `-rewrite -new-syntax`, then again with options +`-rewrite -indent`. To go in the opposite direction, from indented code to old-style syntax, it's `-rewrite -no-indent`, followed by `-rewrite -old-syntax`. + +## Variant: Indentation Marker `:` for Arguments + +Generally, the possible indentation regions coincide with those regions where braces `{...}` are also legal, no matter whether the braces enclose an expression or a set of definitions. There is one exception, though: Arguments to functions can be enclosed in braces but they cannot be simply indented instead. Making indentation always significant for function arguments would be too restrictive and fragile. + +To allow such arguments to be written without braces, a variant of the indentation scheme is implemented under language import +```scala +import language.experimental.fewerBraces +``` +In this variant, a `` token is also recognized where function argument would be expected. Examples: + +```scala +times(10): + println("ah") + println("ha") +``` + +or + +```scala +credentials `++`: + val file = Path.userHome / ".credentials" + if file.exists + then Seq(Credentials(file)) + else Seq() +``` + +or + +```scala +xs.map: + x => + val y = x - 1 + y * y +``` +What's more, a `:` in these settings can also be followed on the same line by the parameter part and arrow of a lambda. So the last example could be compressed to this: + +```scala +xs.map: x => + val y = x - 1 + y * y +``` +and the following would also be legal: +```scala +xs.foldLeft(0): (x, y) => + x + y +``` + +The grammar changes for this variant are as follows. + +``` +SimpleExpr ::= ... + | SimpleExpr ColonArgument +InfixExpr ::= ... + | InfixExpr id ColonArgument +ColonArgument ::= colon [LambdaStart] + indent (CaseClauses | Block) outdent +LambdaStart ::= FunParams (‘=>’ | ‘?=>’) + | HkTypeParamClause ‘=>’ +``` \ No newline at end of file diff --git a/docs/_spec/TODOreference/other-new-features/kind-polymorphism.md b/docs/_spec/TODOreference/other-new-features/kind-polymorphism.md new file mode 100644 index 000000000000..8f0172c4c04b --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/kind-polymorphism.md @@ -0,0 +1,47 @@ +--- +layout: doc-page +title: "Kind Polymorphism" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/kind-polymorphism.html +--- + +Normally type parameters in Scala are partitioned into _kinds_. First-level types are types of values. Higher-kinded types are type constructors +such as `List` or `Map`. The kind of a type is indicated by the top type of which it is a subtype. Normal types are subtypes of `Any`, +covariant single argument type constructors such as `List` are subtypes of `[+X] =>> Any`, and the `Map` type constructor is +a subtype of `[X, +Y] =>> Any`. + +A type can be used only as prescribed by its kind. Subtypes of `Any` cannot be applied to type arguments whereas subtypes of `[X] =>> Any` +_must_ be applied to a type argument, unless they are passed to type parameters of the same kind. + +Sometimes we would like to have type parameters that can have more than one kind, for instance to define an implicit +value that works for parameters of any kind. This is now possible through a form of (_subtype_) kind polymorphism. +Kind polymorphism relies on the special type [`scala.AnyKind`](https://scala-lang.org/api/3.x/scala/AnyKind.html) that can be used as an upper bound of a type. + +```scala +def f[T <: AnyKind] = ... +``` + +The actual type arguments of `f` can then be types of arbitrary kinds. So the following would all be legal: + +```scala +f[Int] +f[List] +f[Map] +f[[X] =>> String] +``` + +We call type parameters and abstract types with an `AnyKind` upper bound _any-kinded types_. +Since the actual kind of an any-kinded type is unknown, its usage must be heavily restricted: An any-kinded type +can be neither the type of a value, nor can it be instantiated with type parameters. So about the only +thing one can do with an any-kinded type is to pass it to another any-kinded type argument. +Nevertheless, this is enough to achieve some interesting generalizations that work across kinds, typically +through advanced uses of implicits. + +(todo: insert good concise example) + +Some technical details: [`AnyKind`](https://scala-lang.org/api/3.x/scala/AnyKind.html) is a synthesized class just like `Any`, but without any members. It extends no other class. +It is declared `abstract` and `final`, so it can be neither instantiated nor extended. + +`AnyKind` plays a special role in Scala's subtype system: It is a supertype of all other types no matter what their kind is. It is also assumed to be kind-compatible with all other types. Furthermore, `AnyKind` is treated as a higher-kinded type (so it cannot be used as a type of values), but at the same time it has no type parameters (so it cannot be instantiated). + +**Note**: This feature is considered experimental but stable and it can be disabled under compiler flag +(i.e. `-Yno-kind-polymorphism`). diff --git a/docs/_spec/TODOreference/other-new-features/matchable.md b/docs/_spec/TODOreference/other-new-features/matchable.md new file mode 100644 index 000000000000..234fdf03220c --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/matchable.md @@ -0,0 +1,141 @@ +--- +layout: doc-page +title: "The Matchable Trait" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/matchable.html +--- + +A new trait [`Matchable`](https://scala-lang.org/api/3.x/scala/Matchable.html) controls the ability to pattern match. + +## The Problem + +The Scala 3 standard library has a type [`IArray`](https://scala-lang.org/api/3.x/scala.html#IArray-0) for immutable +arrays that is defined like this: + +```scala + opaque type IArray[+T] = Array[_ <: T] +``` + +The `IArray` type offers extension methods for `length` and `apply`, but not for `update`; hence it seems values of type `IArray` cannot be updated. + +However, there is a potential hole due to pattern matching. Consider: + +```scala +val imm: IArray[Int] = ... +imm match + case a: Array[Int] => a(0) = 1 +``` + +The test will succeed at runtime since [`IArray`](https://scala-lang.org/api/3.x/scala.html#IArray-0)s _are_ represented as +`Array`s at runtime. But if we allowed it, it would break the fundamental abstraction of immutable arrays. + +__Aside:__ One could also achieve the same by casting: + +```scala +imm.asInstanceOf[Array[Int]](0) = 1 +``` + +But that is not as much of a problem since in Scala `asInstanceOf` is understood to be low-level and unsafe. By contrast, a pattern match that compiles without warning or error should not break abstractions. + +Note also that the problem is not tied to [opaque types](opaques.md) as match selectors. The following slight variant with a value of parametric +type `T` as match selector leads to the same problem: + +```scala +def f[T](x: T) = x match + case a: Array[Int] => a(0) = 0 +f(imm) +``` + +Finally, note that the problem is not linked to just [opaque types](opaques.md). No unbounded type parameter or abstract type should be decomposable with a pattern match. + +## The Solution + +There is a new type [`scala.Matchable`](https://scala-lang.org/api/3.x/scala/Matchable.html) that controls pattern matching. When typing a pattern match of a constructor pattern `C(...)` or +a type pattern `_: C` it is required that the selector type conforms +to `Matchable`. If that's not the case a warning is issued. For instance when compiling the example at the start of this section we get: + +``` +> sc ../new/test.scala -source future +-- Warning: ../new/test.scala:4:12 --------------------------------------------- +4 | case a: Array[Int] => a(0) = 0 + | ^^^^^^^^^^ + | pattern selector should be an instance of Matchable, + | but it has unmatchable type IArray[Int] instead +``` + +To allow migration from Scala 2 and cross-compiling +between Scala 2 and 3 the warning is turned on only for `-source future-migration` or higher. + +[`Matchable`](https://scala-lang.org/api/3.x/scala/Matchable.html) is a universal trait with `Any` as its parent class. It is extended by both [`AnyVal`](https://scala-lang.org/api/3.x/scala/AnyVal.html) and [`AnyRef`](https://scala-lang.org/api/3.x/scala/AnyRef.html). Since `Matchable` is a supertype of every concrete value or reference class it means that instances of such classes can be matched as before. However, match selectors of the following types will produce a warning: + +- Type `Any`: if pattern matching is required one should use `Matchable` instead. +- Unbounded type parameters and abstract types: If pattern matching is required they should have an upper bound `Matchable`. +- Type parameters and abstract types that are only bounded by some + universal trait: Again, `Matchable` should be added as a bound. + +Here is the hierarchy of top-level classes and traits with their defined methods: + +```scala +abstract class Any: + def getClass + def isInstanceOf + def asInstanceOf + def == + def != + def ## + def equals + def hashCode + def toString + +trait Matchable extends Any + +class AnyVal extends Any, Matchable +class Object extends Any, Matchable +``` + +[`Matchable`](https://scala-lang.org/api/3.x/scala/Matchable.html) is currently a marker trait without any methods. Over time +we might migrate methods `getClass` and `isInstanceOf` to it, since these are closely related to pattern-matching. + +## `Matchable` and Universal Equality + +Methods that pattern-match on selectors of type `Any` will need a cast once the +Matchable warning is turned on. The most common such method is the universal +`equals` method. It will have to be written as in the following example: + +```scala +class C(val x: String): + + override def equals(that: Any): Boolean = + that.asInstanceOf[Matchable] match + case that: C => this.x == that.x + case _ => false +``` + +The cast of `that` to [`Matchable`](https://scala-lang.org/api/3.x/scala/Matchable.html) serves as an indication that universal equality +is unsafe in the presence of abstract types and opaque types since it cannot properly distinguish the meaning of a type from its representation. The cast +is guaranteed to succeed at run-time since `Any` and [`Matchable`](https://scala-lang.org/api/3.x/scala/Matchable.html) both erase to +`Object`. + +For instance, consider the definitions + +```scala +opaque type Meter = Double +def Meter(x: Double): Meter = x + +opaque type Second = Double +def Second(x: Double): Second = x +``` + +Here, universal `equals` will return true for + +```scala + Meter(10).equals(Second(10)) +``` + +even though this is clearly false mathematically. With [multiversal equality](../contextual/multiversal-equality.md) one can mitigate that problem somewhat by turning + +```scala + import scala.language.strictEquality + Meter(10) == Second(10) +``` + +into a type error. diff --git a/docs/_spec/TODOreference/other-new-features/opaques-details.md b/docs/_spec/TODOreference/other-new-features/opaques-details.md new file mode 100644 index 000000000000..d7305a249089 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/opaques-details.md @@ -0,0 +1,126 @@ +--- +layout: doc-page +title: "Opaque Type Aliases: More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/opaques-details.html +--- + +## Syntax + +``` +Modifier ::= ... + | ‘opaque’ +``` + +`opaque` is a [soft modifier](../soft-modifier.md). It can still be used as a normal identifier when it is not in front of a definition keyword. + +Opaque type aliases must be members of classes, traits, or objects, or they are defined +at the top-level. They cannot be defined in local blocks. + +## Type Checking + +The general form of a (monomorphic) opaque type alias is + +```scala +opaque type T >: L <: U = R +``` + +where the lower bound `L` and the upper bound `U` may be missing, in which case they are assumed to be [`scala.Nothing`](https://scala-lang.org/api/3.x/scala/Nothing.html) and [`scala.Any`](https://scala-lang.org/api/3.x/scala/Any.html), respectively. If bounds are given, it is checked that the right-hand side `R` conforms to them, i.e. `L <: R` and `R <: U`. F-bounds are not supported for opaque type aliases: `T` is not allowed to appear in `L` or `U`. + +Inside the scope of the alias definition, the alias is transparent: `T` is treated +as a normal alias of `R`. Outside its scope, the alias is treated as the abstract type +```scala +type T >: L <: U +``` +A special case arises if the opaque type alias is defined in an object. Example: + +```scala +object o: + opaque type T = R +``` + +In this case we have inside the object (also for non-opaque types) that `o.T` is equal to +`T` or its expanded form `o.this.T`. Equality is understood here as mutual subtyping, i.e. +`o.T <: o.this.T` and `o.this.T <: T`. Furthermore, we have by the rules of opaque type aliases +that `o.this.T` equals `R`. The two equalities compose. That is, inside `o`, it is +also known that `o.T` is equal to `R`. This means the following code type-checks: + +```scala +object o: + opaque type T = Int + val x: Int = id(2) +def id(x: o.T): o.T = x +``` + +Opaque type aliases cannot be `private` and cannot be overridden in subclasses. +Opaque type aliases cannot have a context function type as right-hand side. + +## Type Parameters of Opaque Types + +Opaque type aliases can have a single type parameter list. The following aliases +are well-formed +```scala +opaque type F[T] = (T, T) +opaque type G = [T] =>> List[T] +``` +but the following are not: +```scala +opaque type BadF[T] = [U] =>> (T, U) +opaque type BadG = [T] =>> [U] => (T, U) +``` + +## Translation of Equality + +Comparing two values of opaque type with `==` or `!=` normally uses universal equality, +unless another overloaded `==` or `!=` operator is defined for the type. To avoid +boxing, the operation is mapped after type checking to the (in-)equality operator +defined on the underlying type. For instance, +```scala + opaque type T = Int + + ... + val x: T + val y: T + x == y // uses Int equality for the comparison. +``` + +## Top-level Opaque Types + +An opaque type alias on the top-level is transparent in all other top-level definitions in the sourcefile where it appears, but is opaque in nested +objects and classes and in all other source files. Example: +```scala +// in test1.scala +opaque type A = String +val x: A = "abc" + +object obj: + val y: A = "abc" // error: found: "abc", required: A + +// in test2.scala +def z: String = x // error: found: A, required: String +``` +This behavior becomes clear if one recalls that top-level definitions are placed in their own synthetic object. For instance, the code in `test1.scala` would expand to +```scala +object test1$package: + opaque type A = String + val x: A = "abc" + +object obj: + val y: A = "abc" // error: cannot assign "abc" to opaque type alias A +``` +The opaque type alias `A` is transparent in its scope, which includes the definition of `x`, but not the definitions of `obj` and `y`. + + +## Relationship to SIP 35 + +Opaque types in Scala 3 are an evolution from what is described in +[Scala SIP 35](https://docs.scala-lang.org/sips/opaque-types.html). + +The differences compared to the state described in this SIP are: + + 1. Opaque type aliases cannot be defined anymore in local statement sequences. + 2. The scope where an opaque type alias is visible is now the whole scope where + it is defined, instead of just a companion object. + 3. The notion of a companion object for opaque type aliases has been dropped. + 4. Opaque type aliases can have bounds. + 5. The notion of type equality involving opaque type aliases has been clarified. It was + strengthened with respect to the previous implementation of SIP 35. diff --git a/docs/_spec/TODOreference/other-new-features/opaques.md b/docs/_spec/TODOreference/other-new-features/opaques.md new file mode 100644 index 000000000000..d8c4d37bcb3b --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/opaques.md @@ -0,0 +1,179 @@ +--- +layout: doc-page +title: "Opaque Type Aliases" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/opaques.html +--- + +Opaque types aliases provide type abstraction without any overhead. Example: + +```scala +object MyMath: + + opaque type Logarithm = Double + + object Logarithm: + + // These are the two ways to lift to the Logarithm type + + def apply(d: Double): Logarithm = math.log(d) + + def safe(d: Double): Option[Logarithm] = + if d > 0.0 then Some(math.log(d)) else None + + end Logarithm + + // Extension methods define opaque types' public APIs + extension (x: Logarithm) + def toDouble: Double = math.exp(x) + def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y)) + def * (y: Logarithm): Logarithm = x + y + +end MyMath +``` + +This introduces `Logarithm` as a new abstract type, which is implemented as `Double`. +The fact that `Logarithm` is the same as `Double` is only known in the scope where +`Logarithm` is defined, which in the above example corresponds to the object `MyMath`. +Or in other words, within the scope, it is treated as a type alias, but this is opaque to the outside world +where, in consequence, `Logarithm` is seen as an abstract type that has nothing to do with `Double`. + +The public API of `Logarithm` consists of the `apply` and `safe` methods defined in the companion object. +They convert from `Double`s to `Logarithm` values. Moreover, an operation `toDouble` that converts the other way, and operations `+` and `*` are defined as extension methods on `Logarithm` values. +The following operations would be valid because they use functionality implemented in the `MyMath` object. + +```scala +import MyMath.Logarithm + +val l = Logarithm(1.0) +val l2 = Logarithm(2.0) +val l3 = l * l2 +val l4 = l + l2 +``` + +But the following operations would lead to type errors: + +```scala +val d: Double = l // error: found: Logarithm, required: Double +val l2: Logarithm = 1.0 // error: found: Double, required: Logarithm +l * 2 // error: found: Int(2), required: Logarithm +l / l2 // error: `/` is not a member of Logarithm +``` + +## Bounds For Opaque Type Aliases + +Opaque type aliases can also come with bounds. Example: + +```scala +object Access: + + opaque type Permissions = Int + opaque type PermissionChoice = Int + opaque type Permission <: Permissions & PermissionChoice = Int + + extension (x: PermissionChoice) + def | (y: PermissionChoice): PermissionChoice = x | y + extension (x: Permissions) + def & (y: Permissions): Permissions = x | y + extension (granted: Permissions) + def is(required: Permissions) = (granted & required) == required + def isOneOf(required: PermissionChoice) = (granted & required) != 0 + + val NoPermission: Permission = 0 + val Read: Permission = 1 + val Write: Permission = 2 + val ReadWrite: Permissions = Read | Write + val ReadOrWrite: PermissionChoice = Read | Write + +end Access +``` + +The `Access` object defines three opaque type aliases: + +- `Permission`, representing a single permission, +- `Permissions`, representing a set of permissions with the meaning "all of these permissions granted", +- `PermissionChoice`, representing a set of permissions with the meaning "at least one of these permissions granted". + +Outside the `Access` object, values of type `Permissions` may be combined using the `&` operator, +where `x & y` means "all permissions in `x` *and* in `y` granted". +Values of type `PermissionChoice` may be combined using the `|` operator, +where `x | y` means "a permission in `x` *or* in `y` granted". + +Note that inside the `Access` object, the `&` and `|` operators always resolve to the corresponding methods of `Int`, +because members always take precedence over extension methods. +For that reason, the `|` extension method in `Access` does not cause infinite recursion. + +In particular, the definition of `ReadWrite` must use `|`, the bitwise operator for `Int`, +even though client code outside `Access` would use `&`, the extension method on `Permissions`. +The internal representations of `ReadWrite` and `ReadOrWrite` are identical, but this is not visible to the client, +which is interested only in the semantics of `Permissions`, as in the example below. + +All three opaque type aliases have the same underlying representation type `Int`. The +`Permission` type has an upper bound `Permissions & PermissionChoice`. This makes +it known outside the `Access` object that `Permission` is a subtype of the other +two types. Hence, the following usage scenario type-checks. + +```scala +object User: + import Access.* + + case class Item(rights: Permissions) + extension (item: Item) + def +(other: Item): Item = Item(item.rights & other.rights) + + val roItem = Item(Read) // OK, since Permission <: Permissions + val woItem = Item(Write) + val rwItem = Item(ReadWrite) + val noItem = Item(NoPermission) + + assert(!roItem.rights.is(ReadWrite)) + assert(roItem.rights.isOneOf(ReadOrWrite)) + + assert(rwItem.rights.is(ReadWrite)) + assert(rwItem.rights.isOneOf(ReadOrWrite)) + + assert(!noItem.rights.is(ReadWrite)) + assert(!noItem.rights.isOneOf(ReadOrWrite)) + + assert((roItem + woItem).rights.is(ReadWrite)) +end User +``` +On the other hand, the call `roItem.rights.isOneOf(ReadWrite)` would give a type error: +```scala + assert(roItem.rights.isOneOf(ReadWrite)) + ^^^^^^^^^ + Found: (Access.ReadWrite : Access.Permissions) + Required: Access.PermissionChoice +``` +`Permissions` and `PermissionChoice` are different, unrelated types outside `Access`. + + +## Opaque Type Members on Classes +While typically, opaque types are used together with objects to hide implementation details of a module, they can also be used with classes. + +For example, we can redefine the above example of Logarithms as a class. +```scala +class Logarithms: + + opaque type Logarithm = Double + + def apply(d: Double): Logarithm = math.log(d) + + def safe(d: Double): Option[Logarithm] = + if d > 0.0 then Some(math.log(d)) else None + + def mul(x: Logarithm, y: Logarithm) = x + y +``` + +Opaque type members of different instances are treated as different: +```scala +val l1 = new Logarithms +val l2 = new Logarithms +val x = l1(1.5) +val y = l1(2.6) +val z = l2(3.1) +l1.mul(x, y) // type checks +l1.mul(x, z) // error: found l2.Logarithm, required l1.Logarithm +``` +In general, one can think of an opaque type as being only transparent in the scope of `private[this]`. + +[More details](opaques-details.md) diff --git a/docs/_spec/TODOreference/other-new-features/open-classes.md b/docs/_spec/TODOreference/other-new-features/open-classes.md new file mode 100644 index 000000000000..764c234df599 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/open-classes.md @@ -0,0 +1,80 @@ +--- +layout: doc-page +title: "Open Classes" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/open-classes.html +--- + +An `open` modifier on a class signals that the class is planned for extensions. Example: +```scala +// File Writer.scala +package p + +open class Writer[T]: + + /** Sends to stdout, can be overridden */ + def send(x: T) = println(x) + + /** Sends all arguments using `send` */ + def sendAll(xs: T*) = xs.foreach(send) +end Writer + +// File EncryptedWriter.scala +package p + +class EncryptedWriter[T: Encryptable] extends Writer[T]: + override def send(x: T) = super.send(encrypt(x)) +``` +An open class typically comes with some documentation that describes +the internal calling patterns between methods of the class as well as hooks that can be overridden. We call this the _extension contract_ of the class. It is different from the _external contract_ between a class and its users. + +Classes that are not open can still be extended, but only if at least one of two alternative conditions is met: + + - The extending class is in the same source file as the extended class. In this case, the extension is usually an internal implementation matter. + + - The language feature [`adhocExtensions`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$adhocExtensions$.html) is enabled for the extending class. This is typically enabled by an import clause in the source file of the extension: + ```scala + import scala.language.adhocExtensions + ``` + Alternatively, the feature can be enabled by the compiler option `-language:adhocExtensions`. + If the feature is not enabled, the compiler will issue a "feature" warning. For instance, if the `open` modifier on class `Writer` is dropped, compiling `EncryptedWriter` would produce a warning: + ``` + -- Feature Warning: EncryptedWriter.scala:6:14 ---- + |class EncryptedWriter[T: Encryptable] extends Writer[T] + | ^ + |Unless class Writer is declared 'open', its extension + | in a separate file should be enabled + |by adding the import clause 'import scala.language.adhocExtensions' + |or by setting the compiler option -language:adhocExtensions. + ``` + +## Motivation + +When writing a class, there are three possible expectations of extensibility: + +1. The class is intended to allow extensions. This means one should expect +a carefully worked out and documented extension contract for the class. + +2. Extensions of the class are forbidden, for instance to make correctness or security guarantees. + +3. There is no firm decision either way. The class is not _a priori_ intended for extensions, but if others find it useful to extend on an _ad-hoc_ basis, let them go ahead. However, they are on their own in this case. There is no documented extension contract, and future versions of the class might break the extensions (by rearranging internal call patterns, for instance). + +The three cases are clearly distinguished by using `open` for (1), `final` for (2) and no modifier for (3). + +It is good practice to avoid _ad-hoc_ extensions in a code base, since they tend to lead to fragile systems that are hard to evolve. But there +are still some situations where these extensions are useful: for instance, +to mock classes in tests, or to apply temporary patches that add features or fix bugs in library classes. That's why _ad-hoc_ extensions are permitted, but only if there is an explicit opt-in via a language feature import. + +## Details + + - `open` is a soft modifier. It is treated as a normal identifier + unless it is in modifier position. + - An `open` class cannot be `final` or `sealed`. + - Traits or `abstract` classes are always `open`, so `open` is redundant for them. + +## Relationship with `sealed` + +A class that is neither `abstract` nor `open` is similar to a `sealed` class: it can still be extended, but only in the same source file. The difference is what happens if an extension of the class is attempted in another source file. For a `sealed` class, this is an error, whereas for a simple non-open class, this is still permitted provided the [`adhocExtensions`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$adhocExtensions$.html) feature is enabled, and it gives a warning otherwise. + +## Migration + +`open` is a new modifier in Scala 3. To allow cross compilation between Scala 2.13 and Scala 3.0 without warnings, the feature warning for ad-hoc extensions is produced only under `-source future`. It will be produced by default from Scala 3.1 on. diff --git a/docs/_spec/TODOreference/other-new-features/other-new-features.md b/docs/_spec/TODOreference/other-new-features/other-new-features.md new file mode 100644 index 000000000000..974a8548cb68 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/other-new-features.md @@ -0,0 +1,7 @@ +--- +layout: index +title: "Other New Features" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features.html +--- + +The following pages document new features of Scala 3. diff --git a/docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md b/docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md new file mode 100644 index 000000000000..e5165550fc0d --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/parameter-untupling-spec.md @@ -0,0 +1,89 @@ +--- +layout: doc-page +title: "Parameter Untupling - More Details" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/parameter-untupling-spec.html +--- + +## Motivation + +Say you have a list of pairs + +```scala +val xs: List[(Int, Int)] +``` + +and you want to map `xs` to a list of `Int`s so that each pair of numbers is mapped to their sum. +Previously, the best way to do this was with a pattern-matching decomposition: + +```scala +xs.map { + case (x, y) => x + y +} +``` +While correct, this is inconvenient. Instead, we propose to write it the following way: + +```scala +xs.map { + (x, y) => x + y +} +``` + +or, equivalently: + +```scala +xs.map(_ + _) +``` + +Generally, a function value with `n > 1` parameters can be converted to a function with tupled arguments if the expected type is a unary function type of the form `((T_1, ..., T_n)) => U`. + +## Type Checking + +The type checking happens in two steps: + +1. Check whether parameter untupling is feasible +2. Adapt the function and type check it + +### Feasibility Check + +Suppose a function `f` of the form `(p1, ..., pn) => e` (where `n > 1`), with `p1, ..., pn` as parameters and `e` as function body. + +If the expected type for checking `f` is a fully defined function type of the form `TupleN[T1, ..., Tn] => R` (or an equivalent SAM-type), where each type `Ti` fits the corresponding parameter `pi`. Then `f` is feasible for parameter untupling with the expected type `TupleN[T1, ..., Tn] => R`. + +A type `Ti` fits a parameter `pi` if one of the following two cases is `true`: + +* `pi` comes without a type, i.e. it is a simple identifier or `_`. +* `pi` is of the form `x: Ui` or `_: Ui` and `Ti <: Ui`. + +Parameter untupling composes with eta-expansion. That is, an n-ary function generated by eta-expansion can in turn be adapted to the expected type with parameter untupling. + +### Term adaptation + +If the function + +```scala +(p1, ..., pn) => e +``` + +is feasible for parameter untupling with the expected type `TupleN[T1, ..., Tn] => Te`, then continue to type check the following adapted function + +```scala +(x: TupleN[T1, ..., Tn]) => + def p1: T1 = x._1 + ... + def pn: Tn = x._n + e +``` + +with the same expected type. +## Migration + +Code like this could not be written before, hence the new notation is not ambiguous after adoption. + +It is possible that someone has written an implicit conversion from `(T1, ..., Tn) => R` to `TupleN[T1, ..., Tn] => R` for some `n`. +Such a conversion is now only useful for general conversions of function values, when parameter untupling is not applicable. +Some care is required to implement the conversion efficiently. +Obsolete conversions could be detected and fixed by [`Scalafix`](https://scalacenter.github.io/scalafix/). + +## Reference + +For more information, see [Issue #897](https://github.com/lampepfl/dotty/issues/897). diff --git a/docs/_spec/TODOreference/other-new-features/parameter-untupling.md b/docs/_spec/TODOreference/other-new-features/parameter-untupling.md new file mode 100644 index 000000000000..fcc1fa11d519 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/parameter-untupling.md @@ -0,0 +1,77 @@ +--- +layout: doc-page +title: "Parameter Untupling" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/parameter-untupling.html +--- + +Say you have a list of pairs + +```scala +val xs: List[(Int, Int)] +``` + +and you want to map `xs` to a list of `Int`s so that each pair of numbers is mapped to +their sum. Previously, the best way to do this was with a pattern-matching decomposition: + +```scala +xs map { + case (x, y) => x + y +} +``` + +While correct, this is also inconvenient and confusing, since the `case` +suggests that the pattern match could fail. As a shorter and clearer alternative Scala 3 now allows + +```scala +xs.map { + (x, y) => x + y +} +``` + +or, equivalently: + +```scala +xs.map(_ + _) +``` +and +```scala +def combine(i: Int, j: Int) = i + j +xs.map(combine) +``` + +Generally, a function value with `n > 1` parameters is wrapped in a +function type of the form `((T_1, ..., T_n)) => U` if that is the expected type. +The tuple parameter is decomposed and its elements are passed directly to the underlying function. + +More specifically, the adaptation is applied to the mismatching formal +parameter list. In particular, the adaptation is not a conversion +between function types. That is why the following is not accepted: + +```scala +val combiner: (Int, Int) => Int = _ + _ +xs.map(combiner) // Type Mismatch +``` + +The function value must be explicitly tupled, rather than the parameters untupled: +```scala +xs.map(combiner.tupled) +``` + +A conversion may be provided in user code: + +```scala +import scala.language.implicitConversions +transparent inline implicit def `fallback untupling`(f: (Int, Int) => Int): ((Int, Int)) => Int = + p => f(p._1, p._2) // use specialized apply instead of unspecialized `tupled` +xs.map(combiner) +``` + +Parameter untupling is attempted before conversions are applied, so that a conversion in scope +cannot subvert untupling. + +## Reference + +For more information see: + +* [More details](./parameter-untupling-spec.md) +* [Issue #897](https://github.com/lampepfl/dotty/issues/897). diff --git a/docs/_spec/TODOreference/other-new-features/safe-initialization.md b/docs/_spec/TODOreference/other-new-features/safe-initialization.md new file mode 100644 index 000000000000..757038eac786 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/safe-initialization.md @@ -0,0 +1,343 @@ +--- +layout: doc-page +title: "Safe Initialization" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/safe-initialization.html +--- + +Scala 3 implements experimental safe initialization check, which can be enabled by the compiler option `-Ysafe-init`. + +The design and implementation of the initialization checker is described in the +paper _Safe object initialization, abstractly_ [3]. + +## A Quick Glance + +To get a feel of how it works, we first show several examples below. + +### Parent-Child Interaction + +Given the following code snippet: + +``` scala +abstract class AbstractFile: + def name: String + val extension: String = name.substring(4) + +class RemoteFile(url: String) extends AbstractFile: + val localFile: String = s"${url.##}.tmp" // error: usage of `localFile` before it's initialized + def name: String = localFile +``` + +The checker will report: + +``` scala +-- Warning: tests/init/neg/AbstractFile.scala:7:4 ------------------------------ +7 | val localFile: String = s"${url.##}.tmp" // error: usage of `localFile` before it's initialized + | ^ + | Access non-initialized field value localFile. Calling trace: + | -> val extension: String = name.substring(4) [ AbstractFile.scala:3 ] + | -> def name: String = localFile [ AbstractFile.scala:8 ] +``` + +### Inner-Outer Interaction + +Given the code below: + +``` scala +object Trees: + class ValDef { counter += 1 } + class EmptyValDef extends ValDef + val theEmptyValDef = new EmptyValDef + private var counter = 0 // error +``` + +The checker will report: + +``` scala +-- Warning: tests/init/neg/trees.scala:5:14 ------------------------------------ +5 | private var counter = 0 // error + | ^ + | Access non-initialized field variable counter. Calling trace: + | -> val theEmptyValDef = new EmptyValDef [ trees.scala:4 ] + | -> class EmptyValDef extends ValDef [ trees.scala:3 ] + | -> class ValDef { counter += 1 } [ trees.scala:2 ] +``` + +### Functions + +Given the code below: + +``` scala +abstract class Parent: + val f: () => String = () => this.message + def message: String + +class Child extends Parent: + val a = f() + val b = "hello" // error + def message: String = b +``` + +The checker reports: + +``` scala +-- Warning: tests/init/neg/features-high-order.scala:7:6 ----------------------- +7 | val b = "hello" // error + | ^ + |Access non-initialized field value b. Calling trace: + | -> val a = f() [ features-high-order.scala:6 ] + | -> val f: () => String = () => this.message [ features-high-order.scala:2 ] + | -> def message: String = b [ features-high-order.scala:8 ] +``` +## Design Goals + +We establish the following design goals: + +- __Sound__: checking always terminates, and is sound for common and reasonable usage (over-approximation) +- __Expressive__: support common and reasonable initialization patterns +- __Friendly__: simple rules, minimal syntactic overhead, informative error messages +- __Modular__: modular checking, no analysis beyond project boundary +- __Fast__: instant feedback +- __Simple__: no changes to core type system, explainable by a simple theory + +By _reasonable usage_, we include the following use cases (but not restricted to them): + +- Access fields on `this` and outer `this` during initialization +- Call methods on `this` and outer `this` during initialization +- Instantiate inner class and call methods on such instances during initialization +- Capture fields in functions + +## Principles + +To achieve the goals, we uphold the following fundamental principles: +_stackability_, _monotonicity_, _scopability_ and _authority_. + +Stackability means that all fields of a class are initialized at the end of the +class body. Scala enforces this property in syntax by demanding that all fields +are initialized at the end of the primary constructor, except for the language +feature below: + +``` scala +var x: T = _ +``` + +Control effects such as exceptions may break this property, as the +following example shows: + +``` scala +class MyException(val b: B) extends Exception("") +class A: + val b = try { new B } catch { case myEx: MyException => myEx.b } + println(b.a) + +class B: + throw new MyException(this) + val a: Int = 1 +``` + +In the code above, the control effect teleport the uninitialized value +wrapped in an exception. In the implementation, we avoid the problem +by ensuring that the values that are thrown must be transitively initialized. + +Monotonicity means that the initialization status of an object should +not go backward: initialized fields continue to be initialized, a +field points to an initialized object may not later point to an +object under initialization. As an example, the following code will be rejected: + +``` scala +trait Reporter: + def report(msg: String): Unit + +class FileReporter(ctx: Context) extends Reporter: + ctx.typer.reporter = this // ctx now reaches an uninitialized object + val file: File = new File("report.txt") + def report(msg: String) = file.write(msg) +``` + +In the code above, suppose `ctx` points to a transitively initialized +object. Now the assignment at line 3 makes `this`, which is not fully +initialized, reachable from `ctx`. This makes field usage dangerous, +as it may indirectly reach uninitialized fields. + +Monotonicity is based on a well-known technique called _heap monotonic +typestate_ to ensure soundness in the presence of aliasing +[1]. Roughly speaking, it means initialization state should not go backwards. + +Scopability means that there are no side channels to access to partially +constructed objects. Control effects like coroutines, delimited +control, resumable exceptions may break the property, as they can transport a +value upper in the stack (not in scope) to be reachable from the current scope. +Static fields can also serve as a teleport thus breaks this property. In the +implementation, we need to enforce that teleported values are transitively +initialized. + +The three principles above contribute to _local reasoning about initialization_, +which means: + +> An initialized environment can only produce initialized values. + +For example, if the arguments to an `new`-expression are transitively +initialized, so is the result. If the receiver and arguments in a method call +are transitively initialized, so is the result. + +Local reasoning about initialization gives rise to a fast initialization +checker, as it avoids whole-program analysis. + +The principle of authority goes hand-in-hand with monotonicity: the principle +of monotonicity stipulates that initialization states cannot go backwards, while +the principle of authority stipulates that the initialization states may not +go forward at arbitrary locations due to aliasing. In Scala, we may only +advance initialization states of objects in the class body when a field is +defined with a mandatory initializer or at local reasoning points when the object +becomes transitively initialized. + +## Abstract Values + +There are three fundamental abstractions for initialization states of objects: + +- __Cold__: A cold object may have uninitialized fields. +- __Warm__: A warm object has all its fields initialized but may reach _cold_ objects. +- __Hot__: A hot object is transitively initialized, i.e., it only reaches warm objects. + +In the initialization checker, the abstraction `Warm` is refined to handle inner +classes and multiple constructors: + +- __Warm[C] { outer = V, ctor, args = Vs }__: A warm object of class `C`, where the immediate outer of `C` is `V`, the constructor is `ctor` and constructor arguments are `Vs`. + +The initialization checker checks each concrete class separately. The abstraction `ThisRef` +represents the current object under initialization: + +- __ThisRef[C]__: The current object of class `C` under initialization. + +The initialization state of the current object is stored in the abstract heap as an +abstract object. The abstract heap also serves as a cache for the field values +of warm objects. `Warm` and `ThisRef` are "addresses" of the abstract objects stored +in the abstract heap. + +Two more abstractions are introduced to support functions and conditional +expressions: + +- __Fun(e, V, C)__: An abstract function value where `e` is the code, `V` is the + abstract value for `this` inside the function body and the function is located + inside the class `C`. + +- __Refset(Vs)__: A set of abstract values `Vs`. + +A value `v` is _effectively hot_ if any of the following is true: + +- `v` is `Hot`. +- `v` is `ThisRef` and all fields of the underlying object are assigned. +- `v` is `Warm[C] { ... }` and + 1. `C` does not contain inner classes; and + 2. Calling any method on `v` encounters no initialization errors and the method return value is _effectively hot_; and + 3. Each field of `v` is _effectively hot_. +- `v` is `Fun(e, V, C)` and calling the function encounters no errors and the + function return value is _effectively hot_. +- The root object (refered by `ThisRef`) is _effectively hot_. + +An effectively hot value can be regarded as transitively initialized thus can +be safely leaked via method arguments or as RHS of reassignment. +The initialization checker tries to promote non-hot values to effectively hot +whenenver possible. + +## Rules + +With the established principles and design goals, the following rules are imposed: + +1. The field access `e.f` or method call `e.m()` is illegal if `e` is _cold_. + + A cold value should not be used. + +2. The field access `e.f` is invalid if `e` has the value `ThisRef` and `f` is not initialized. + +3. In an assignment `o.x = e`, the expression `e` must be _effectively hot_. + + This is how monotonicity is enforced in the system. Note that in an + initialization `val f: T = e`, the expression `e` may point to a non-hot + value. + +4. Arguments to method calls must be _effectively hot_. + + Escape of `this` in the constructor is commonly regarded as an anti-pattern. + + However, passing non-hot values as argument to another constructor is allowed, to support + creation of cyclic data structures. The checker will ensure that the escaped + non-initialized object is not used, i.e. calling methods or accessing fields + on the escaped object is not allowed. + + An exception is for calling synthetic `apply`s of case classes. For example, + the method call `Some.apply(e)` will be interpreted as `new Some(e)`, thus + is valid even if `e` is not hot. + + Another exception to this rule is parametric method calls. For example, in + `List.apply(e)`, the argument `e` may be non-hot. If that is the case, the + result value of the parametric method call is taken as _cold_. + +5. Method calls on hot values with effectively hot arguments produce hot results. + + This rule is assured by local reasoning about initialization. + +6. Method calls on `ThisRef` and warm values will be resolved statically and the + corresponding method bodies are checked. + +7. In a new expression `new p.C(args)`, if the values of `p` and `args` are + effectively hot, then the result value is also hot. + + This is assured by local reasoning about initialization. + +8. In a new expression `new p.C(args)`, if any value of `p` and `args` is not + effectively hot, then the result value takes the form `Warm[C] { outer = Vp, args = Vargs }`. The initialization code for the class `C` is checked again to make + sure the non-hot values are used properly. + + In the above, `Vp` is the widened value of `p` --- the widening happens if `p` + is a warm value `Warm[D] { outer = V, args }` and we widen it to + `Warm[D] { outer = Cold, args }`. + + The variable `Vargs` represents values of `args` with non-hot values widened + to `Cold`. + + The motivation for the widening is to finitize the abstract domain and ensure + termination of the initialization check. + +9. The scrutinee in a pattern match and the values in return and throw statements must be _effectively hot_. + +## Modularity + +The analysis takes the primary constructor of concrete classes as entry points. +It follows the constructors of super classes, which might be defined in another project. +The analysis takes advantage of TASTy for analyzing super classes defined in another project. + +The crossing of project boundary raises a concern about modularity. It is +well-known in object-oriented programming that superclass and subclass are +tightly coupled. For example, adding a method in the superclass requires +recompiling the child class for checking safe overriding. + +Initialization is no exception in this respect. The initialization of an object +essentially involves close interaction between subclass and superclass. If the +superclass is defined in another project, the crossing of project boundary +cannot be avoided for soundness of the analysis. + +Meanwhile, inheritance across project boundary has been under scrutiny and the +introduction of [open classes](./open-classes.md) mitigate the concern here. +For example, the initialization check could enforce that the constructors of +open classes may not contain method calls on `this` or introduce annotations as +a contract. + +The feedback from the community on the topic is welcome. + +## Back Doors + +Occasionally you may want to suppress warnings reported by the +checker. You can either write `e: @unchecked` to tell the checker to +skip checking for the expression `e`, or you may use the old trick: +mark some fields as lazy. + +## Caveats + +- The system cannot provide safety guarantee when extending Java or Scala 2 classes. +- Safe initialization of global objects is only partially checked. + +## References + +1. Fähndrich, M. and Leino, K.R.M., 2003, July. [_Heap monotonic typestates_](https://www.microsoft.com/en-us/research/publication/heap-monotonic-typestate/). In International Workshop on Aliasing, Confinement and Ownership in object-oriented programming (IWACO). +2. Fengyun Liu, Ondřej Lhoták, Aggelos Biboudis, Paolo G. Giarrusso, and Martin Odersky. [_A type-and-effect system for object initialization_](https://dl.acm.org/doi/10.1145/3428243). OOPSLA, 2020. +3. Fengyun Liu, Ondřej Lhoták, Enze Xing, Nguyen Cao Pham. [_Safe object initialization, abstractly_](https://dl.acm.org/doi/10.1145/3486610.3486895). Scala 2021. diff --git a/docs/_spec/TODOreference/other-new-features/targetName.md b/docs/_spec/TODOreference/other-new-features/targetName.md new file mode 100644 index 000000000000..63c4cf1ec0df --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/targetName.md @@ -0,0 +1,118 @@ +--- +layout: doc-page +title: "The @targetName annotation" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/targetName.html +--- + +A [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotation on a definition defines an alternate name for the implementation of that definition. Example: + +```scala +import scala.annotation.targetName + +object VecOps: + extension [T](xs: Vec[T]) + @targetName("append") + def ++= [T] (ys: Vec[T]): Vec[T] = ... +``` + +Here, the `++=` operation is implemented (in Byte code or native code) under the name `append`. The implementation name affects the code that is generated, and is the name under which code from other languages can call the method. For instance, `++=` could be invoked from Java like this: + +```java +VecOps.append(vec1, vec2) +``` + +The [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotation has no bearing on Scala usages. Any application of that method in Scala has to use `++=`, not `append`. + +## Details + + 1. `@targetName` is defined in package `scala.annotation`. It takes a single argument + of type `String`. That string is called the _external name_ of the definition + that's annotated. + + 2. A `@targetName` annotation can be given for all kinds of definitions except a top-level `class`, `trait`, or `object`. + + 3. The name given in a [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotation must be a legal name + for the defined entities on the host platform. + + 4. It is recommended that definitions with symbolic names have a [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotation. This will establish an alternate name that is easier to search for and + will avoid cryptic encodings in runtime diagnostics. + + 5. Definitions with names in backticks that are not legal host platform names + should also have a [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotation. + +## Relationship with Overriding + +[`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotations are significant for matching two method definitions to decide whether they conflict or override each other. Two method definitions match if they have the same name, signature, and erased name. Here, + +- The _signature_ of a definition consists of the names of the erased types of all (value-) parameters and the method's result type. +- The _erased name_ of a method definition is its target name if a [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotation is given and its defined name otherwise. + +This means that `@targetName` annotations can be used to disambiguate two method definitions that would otherwise clash. For instance. + +```scala +def f(x: => String): Int = x.length +def f(x: => Int): Int = x + 1 // error: double definition +``` + +The two definitions above clash since their erased parameter types are both [`Function0`](https://scala-lang.org/api/3.x/scala/Function0.html), which is the type of the translation of a by-name-parameter. Hence they have the same names and signatures. But we can avoid the clash by adding a [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotation to either method or to both of them. Example: + +```scala +@targetName("f_string") +def f(x: => String): Int = x.length +def f(x: => Int): Int = x + 1 // OK +``` + +This will produce methods `f_string` and `f` in the generated code. + +However, [`@targetName`](https://scala-lang.org/api/3.x/scala/annotation/targetName.html) annotations are not allowed to break overriding relationships +between two definitions that have otherwise the same names and types. So the following would be in error: + +```scala +import annotation.targetName +class A: + def f(): Int = 1 +class B extends A: + @targetName("g") def f(): Int = 2 +``` + +The compiler reports here: + +``` +-- Error: test.scala:6:23 ------------------------------------------------------ +6 | @targetName("g") def f(): Int = 2 + | ^ + |error overriding method f in class A of type (): Int; + | method f of type (): Int should not have a @targetName + | annotation since the overridden member hasn't one either +``` + +The relevant overriding rules can be summarized as follows: + +- Two members can override each other if their names and signatures are the same, + and they either have the same erased names or the same types. +- If two members override, then both their erased names and their types must be the same. + +As usual, any overriding relationship in the generated code must also +be present in the original code. So the following example would also be in error: + +```scala +import annotation.targetName +class A: + def f(): Int = 1 +class B extends A: + @targetName("f") def g(): Int = 2 +``` + +Here, the original methods `g` and `f` do not override each other since they have +different names. But once we switch to target names, there is a clash that is reported by the compiler: + +``` +-- [E120] Naming Error: test.scala:4:6 ----------------------------------------- +4 |class B extends A: + | ^ + | Name clash between defined and inherited member: + | def f(): Int in class A at line 3 and + | def g(): Int in class B at line 5 + | have the same name and type after erasure. +1 error found +``` diff --git a/docs/_spec/TODOreference/other-new-features/threadUnsafe-annotation.md b/docs/_spec/TODOreference/other-new-features/threadUnsafe-annotation.md new file mode 100644 index 000000000000..ae1af1e4b671 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/threadUnsafe-annotation.md @@ -0,0 +1,18 @@ +--- +layout: doc-page +title: "The @threadUnsafe annotation" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/threadUnsafe-annotation.html +--- + +A new annotation [`@threadUnsafe`](https://scala-lang.org/api/3.x/scala/annotation/threadUnsafe.html) can be used on a field which defines +a `lazy val`. When this annotation is used, the initialization of the +[`lazy val`](../changed-features/lazy-vals-init.md) will use a faster mechanism which is not thread-safe. + +## Example + +```scala +import scala.annotation.threadUnsafe + +class Hello: + @threadUnsafe lazy val x: Int = 1 +``` diff --git a/docs/_spec/TODOreference/other-new-features/trait-parameters.md b/docs/_spec/TODOreference/other-new-features/trait-parameters.md new file mode 100644 index 000000000000..c704e73ce9b8 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/trait-parameters.md @@ -0,0 +1,88 @@ +--- +layout: doc-page +title: "Trait Parameters" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/trait-parameters.html +--- + +Scala 3 allows traits to have parameters, just like classes have parameters. + +```scala +trait Greeting(val name: String): + def msg = s"How are you, $name" + +class C extends Greeting("Bob"): + println(msg) +``` + +Arguments to a trait are evaluated immediately before the trait is initialized. + +One potential issue with trait parameters is how to prevent +ambiguities. For instance, you might try to extend `Greeting` twice, +with different parameters. + +```scala +class D extends C, Greeting("Bill") // error: parameter passed twice +``` + +Should this print "Bob" or "Bill"? In fact this program is illegal, +because it violates the second rule of the following for trait parameters: + + 1. If a class `C` extends a parameterized trait `T`, and its superclass does not, `C` _must_ pass arguments to `T`. + + 2. If a class `C` extends a parameterized trait `T`, and its superclass does as well, `C` _must not_ pass arguments to `T`. + + 3. Traits must never pass arguments to parent traits. + +Here's a trait extending the parameterized trait `Greeting`. + +```scala +trait FormalGreeting extends Greeting: + override def msg = s"How do you do, $name" +``` +As is required, no arguments are passed to `Greeting`. However, this poses an issue +when defining a class that extends `FormalGreeting`: + +```scala +class E extends FormalGreeting // error: missing arguments for `Greeting`. +``` + +The correct way to write `E` is to extend both `Greeting` and +`FormalGreeting` (in either order): + +```scala +class E extends Greeting("Bob"), FormalGreeting +``` + +## Traits With Context Parameters + +This "explicit extension required" rule is relaxed if the missing trait contains only +[context parameters](../contextual/using-clauses.md). In that case the trait reference is +implicitly inserted as an additional parent with inferred arguments. For instance, +here's a variant of greetings where the addressee is a context parameter of type +`ImpliedName`: + +```scala +case class ImpliedName(name: String): + override def toString = name + +trait ImpliedGreeting(using val iname: ImpliedName): + def msg = s"How are you, $iname" + +trait ImpliedFormalGreeting extends ImpliedGreeting: + override def msg = s"How do you do, $iname" + +class F(using iname: ImpliedName) extends ImpliedFormalGreeting +``` + +The definition of `F` in the last line is implicitly expanded to +```scala +class F(using iname: ImpliedName) extends + Object, + ImpliedGreeting(using iname), + ImpliedFormalGreeting(using iname) +``` +Note the inserted reference to the super trait `ImpliedGreeting`, which was not mentioned explicitly. + +## Reference + +For more information, see [Scala SIP 25](http://docs.scala-lang.org/sips/pending/trait-parameters.html). diff --git a/docs/_spec/TODOreference/other-new-features/transparent-traits.md b/docs/_spec/TODOreference/other-new-features/transparent-traits.md new file mode 100644 index 000000000000..699ce0b9ddd8 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/transparent-traits.md @@ -0,0 +1,70 @@ +--- +layout: doc-page +title: "Transparent Traits" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/transparent-traits.html +--- + +Traits are used in two roles: + + 1. As mixins for other classes and traits + 2. As types of vals, defs, or parameters + +Some traits are used primarily in the first role, and we usually do not want to see them in inferred types. An example is the [`Product`](https://scala-lang.org/api/3.x/scala/Product.html) trait that the compiler adds as a mixin trait to every case class or case object. In Scala 2, this parent trait sometimes makes inferred types more complicated than they should be. Example: + +```scala +trait Kind +case object Var extends Kind +case object Val extends Kind +val x = Set(if condition then Val else Var) +``` + +Here, the inferred type of `x` is `Set[Kind & Product & Serializable]` whereas one would have hoped it to be `Set[Kind]`. The reasoning for this particular type to be inferred is as follows: + +- The type of the conditional above is the [union type](../new-types/union-types.md) `Val | Var`. +- A union type is widened in type inference to the least supertype that is not a union type. + In the example, this type is `Kind & Product & Serializable` since all three traits are traits of both `Val` and `Var`. + So that type becomes the inferred element type of the set. + +Scala 3 allows one to mark a mixin trait as `transparent`, which means that it can be suppressed in type inference. Here's an example that follows the lines of the code above, but now with a new transparent trait `S` instead of `Product`: + +```scala +transparent trait S +trait Kind +object Var extends Kind, S +object Val extends Kind, S +val x = Set(if condition then Val else Var) +``` + +Now `x` has inferred type `Set[Kind]`. The common transparent trait `S` does not +appear in the inferred type. + +## Transparent Traits + +The traits [`scala.Product`](https://scala-lang.org/api/3.x/scala/Product.html), [`java.io.Serializable`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/Serializable.html) and [`java.lang.Comparable`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Comparable.html) +are treated automatically as transparent. Other traits are turned into transparent traits using the modifier `transparent`. Scala 2 traits can also be made transparent +by adding a [`@transparentTrait`](https://scala-lang.org/api/3.x/scala/annotation/transparentTrait.html) annotation. This annotation is defined in [`scala.annotation`](https://scala-lang.org/api/3.x/scala/annotation.html). It will be deprecated and phased out once Scala 2/3 interoperability is no longer needed. + +Typically, transparent traits are traits +that influence the implementation of inheriting classes and traits that are not usually used as types by themselves. Two examples from the standard collection library are: + +- [`IterableOps`](https://scala-lang.org/api/3.x/scala/collection/IterableOps.html), which provides method implementations for an [`Iterable`](https://scala-lang.org/api/3.x/scala/collection/Iterable.html). +- [`StrictOptimizedSeqOps`](https://scala-lang.org/api/3.x/scala/collection/StrictOptimizedSeqOps.html), which optimises some of these implementations for sequences with efficient indexing. + +Generally, any trait that is extended recursively is a good candidate to be +declared transparent. + +## Rules for Inference + +Transparent traits can be given as explicit types as usual. But they are often elided when types are inferred. Roughly, the rules for type inference say that transparent traits are dropped from intersections where possible. + +The precise rules are as follows: + +- When inferring a type of a type variable, or the type of a val, or the return type of a def, +- where that type is not higher-kinded, +- and where `B` is its known upper bound or `Any` if none exists: +- If the type inferred so far is of the form `T1 & ... & Tn` where + `n >= 1`, replace the maximal number of transparent `Ti`s by `Any`, while ensuring that + the resulting type is still a subtype of the bound `B`. +- However, do not perform this widening if all transparent traits `Ti` can get replaced in that way. + +The last clause ensures that a single transparent trait instance such as [`Product`](https://scala-lang.org/api/3.x/scala/Product.html) is not widened to [`Any`](https://scala-lang.org/api/3.x/scala/Any.html). Transparent trait instances are only dropped when they appear in conjunction with some other type. diff --git a/docs/_spec/TODOreference/other-new-features/type-test.md b/docs/_spec/TODOreference/other-new-features/type-test.md new file mode 100644 index 000000000000..ec7a87230753 --- /dev/null +++ b/docs/_spec/TODOreference/other-new-features/type-test.md @@ -0,0 +1,181 @@ +--- +layout: doc-page +title: "TypeTest" +nightlyOf: https://docs.scala-lang.org/scala3/reference/other-new-features/type-test.html +--- + +## TypeTest + +When pattern matching there are two situations where a runtime type test must be performed. +The first case is an explicit type test using the ascription pattern notation. + +```scala +(x: X) match + case y: Y => +``` + +The second case is when an extractor takes an argument that is not a subtype of the scrutinee type. + +```scala +(x: X) match + case y @ Y(n) => + +object Y: + def unapply(x: Y): Some[Int] = ... +``` + +In both cases, a class test will be performed at runtime. +But when the type test is on an abstract type (type parameter or type member), the test cannot be performed because the type is erased at runtime. + +A [`TypeTest`](https://scala-lang.org/api/3.x/scala/reflect/TypeTest.html) can be provided to make this test possible. + +```scala +package scala.reflect + +trait TypeTest[-S, T]: + def unapply(s: S): Option[s.type & T] +``` + +It provides an extractor that returns its argument typed as a `T` if the argument is a `T`. +It can be used to encode a type test. + +```scala +def f[X, Y](x: X)(using tt: TypeTest[X, Y]): Option[Y] = x match + case tt(x @ Y(1)) => Some(x) + case tt(x) => Some(x) + case _ => None +``` + +To avoid the syntactic overhead the compiler will look for a type test automatically if it detects that the type test is on abstract types. +This means that `x: Y` is transformed to `tt(x)` and `x @ Y(_)` to `tt(x @ Y(_))` if there is a contextual `TypeTest[X, Y]` in scope. +The previous code is equivalent to + +```scala +def f[X, Y](x: X)(using TypeTest[X, Y]): Option[Y] = x match + case x @ Y(1) => Some(x) + case x: Y => Some(x) + case _ => None +``` + +We could create a type test at call site where the type test can be performed with runtime class tests directly as follows + +```scala +val tt: TypeTest[Any, String] = + new TypeTest[Any, String]: + def unapply(s: Any): Option[s.type & String] = s match + case s: String => Some(s) + case _ => None + +f[AnyRef, String]("acb")(using tt) +``` + +The compiler will synthesize a new instance of a type test if none is found in scope as: + +```scala +new TypeTest[A, B]: + def unapply(s: A): Option[s.type & B] = s match + case s: B => Some(s) + case _ => None +``` + +If the type tests cannot be done there will be an unchecked warning that will be raised on the `case s: B =>` test. + +The most common [`TypeTest`](https://scala-lang.org/api/3.x/scala/reflect/TypeTest.html) instances are the ones that take any parameters (i.e. `TypeTest[Any, T]`). +To make it possible to use such instances directly in context bounds we provide the alias + +```scala +package scala.reflect + +type Typeable[T] = TypeTest[Any, T] +``` + +This alias can be used as + +```scala +def f[T: Typeable]: Boolean = + "abc" match + case x: T => true + case _ => false + +f[String] // true +f[Int] // false +``` + +## TypeTest and ClassTag + +[`TypeTest`](https://scala-lang.org/api/3.x/scala/reflect/TypeTest.html) is a replacement for functionality provided previously by `ClassTag.unapply`. +Using [`ClassTag`](https://scala-lang.org/api/3.x/scala/reflect/ClassTag.html) instances was unsound since classtags can check only the class component of a type. +[`TypeTest`](https://scala-lang.org/api/3.x/scala/reflect/TypeTest.html) fixes that unsoundness. +[`ClassTag`](https://scala-lang.org/api/3.x/scala/reflect/ClassTag.html) type tests are still supported but a warning will be emitted after 3.0. + + +## Example + +Given the following abstract definition of Peano numbers that provides two given instances of types `TypeTest[Nat, Zero]` and `TypeTest[Nat, Succ]` + +```scala +import scala.reflect.* + +trait Peano: + type Nat + type Zero <: Nat + type Succ <: Nat + + def safeDiv(m: Nat, n: Succ): (Nat, Nat) + + val Zero: Zero + + val Succ: SuccExtractor + trait SuccExtractor: + def apply(nat: Nat): Succ + def unapply(succ: Succ): Some[Nat] + + given typeTestOfZero: TypeTest[Nat, Zero] + given typeTestOfSucc: TypeTest[Nat, Succ] +``` + +together with an implementation of Peano numbers based on type `Int` + +```scala +object PeanoInt extends Peano: + type Nat = Int + type Zero = Int + type Succ = Int + + def safeDiv(m: Nat, n: Succ): (Nat, Nat) = (m / n, m % n) + + val Zero: Zero = 0 + + val Succ: SuccExtractor = new: + def apply(nat: Nat): Succ = nat + 1 + def unapply(succ: Succ) = Some(succ - 1) + + def typeTestOfZero: TypeTest[Nat, Zero] = new: + def unapply(x: Nat): Option[x.type & Zero] = + if x == 0 then Some(x) else None + + def typeTestOfSucc: TypeTest[Nat, Succ] = new: + def unapply(x: Nat): Option[x.type & Succ] = + if x > 0 then Some(x) else None +``` + +it is possible to write the following program + +```scala +@main def test = + import PeanoInt.* + + def divOpt(m: Nat, n: Nat): Option[(Nat, Nat)] = + n match + case Zero => None + case s @ Succ(_) => Some(safeDiv(m, s)) + + val two = Succ(Succ(Zero)) + val five = Succ(Succ(Succ(two))) + + println(divOpt(five, two)) // prints "Some((2,1))" + println(divOpt(two, five)) // prints "Some((0,2))" + println(divOpt(two, Zero)) // prints "None" +``` + +Note that without the `TypeTest[Nat, Succ]` the pattern `Succ.unapply(nat: Succ)` would be unchecked. diff --git a/docs/_spec/TODOreference/overview.md b/docs/_spec/TODOreference/overview.md new file mode 100644 index 000000000000..b1e8281dfc16 --- /dev/null +++ b/docs/_spec/TODOreference/overview.md @@ -0,0 +1,155 @@ +--- +layout: doc-page +title: "Reference" +nightlyOf: https://docs.scala-lang.org/scala3/reference/overview.html +redirectFrom: overview.html +--- + +Scala 3 implements many language changes and improvements over Scala 2. +In this reference, we discuss design decisions and present important differences compared to Scala 2. + +## Goals + +The language redesign was guided by three main goals: + +- Strengthen Scala's foundations. + Make the full programming language compatible with the foundational work on the + [DOT calculus](https://infoscience.epfl.ch/record/227176/files/soundness_oopsla16.pdf) + and apply the lessons learned from that work. +- Make Scala easier and safer to use. + Tame powerful constructs such as implicits to provide a gentler learning curve. Remove warts and puzzlers. +- Further improve the consistency and expressiveness of Scala's language constructs. + +Corresponding to these goals, the language changes fall into seven categories: +(1) Core constructs to strengthen foundations, (2) simplifications and (3) [restrictions](#restrictions), to make the language easier and safer to use, (4) [dropped constructs](#dropped-constructs) to make the language smaller and more regular, (5) [changed constructs](#changes) to remove warts, and increase consistency and usability, (6) [new constructs](#new-constructs) to fill gaps and increase expressiveness, (7) a new, principled approach to metaprogramming that replaces [Scala 2 experimental macros](https://docs.scala-lang.org/overviews/macros/overview.html). + +## Essential Foundations + +These new constructs directly model core features of DOT, higher-kinded types, and the [SI calculus for implicit resolution](https://infoscience.epfl.ch/record/229878/files/simplicitly_1.pdf). + +- [Intersection types](new-types/intersection-types.md), replacing compound types, +- [Union types](new-types/union-types.md), +- [Type lambdas](new-types/type-lambdas.md), replacing encodings using structural types and type projection. +- [Context functions](contextual/context-functions.md), offering abstraction over given parameters. + +## Simplifications + +These constructs replace existing constructs with the aim of making the language safer and simpler to use, and to promote uniformity in code style. + +- [Trait parameters](other-new-features/trait-parameters.md) + replace [early initializers](dropped-features/early-initializers.md) with a more generally useful construct. +- [Given instances](contextual/givens.md) + replace implicit objects and defs, focussing on intent over mechanism. +- [Using clauses](contextual/using-clauses.md) + replace implicit parameters, avoiding their ambiguities. +- [Extension methods](contextual/extension-methods.md) + replace implicit classes with a clearer and simpler mechanism. +- [Opaque type aliases](other-new-features/opaques.md) + replace most uses of value classes while guaranteeing the absence of boxing. +- [Top-level definitions](dropped-features/package-objects.md) + replace package objects, dropping syntactic boilerplate. +- [Export clauses](other-new-features/export.md) + provide a simple and general way to express aggregation, which can replace + the previous facade pattern of package objects inheriting from classes. +- [Vararg splices](changed-features/vararg-splices.md) + now use the form `xs*` in function arguments and patterns instead of `xs: _*` and `xs @ _*`, +- [Universal apply methods](other-new-features/creator-applications.md) + allow using simple function call syntax instead of `new` expressions. `new` expressions stay around + as a fallback for the cases where creator applications cannot be used. + +With the exception of [early initializers](dropped-features/early-initializers.md) and old-style vararg patterns, all superseded constructs continue to be available in Scala 3.0. The plan is to deprecate and phase them out later. + +Value classes (superseded by opaque type aliases) are a special case. There are currently no deprecation plans for value classes, since we might bring them back in a more general form if they are supported natively by the JVM as is planned by [project Valhalla](https://openjdk.java.net/projects/valhalla/). + +## Restrictions + +These constructs are restricted to make the language safer. + +- [Implicit Conversions](contextual/conversions.md): + there is only one way to define implicit conversions instead of many, and potentially surprising implicit conversions require a language import. +- [Given Imports](contextual/given-imports.md): + implicits now require a special form of import, to make the import clearly visible. +- [Type Projection](dropped-features/type-projection.md): + only classes can be used as prefix `C` of a type projection `C#A`. Type projection on abstract types is no longer supported since it is unsound. +- [Multiversal Equality](contextual/multiversal-equality.md): + implement an "opt-in" scheme to rule out nonsensical comparisons with `==` and `!=`. +- [infix](changed-features/operators.md): + make method application syntax uniform across code bases. + +Unrestricted implicit conversions continue to be available in Scala 3.0, but will be deprecated and removed later. Unrestricted versions of the other constructs in the list above are available only under `-source 3.0-migration`. + +## Dropped Constructs + +These constructs are proposed to be dropped without a new construct replacing them. The motivation for dropping these constructs is to simplify the language and its implementation. + +- [DelayedInit](dropped-features/delayed-init.md), +- [Existential types](dropped-features/existential-types.md), +- [Procedure syntax](dropped-features/procedure-syntax.md), +- [Class shadowing](dropped-features/class-shadowing.md), +- [XML literals](dropped-features/xml.md), +- [Symbol literals](dropped-features/symlits.md), +- [Auto application](dropped-features/auto-apply.md), +- [Weak conformance](dropped-features/weak-conformance.md), +- Compound types (replaced by [Intersection types](new-types/intersection-types.md)), +- [Auto tupling](https://github.com/lampepfl/dotty/pull/4311) (implemented, but not merged). + +The date when these constructs are dropped varies. The current status is: + +- Not implemented at all: + - DelayedInit, existential types, weak conformance. +- Supported under `-source 3.0-migration`: + - procedure syntax, class shadowing, symbol literals, auto application, auto tupling in a restricted form. +- Supported in 3.0, to be deprecated and phased out later: + - [XML literals](dropped-features/xml.md), compound types. + +## Changes + +These constructs have undergone changes to make them more regular and useful. + +- [Structural Types](changed-features/structural-types.md): + They now allow pluggable implementations, which greatly increases their usefulness. Some usage patterns are restricted compared to the status quo. +- [Name-based pattern matching](changed-features/pattern-matching.md): + The existing undocumented Scala 2 implementation has been codified in a slightly simplified form. +- [Automatic Eta expansion](changed-features/eta-expansion.md): + Eta expansion is now performed universally also in the absence of an expected type. The postfix `_` operator is thus made redundant. It will be deprecated and dropped after Scala 3.0. +- [Implicit Resolution](changed-features/implicit-resolution.md): + The implicit resolution rules have been cleaned up to make them more useful and less surprising. Implicit scope is restricted to no longer include package prefixes. + +Most aspects of old-style implicit resolution are still available under `-source 3.0-migration`. The other changes in this list are applied unconditionally. + +## New Constructs + +These are additions to the language that make it more powerful or pleasant to use. + +- [Enums](enums/enums.md) provide concise syntax for enumerations and [algebraic data types](enums/adts.md). +- [Parameter untupling](other-new-features/parameter-untupling.md) avoids having to use `case` for tupled parameter destructuring. +- [Dependent function types](new-types/dependent-function-types.md) generalize dependent methods to dependent function values and types. +- [Polymorphic function types](new-types/polymorphic-function-types.md) generalize polymorphic methods to polymorphic function values and types. + _Current status_: There is a proposal and a merged prototype implementation, but the implementation has not been finalized (it is notably missing type inference support). +- [Kind polymorphism](other-new-features/kind-polymorphism.md) allows the definition of operators working equally on types and type constructors. +- [`@targetName` annotations](other-new-features/targetName.md) make it easier to interoperate with code written in other languages and give more flexibility for avoiding name clashes. + +## Metaprogramming + +The following constructs together aim to put metaprogramming in Scala on a new basis. So far, metaprogramming was achieved by a combination of macros and libraries such as [Shapeless](https://github.com/milessabin/shapeless) that were in turn based on some key macros. Current Scala 2 macro mechanisms are a thin veneer on top of the current Scala 2 compiler, which makes them fragile and in many cases impossible to port to Scala 3. + +It's worth noting that macros were never included in the [Scala 2 language specification](https://scala-lang.org/files/archive/spec/2.13/) and were so far made available only under an `-experimental` flag. This has not prevented their widespread usage. + +To enable porting most uses of macros, we are experimenting with the advanced language constructs listed below. These designs are more provisional than the rest of the proposed language constructs for Scala 3.0. There might still be some changes until the final release. Stabilizing the feature set needed for metaprogramming is our first priority. + +- [Match Types](new-types/match-types.md) + allow computation on types. +- [Inline](metaprogramming/inline.md) + provides by itself a straightforward implementation of some simple macros and is at the same time an essential building block for the implementation of complex macros. +- [Quotes and Splices](metaprogramming/macros.md) + provide a principled way to express macros and staging with a unified set of abstractions. +- [Type class derivation](contextual/derivation.md) + provides an in-language implementation of the `Gen` macro in Shapeless and other foundational libraries. The new implementation is more robust, efficient and easier to use than the macro. +- [By-name context parameters](contextual/by-name-context-parameters.md) + provide a more robust in-language implementation of the `Lazy` macro in [Shapeless](https://github.com/milessabin/shapeless). + +## See Also + +[A classification of proposed language features](./features-classification.md) is +an expanded version of this page that adds the status (i.e. relative importance to be a part of Scala 3, and relative urgency when to decide this) and expected migration cost +of each language construct. diff --git a/docs/_spec/TODOreference/soft-modifier.md b/docs/_spec/TODOreference/soft-modifier.md new file mode 100644 index 000000000000..c1329ebab1f0 --- /dev/null +++ b/docs/_spec/TODOreference/soft-modifier.md @@ -0,0 +1,27 @@ +--- +layout: doc-page +title: "Soft Keywords" +nightlyOf: https://docs.scala-lang.org/scala3/reference/soft-modifier.html +--- + +A soft modifier is one of the identifiers `infix`, `inline`, `opaque`, `open` and `transparent`. + +A soft keyword is a soft modifier, or one of `as`, `derives`, `end`, `extension`, `throws`, `using`, `|`, `+`, `-`, `*` + +A soft modifier is treated as potential modifier of a definition if it is followed by a hard modifier or a keyword combination starting a definition (`def`, `val`, `var`, `type`, `given`, `class`, `trait`, `object`, `enum`, `case class`, `case object`). Between the two words there may be a sequence of newline tokens and soft modifiers. + +Otherwise, soft keywords are treated specially in the following situations: + + - `inline`, if it is followed by any token that can start an expression. + - `derives`, if it appears after an extension clause or after + the name and possibly parameters of a class, trait, object, or enum definition. + - `end`, if it appears at the start of a line following a statement (i.e. definition or toplevel expression) + - `extension`, if it appears at the start of a statement and is followed by `(` or `[`. + - `using`, if it appears at the start of a parameter or argument list. + - `as`, in a renaming import clause + - `|`, if it separates two patterns in an alternative. + - `+`, `-`, if they appear in front of a type parameter. + - `*`, in a wildcard import, or it follows the type of a parameter, or if it appears in + a vararg splice `x*`. + +Everywhere else a soft keyword is treated as a normal identifier. diff --git a/docs/_spec/TODOreference/syntax.md b/docs/_spec/TODOreference/syntax.md new file mode 100644 index 000000000000..e11629c8eaf9 --- /dev/null +++ b/docs/_spec/TODOreference/syntax.md @@ -0,0 +1,472 @@ +--- +layout: doc-page +title: "Scala 3 Syntax Summary" +nightlyOf: https://docs.scala-lang.org/scala3/reference/syntax.html +--- + + + +The following description of Scala tokens uses literal characters `‘c’` when +referring to the ASCII fragment `\u0000` – `\u007F`. + +_Unicode escapes_ are used to represent the [Unicode character](https://www.w3.org/International/articles/definitions-characters/) with the given +hexadecimal code: + +``` +UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit +hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ +``` + +Informal descriptions are typeset as `“some comment”`. + +## Lexical Syntax + +The lexical syntax of Scala is given by the following grammar in EBNF +form. + +``` +whiteSpace ::= ‘\u0020’ | ‘\u0009’ | ‘\u000D’ | ‘\u000A’ +upper ::= ‘A’ | … | ‘Z’ | ‘\$’ | ‘_’ “… and Unicode category Lu” +lower ::= ‘a’ | … | ‘z’ “… and Unicode category Ll” +letter ::= upper | lower “… and Unicode categories Lo, Lt, Nl” +digit ::= ‘0’ | … | ‘9’ +paren ::= ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ +delim ::= ‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ +opchar ::= ‘!’ | ‘#’ | ‘%’ | ‘&’ | ‘*’ | ‘+’ | ‘-’ | ‘/’ | ‘:’ | + ‘<’ | ‘=’ | ‘>’ | ‘?’ | ‘@’ | ‘\’ | ‘^’ | ‘|’ | ‘~’ + “… and Unicode categories Sm, So” +printableChar ::= “all characters in [\u0020, \u007E] inclusive” +charEscapeSeq ::= ‘\’ (‘b’ | ‘t’ | ‘n’ | ‘f’ | ‘r’ | ‘"’ | ‘'’ | ‘\’) + +op ::= opchar {opchar} +varid ::= lower idrest +alphaid ::= upper idrest + | varid +plainid ::= alphaid + | op +id ::= plainid + | ‘`’ { charNoBackQuoteOrNewline | UnicodeEscape | charEscapeSeq } ‘`’ +idrest ::= {letter | digit} [‘_’ op] +quoteId ::= ‘'’ alphaid +spliceId ::= ‘$’ alphaid ; + +integerLiteral ::= (decimalNumeral | hexNumeral) [‘L’ | ‘l’] +decimalNumeral ::= ‘0’ | nonZeroDigit [{digit | ‘_’} digit] +hexNumeral ::= ‘0’ (‘x’ | ‘X’) hexDigit [{hexDigit | ‘_’} hexDigit] +nonZeroDigit ::= ‘1’ | … | ‘9’ + +floatingPointLiteral + ::= [decimalNumeral] ‘.’ digit [{digit | ‘_’} digit] [exponentPart] [floatType] + | decimalNumeral exponentPart [floatType] + | decimalNumeral floatType +exponentPart ::= (‘E’ | ‘e’) [‘+’ | ‘-’] digit [{digit | ‘_’} digit] +floatType ::= ‘F’ | ‘f’ | ‘D’ | ‘d’ + +booleanLiteral ::= ‘true’ | ‘false’ + +characterLiteral ::= ‘'’ (printableChar | charEscapeSeq) ‘'’ + +stringLiteral ::= ‘"’ {stringElement} ‘"’ + | ‘"""’ multiLineChars ‘"""’ +stringElement ::= printableChar \ (‘"’ | ‘\’) + | UnicodeEscape + | charEscapeSeq +multiLineChars ::= {[‘"’] [‘"’] char \ ‘"’} {‘"’} +processedStringLiteral + ::= alphaid ‘"’ {[‘\’] processedStringPart | ‘\\’ | ‘\"’} ‘"’ + | alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘$’) | escape} {‘"’} ‘"""’ +processedStringPart + ::= printableChar \ (‘"’ | ‘$’ | ‘\’) | escape +escape ::= ‘$$’ + | ‘$’ letter { letter | digit } + | ‘{’ Block [‘;’ whiteSpace stringFormat whiteSpace] ‘}’ +stringFormat ::= {printableChar \ (‘"’ | ‘}’ | ‘ ’ | ‘\t’ | ‘\n’)} + +symbolLiteral ::= ‘'’ plainid // until 2.13 + +comment ::= ‘/*’ “any sequence of characters; nested comments are allowed” ‘*/’ + | ‘//’ “any sequence of characters up to end of line” + +nl ::= “new line character” +semi ::= ‘;’ | nl {nl} +``` + +## Optional Braces + +The lexical analyzer also inserts `indent` and `outdent` tokens that represent regions of indented code [at certain points](./other-new-features/indentation.md). + +In the context-free productions below we use the notation `<<< ts >>>` +to indicate a token sequence `ts` that is either enclosed in a pair of braces `{ ts }` or that constitutes an indented region `indent ts outdent`. Analogously, the +notation `:<<< ts >>>` indicates a token sequence `ts` that is either enclosed in a pair of braces `{ ts }` or that constitutes an indented region `indent ts outdent` that follows +a `colon` token. + +A `colon` token reads as the standard colon "`:`" but is generated instead of it where `colon` is legal according to the context free syntax, but only if the previous token +is an alphanumeric identifier, a backticked identifier, or one of the tokens `this`, `super`, `new`, "`)`", and "`]`". + +``` +colon ::= ':' -- with side conditions explained above + <<< ts >>> ::= ‘{’ ts ‘}’ + | indent ts outdent +:<<< ts >>> ::= [nl] ‘{’ ts ‘}’ + | colon indent ts outdent +``` + +## Keywords + +### Regular keywords + +``` +abstract case catch class def do else +enum export extends false final finally for +given if implicit import lazy match new +null object override package private protected return +sealed super then throw trait true try +type val var while with yield +: = <- => <: >: # +@ =>> ?=> +``` + +### Soft keywords + +``` +as derives end extension infix inline opaque open transparent using | * + - +``` + +See the [separate section on soft keywords](./soft-modifier.md) for additional +details on where a soft keyword is recognized. + +## Context-free Syntax + +The context-free syntax of Scala is given by the following EBNF +grammar: + +### Literals and Paths +``` +SimpleLiteral ::= [‘-’] integerLiteral + | [‘-’] floatingPointLiteral + | booleanLiteral + | characterLiteral + | stringLiteral +Literal ::= SimpleLiteral + | processedStringLiteral + | symbolLiteral + | ‘null’ + +QualId ::= id {‘.’ id} +ids ::= id {‘,’ id} + +SimpleRef ::= id + | [id ‘.’] ‘this’ + | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id + +ClassQualifier ::= ‘[’ id ‘]’ +``` + +### Types +``` +Type ::= FunType + | HkTypeParamClause ‘=>>’ Type + | FunParamClause ‘=>>’ Type + | MatchType + | InfixType +FunType ::= FunTypeArgs (‘=>’ | ‘?=>’) Type + | HKTypeParamClause '=>' Type +FunTypeArgs ::= InfixType + | ‘(’ [ FunArgTypes ] ‘)’ + | FunParamClause +FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’ +TypedFunParam ::= id ‘:’ Type +MatchType ::= InfixType `match` <<< TypeCaseClauses >>> +InfixType ::= RefinedType {id [nl] RefinedType} +RefinedType ::= AnnotType {[nl] Refinement} +AnnotType ::= SimpleType {Annotation} + +SimpleType ::= SimpleLiteral + | ‘?’ TypeBounds + | id + | Singleton ‘.’ id + | Singleton ‘.’ ‘type’ + | ‘(’ Types ‘)’ + | Refinement + | SimpleType1 TypeArgs + | SimpleType1 ‘#’ id +Singleton ::= SimpleRef + | SimpleLiteral + | Singleton ‘.’ id + +FunArgType ::= Type + | ‘=>’ Type +FunArgTypes ::= FunArgType { ‘,’ FunArgType } +ParamType ::= [‘=>’] ParamValueType +ParamValueType ::= Type [‘*’] +TypeArgs ::= ‘[’ Types ‘]’ +Refinement ::= :<<< [RefineDcl] {semi [RefineDcl]} >>> +TypeBounds ::= [‘>:’ Type] [‘<:’ Type] +TypeParamBounds ::= TypeBounds {‘:’ Type} +Types ::= Type {‘,’ Type} +``` + +### Expressions +``` +Expr ::= FunParams (‘=>’ | ‘?=>’) Expr + | HkTypeParamClause ‘=>’ Expr + | Expr1 +BlockResult ::= FunParams (‘=>’ | ‘?=>’) Block + | HkTypeParamClause ‘=>’ Block + | Expr1 +FunParams ::= Bindings + | id + | ‘_’ +Expr1 ::= [‘inline’] ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] + | [‘inline’] ‘if’ Expr ‘then’ Expr [[semi] ‘else’ Expr] + | ‘while’ ‘(’ Expr ‘)’ {nl} Expr + | ‘while’ Expr ‘do’ Expr + | ‘try’ Expr Catches [‘finally’ Expr] + | ‘try’ Expr [‘finally’ Expr] + | ‘throw’ Expr + | ‘return’ [Expr] + | ForExpr + | [SimpleExpr ‘.’] id ‘=’ Expr + | PrefixOperator SimpleExpr ‘=’ Expr + | SimpleExpr ArgumentExprs ‘=’ Expr + | PostfixExpr [Ascription] + | ‘inline’ InfixExpr MatchClause +Ascription ::= ‘:’ InfixType + | ‘:’ Annotation {Annotation} +Catches ::= ‘catch’ (Expr | ExprCaseClause) +PostfixExpr ::= InfixExpr [id] -- only if language.postfixOperators is enabled +InfixExpr ::= PrefixExpr + | InfixExpr id [nl] InfixExpr + | InfixExpr MatchClause +MatchClause ::= ‘match’ <<< CaseClauses >>> +PrefixExpr ::= [PrefixOperator] SimpleExpr +PrefixOperator ::= ‘-’ | ‘+’ | ‘~’ | ‘!’ -- unless backquoted +SimpleExpr ::= SimpleRef + | Literal + | ‘_’ + | BlockExpr + | ExprSplice + | Quoted + | quoteId -- only inside splices + | ‘new’ ConstrApp {‘with’ ConstrApp} [TemplateBody] + | ‘new’ TemplateBody + | ‘(’ ExprsInParens ‘)’ + | SimpleExpr ‘.’ id + | SimpleExpr ‘.’ MatchClause + | SimpleExpr TypeArgs + | SimpleExpr ArgumentExprs +Quoted ::= ‘'’ ‘{’ Block ‘}’ + | ‘'’ ‘[’ Type ‘]’ +ExprSplice ::= spliceId -- if inside quoted block + | ‘$’ ‘{’ Block ‘}’ -- unless inside quoted pattern + | ‘$’ ‘{’ Pattern ‘}’ -- when inside quoted pattern +ExprsInParens ::= ExprInParens {‘,’ ExprInParens} +ExprInParens ::= PostfixExpr ‘:’ Type + | Expr +ParArgumentExprs ::= ‘(’ [ExprsInParens] ‘)’ + | ‘(’ ‘using’ ExprsInParens ‘)’ + | ‘(’ [ExprsInParens ‘,’] PostfixExpr ‘*’ ‘)’ +ArgumentExprs ::= ParArgumentExprs + | BlockExpr +BlockExpr ::= <<< (CaseClauses | Block) >>> +Block ::= {BlockStat semi} [BlockResult] +BlockStat ::= Import + | {Annotation {nl}} {LocalModifier} Def + | Extension + | Expr1 + | EndMarker + +ForExpr ::= ‘for’ ‘(’ Enumerators0 ‘)’ {nl} [‘do‘ | ‘yield’] Expr + | ‘for’ ‘{’ Enumerators0 ‘}’ {nl} [‘do‘ | ‘yield’] Expr + | ‘for’ Enumerators0 (‘do‘ | ‘yield’) Expr +Enumerators0 ::= {nl} Enumerators [semi] +Enumerators ::= Generator {semi Enumerator | Guard} +Enumerator ::= Generator + | Guard {Guard} + | Pattern1 ‘=’ Expr +Generator ::= [‘case’] Pattern1 ‘<-’ Expr +Guard ::= ‘if’ PostfixExpr + +CaseClauses ::= CaseClause { CaseClause } +CaseClause ::= ‘case’ Pattern [Guard] ‘=>’ Block +ExprCaseClause ::= ‘case’ Pattern [Guard] ‘=>’ Expr +TypeCaseClauses ::= TypeCaseClause { TypeCaseClause } +TypeCaseClause ::= ‘case’ (InfixType | ‘_’) ‘=>’ Type [semi] + +Pattern ::= Pattern1 { ‘|’ Pattern1 } +Pattern1 ::= Pattern2 [‘:’ RefinedType] +Pattern2 ::= [id ‘@’] InfixPattern [‘*’] +InfixPattern ::= SimplePattern { id [nl] SimplePattern } +SimplePattern ::= PatVar + | Literal + | ‘(’ [Patterns] ‘)’ + | Quoted + | SimplePattern1 [TypeArgs] [ArgumentPatterns] + | ‘given’ RefinedType +SimplePattern1 ::= SimpleRef + | SimplePattern1 ‘.’ id +PatVar ::= varid + | ‘_’ +Patterns ::= Pattern {‘,’ Pattern} +ArgumentPatterns ::= ‘(’ [Patterns] ‘)’ + | ‘(’ [Patterns ‘,’] PatVar ‘*’ ‘)’ +``` + +### Type and Value Parameters +``` +ClsTypeParamClause::= ‘[’ ClsTypeParam {‘,’ ClsTypeParam} ‘]’ +ClsTypeParam ::= {Annotation} [‘+’ | ‘-’] id [HkTypeParamClause] TypeParamBounds + +DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ +DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds + +TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’ +TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds + +HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ +HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause] | ‘_’) TypeBounds + +ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] +ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’ + | [nl] ‘(’ ‘using’ (ClsParams | FunArgTypes) ‘)’ +ClsParams ::= ClsParam {‘,’ ClsParam} +ClsParam ::= {Annotation} [{Modifier} (‘val’ | ‘var’) | ‘inline’] Param +Param ::= id ‘:’ ParamType [‘=’ Expr] + +DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’] +DefParamClause ::= [nl] ‘(’ DefParams ‘)’ | UsingParamClause +UsingParamClause ::= [nl] ‘(’ ‘using’ (DefParams | FunArgTypes) ‘)’ +DefParams ::= DefParam {‘,’ DefParam} +DefParam ::= {Annotation} [‘inline’] Param +``` + +### Bindings and Imports +``` +Bindings ::= ‘(’ [Binding {‘,’ Binding}] ‘)’ +Binding ::= (id | ‘_’) [‘:’ Type] + +Modifier ::= LocalModifier + | AccessModifier + | ‘override’ + | ‘opaque’ +LocalModifier ::= ‘abstract’ + | ‘final’ + | ‘sealed’ + | ‘open’ + | ‘implicit’ + | ‘lazy’ + | ‘inline’ +AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier] +AccessQualifier ::= ‘[’ id ‘]’ + +Annotation ::= ‘@’ SimpleType1 {ParArgumentExprs} + +Import ::= ‘import’ ImportExpr {‘,’ ImportExpr} +Export ::= ‘export’ ImportExpr {‘,’ ImportExpr} +ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec + | SimpleRef ‘as’ id +ImportSpec ::= NamedSelector + | WildcardSelector + | ‘{’ ImportSelectors) ‘}’ +NamedSelector ::= id [‘as’ (id | ‘_’)] +WildCardSelector ::= ‘*' | ‘given’ [InfixType] +ImportSelectors ::= NamedSelector [‘,’ ImportSelectors] + | WildCardSelector {‘,’ WildCardSelector} + +EndMarker ::= ‘end’ EndMarkerTag -- when followed by EOL +EndMarkerTag ::= id | ‘if’ | ‘while’ | ‘for’ | ‘match’ | ‘try’ + | ‘new’ | ‘this’ | ‘given’ | ‘extension’ | ‘val’ +``` + +### Declarations and Definitions +``` +RefineDcl ::= ‘val’ ValDcl + | ‘def’ DefDcl + | ‘type’ {nl} TypeDcl +Dcl ::= RefineDcl + | ‘var’ VarDcl +ValDcl ::= ids ‘:’ Type +VarDcl ::= ids ‘:’ Type +DefDcl ::= DefSig ‘:’ Type +DefSig ::= id [DefTypeParamClause] DefParamClauses +TypeDcl ::= id [TypeParamClause] {FunParamClause} TypeBounds [‘=’ Type] + +Def ::= ‘val’ PatDef + | ‘var’ PatDef + | ‘def’ DefDef + | ‘type’ {nl} TypeDcl + | TmplDef +PatDef ::= ids [‘:’ Type] ‘=’ Expr + | Pattern2 [‘:’ Type] ‘=’ Expr +DefDef ::= DefSig [‘:’ Type] ‘=’ Expr + | ‘this’ DefParamClause DefParamClauses ‘=’ ConstrExpr + +TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef + | [‘case’] ‘object’ ObjectDef + | ‘enum’ EnumDef + | ‘given’ GivenDef +ClassDef ::= id ClassConstr [Template] +ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses +ConstrMods ::= {Annotation} [AccessModifier] +ObjectDef ::= id [Template] +EnumDef ::= id ClassConstr InheritClauses EnumBody +GivenDef ::= [GivenSig] (AnnotType [‘=’ Expr] | StructuralInstance) +GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘:’ -- one of `id`, `DefParamClause`, `UsingParamClause` must be present +StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ WithTemplateBody] +Extension ::= ‘extension’ [DefTypeParamClause] {UsingParamClause} + ‘(’ DefParam ‘)’ {UsingParamClause} ExtMethods +ExtMethods ::= ExtMethod | [nl] <<< ExtMethod {semi ExtMethod} >>> +ExtMethod ::= {Annotation [nl]} {Modifier} ‘def’ DefDef + | Export +Template ::= InheritClauses [TemplateBody] +InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}] +ConstrApps ::= ConstrApp ({‘,’ ConstrApp} | {‘with’ ConstrApp}) +ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} +ConstrExpr ::= SelfInvocation + | <<< SelfInvocation {semi BlockStat} >>> +SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} + +WithTemplateBody ::= <<< [SelfType] TemplateStat {semi TemplateStat} >>> +TemplateBody ::= :<<< [SelfType] TemplateStat {semi TemplateStat} >>> +TemplateStat ::= Import + | Export + | {Annotation [nl]} {Modifier} Def + | {Annotation [nl]} {Modifier} Dcl + | Extension + | Expr1 + | EndMarker + | +SelfType ::= id [‘:’ InfixType] ‘=>’ + | ‘this’ ‘:’ InfixType ‘=>’ + +EnumBody ::= :<<< [SelfType] EnumStat {semi EnumStat} >>> +EnumStat ::= TemplateStat + | {Annotation [nl]} {Modifier} EnumCase +EnumCase ::= ‘case’ (id ClassConstr [‘extends’ ConstrApps]] | ids) + +TopStats ::= TopStat {semi TopStat} +TopStat ::= Import + | Export + | {Annotation [nl]} {Modifier} Def + | Extension + | Packaging + | PackageObject + | EndMarker + | +Packaging ::= ‘package’ QualId :<<< TopStats >>> +PackageObject ::= ‘package’ ‘object’ ObjectDef + +CompilationUnit ::= {‘package’ QualId semi} TopStats +``` From 074b3b8f44f3411357b8bde68c5d9acdd2524aaf Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Thu, 13 Oct 2022 14:34:09 +0200 Subject: [PATCH 03/11] Add docker for website generation --- .gitignore | 2 ++ docs/_spec/Dockerfile | 24 +++++++++++++++ docs/_spec/Gemfile | 8 +++++ docs/_spec/Gemfile.lock | 57 +++++++++++++++++++++++++++++++++++ docs/_spec/README.md | 11 +++++++ docs/_spec/docker-compose.yml | 11 +++++++ 6 files changed, 113 insertions(+) create mode 100644 docs/_spec/Dockerfile create mode 100644 docs/_spec/Gemfile create mode 100644 docs/_spec/Gemfile.lock create mode 100644 docs/_spec/docker-compose.yml diff --git a/.gitignore b/.gitignore index 4ac67ddfbb06..5240662741bb 100644 --- a/.gitignore +++ b/.gitignore @@ -93,3 +93,5 @@ compiler/test-coursier/run/*.jar # docs related contributors.js content-contributors.css +docs/_spec/_site/ +docs/_spec/.jekyll-metadata diff --git a/docs/_spec/Dockerfile b/docs/_spec/Dockerfile new file mode 100644 index 000000000000..a08c5d0e7f98 --- /dev/null +++ b/docs/_spec/Dockerfile @@ -0,0 +1,24 @@ +FROM ruby:2.7 + +RUN apt-get install -y curl \ + && curl -sL https://deb.nodesource.com/setup_18.x | bash - \ + && apt-get install -y nodejs \ + && curl -L https://www.npmjs.com/install.sh | sh + +RUN gem install bundler:1.17.2 jekyll + +WORKDIR /srv/jekyll + +COPY Gemfile . +COPY Gemfile.lock . + + +RUN echo -n "bundle version: " && bundle --version +RUN bundle install +RUN mkdir /opt/npm-global +RUN npm config set prefix '/opt/npm-global' +RUN npm config set global true +RUN npm install bower +RUN echo -n "npm version: " && npm --version +RUN chmod u+s /bin/chown +RUN date diff --git a/docs/_spec/Gemfile b/docs/_spec/Gemfile new file mode 100644 index 000000000000..bc45dc84db8c --- /dev/null +++ b/docs/_spec/Gemfile @@ -0,0 +1,8 @@ +# To build the spec on Travis CI +source "https://rubygems.org" + +gem "jekyll", "3.6.3" +gem "webrick" +gem "rouge" +# gem 's3_website' +gem "redcarpet", "3.5.1" diff --git a/docs/_spec/Gemfile.lock b/docs/_spec/Gemfile.lock new file mode 100644 index 000000000000..48efd373725e --- /dev/null +++ b/docs/_spec/Gemfile.lock @@ -0,0 +1,57 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + colorator (1.1.0) + ffi (1.15.5) + forwardable-extended (2.6.0) + jekyll (3.6.3) + addressable (~> 2.4) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.14) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 3) + safe_yaml (~> 1.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-watch (1.5.1) + listen (~> 3.0) + kramdown (1.17.0) + liquid (4.0.3) + listen (3.7.1) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.3.6) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (5.0.0) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + redcarpet (3.5.1) + rouge (2.2.1) + safe_yaml (1.0.5) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + webrick (1.7.0) + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + jekyll (= 3.6.3) + redcarpet (= 3.5.1) + rouge + webrick + +BUNDLED WITH + 2.3.5 diff --git a/docs/_spec/README.md b/docs/_spec/README.md index d748dddedfd2..e1c7e3497601 100644 --- a/docs/_spec/README.md +++ b/docs/_spec/README.md @@ -16,11 +16,22 @@ We aim to track the configuration GitHub Pages uses but differences may arise as ## Building + Travis CI builds the spec automatically after every merged pull release and publishes to https://www.scala-lang.org/files/archive/spec/2.13/. + +To preview locally, run the following commands in the docs/_spec subfolder: + +``` +env UID="$(id -u)" GID="$(id -g)" docker-compose up +``` + +and open http://0.0.0.0:4000/files/archive/spec/2.13/ to view the spec. Jekyll will rebuild as you edit the markdown, but make sure to restart it when you change `_config.yml`. + ## General Advice for editors diff --git a/docs/_spec/docker-compose.yml b/docs/_spec/docker-compose.yml new file mode 100644 index 000000000000..3eadc939ed40 --- /dev/null +++ b/docs/_spec/docker-compose.yml @@ -0,0 +1,11 @@ +version: '2' + +services: + jekyll: + user: "${UID}:${GID}" + build: . + command: sh -c "chown $UID / && bundle exec jekyll serve --incremental --host=0.0.0.0 " + ports: + - '4000:4000' + volumes: + - .:/srv/jekyll From d557687147e99d77fba24b98031af1ab1528ad91 Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Wed, 12 Oct 2022 14:35:16 +0200 Subject: [PATCH 04/11] Drop hypersections 14 and 15 14: Empty list of references (there is content in the comments however) 15: Out of date changelog --- docs/_spec/14-references.md | 207 --------- docs/_spec/15-changelog.md | 847 ------------------------------------ 2 files changed, 1054 deletions(-) delete mode 100644 docs/_spec/14-references.md delete mode 100644 docs/_spec/15-changelog.md diff --git a/docs/_spec/14-references.md b/docs/_spec/14-references.md deleted file mode 100644 index cc088dfcae11..000000000000 --- a/docs/_spec/14-references.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -title: References -layout: default -chapter: 14 ---- - -# References - -TODO (see comments in markdown source) - - diff --git a/docs/_spec/15-changelog.md b/docs/_spec/15-changelog.md deleted file mode 100644 index 5d24511ff1cb..000000000000 --- a/docs/_spec/15-changelog.md +++ /dev/null @@ -1,847 +0,0 @@ ---- -title: Changelog -layout: default -chapter: 15 ---- - -# Changelog - -This changelog was no longer maintained after version 2.8.0. - -A pull request updating this chapter to list the most significant -changes made in more recent Scala versions would be highly welcome. - -Many language changes, especially larger ones, are documented in SIP -(Scala Improvement Process) proposals. Most proposals that were -accepted and implemented have not merged into the main spec. Pull -requests that merge SIPs into the main spec are also highly welcome. - -To find out what has changed in Scala 2 since 2.8.0, you can consult -the following sources: - -* Scala release notes (recent versions): https://github.com/scala/scala/releases -* Scala release notes (older versions): https://scala-lang.org/blog/announcements/ -* Scala release notes (even older versions): presumably findable via search engine -* Spec changelog in version control: https://github.com/scala/scala/commits/2.13.x/spec -* SIPs: https://docs.scala-lang.org/sips/all.html - -## Changes in Version 2.8.0 - -Trailing commas in expression, argument, type or pattern sequences are -no longer supported. - -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 accidental [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 function 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 a [companion extractor object for every case class] -(05-classes-and-objects.html#case-classes) now. 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] -(04-basic-declarations-and-definitions.html#variable-declarations-and-definitions), -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`](05-classes-and-objects.html#templates). 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](03-types.html#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`](04-basic-declarations-and-definitions.html#value-declarations-and-definitions). -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] -(03-types.html#compound-types). 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 - -_Implemented by Adriaan Moors_ - -[Type parameters](04-basic-declarations-and-definitions.html#type-parameters) -and abstract -[type members](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases) can now also abstract over [type constructors](03-types.html#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 - -[Early object initialization](05-classes-and-objects.html#early-definitions) -makes it 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](06-expressions.html#for-comprehensions-and-for-loops) -has changed. -In the new syntax, generators do not start with a `val` anymore, but filters -start with an `if` (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] -(06-expressions.html#placeholder-syntax-for-anonymous-functions) 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](06-expressions.html#method-values) -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] -(08-pattern-matching.html#pattern-matching-anonymous-functions) -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]) = - (xs zip ys).foldLeft(0.0) { - 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](05-classes-and-objects.html#modifiers). -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 [`private` or `protected`] -(05-classes-and-objects.html#class-definitions). -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*](11-annotations.html). 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](05-classes-and-objects.html#inheritance-closure) -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](05-classes-and-objects.html#templates) `this`. For instance, in - - class C { self: D => - ... - } - -the name `self` is introduced as an alias for `this` within `C` and the -[self type](05-classes-and-objects.html#class-definitions) of `C` is -assumed to be `D`. 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] -(06-expressions.html#assignment-operators). 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 -`unapply` methods in [extractor objects](08-pattern-matching.html#extractor-patterns). -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 `apply` method is used to build even numbers. - -- The `unapply` method is used to decompose an even number; it is in a sense - the reverse of `apply`. `unapply` methods return option types: - `Some(...)` for a match that succeeds, `None` for a match that fails. - Pattern variables are returned as the elements of `Some`. - If there are several variables, they are grouped in a tuple. - -In the second-to-last line, `Twice`’s method is used to construct a number `x`. -In the last line, `x` is tested against the pattern `Twice(n)`. -This pattern succeeds for even numbers and assigns to the variable `n` one half -of the number that was tested. -The pattern match makes use of the `unapply` method of object `Twice`. -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](06-expressions.html#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](06-expressions.html#infix-operations). 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`](11-annotations.html#deprecation-annotations) -is available. 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 [methods returning `unit`] -(04-basic-declarations-and-definitions.html#procedures) has been introduced. -Scala now allows the following shorthands: - -`def f(params)` **for** `def f(params): unit` -`def f(params) { ... }` **for** `def f(params): unit = { ... }` - -#### Type Patterns - -The [syntax of types in patterns](08-pattern-matching.html#type-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[]`](05-classes-and-objects.html#protected). -In particular, one can now simulate package protected access as in Java writing - - protected[P] def X ... - -where would name the package containing `X`. - -#### Relaxation of Private Access - -[Private members of a class](05-classes-and-objects.html#private) can now be -referenced from the companion module of the class and vice versa. - -#### Implicit Lookup - -The lookup method for [implicit definitions](07-implicits.html#implicit-parameters) -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 `HashSet`, -`List`, `Int`, and `String`. Before, it was just the static part of . - -#### Tightened Pattern Match - -A typed [pattern match with a singleton type `p.type`](08-pattern-matching.html#type-patterns) -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 “q”. Before, the -singleton types were erased to `List`, 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] -(01-lexical-syntax.html#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](06-expressions.html#anonymous-functions) -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](06-expressions.html#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](01-lexical-syntax.html#identifiers): - - implicit match requires - -#### Newlines as Statement Separators - -[Newlines](https://www.scala-lang.org/files/archive/spec/2.11/) -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](05-classes-and-objects.html#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 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](06-expressions.html#for-comprehensions-and-for-loops) -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] -(06-expressions.html#method-conversions) 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_](05-classes-and-objects.html#class-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](05-classes-and-objects.html#class-definitions) -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](05-classes-and-objects.html#modifiers) -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] -(05-classes-and-objects.html#templates) 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. - -#### Implicit Parameters - -Views in Scala 1.0 have been replaced by the more general concept of -[implicit parameters](07-implicits.html#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] -(08-pattern-matching.html#pattern-matching-expressions). -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. From 38e79aae2f11522e55948f4073e852ac90d821fb Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Fri, 14 Oct 2022 14:11:12 +0200 Subject: [PATCH 05/11] =?UTF-8?q?Replace=20=E2=80=A6=20by=20...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/_spec/01-lexical-syntax.md | 4 +- docs/_spec/03-types.md | 56 +++++++++---------- docs/_spec/08-pattern-matching.md | 6 +- docs/_spec/13-syntax-summary.md | 8 +-- .../changed-features/overload-resolution.md | 4 +- docs/_spec/TODOreference/syntax.md | 14 ++--- 6 files changed, 46 insertions(+), 46 deletions(-) diff --git a/docs/_spec/01-lexical-syntax.md b/docs/_spec/01-lexical-syntax.md index 921384b40e20..46bd876b4077 100644 --- a/docs/_spec/01-lexical-syntax.md +++ b/docs/_spec/01-lexical-syntax.md @@ -19,7 +19,7 @@ classes (Unicode general category given in parentheses): 1. Letters, which include lower case letters (`Ll`), upper case letters (`Lu`), title case letters (`Lt`), other letters (`Lo`), modifier letters (`Lm`), letter numerals (`Nl`) and the two characters `\u0024 ‘$’` and `\u005F ‘_’`. -1. Digits `‘0’ | … | ‘9’`. +1. Digits `‘0’ | ... | ‘9’`. 1. Parentheses `‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ `. 1. Delimiter characters ``‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ ``. 1. Operator characters. These consist of all printable ASCII characters @@ -41,7 +41,7 @@ id ::= plainid idrest ::= {letter | digit} [‘_’ op] escapeSeq ::= UnicodeEscape | charEscapeSeq UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit -hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ +hexDigit ::= ‘0’ | ... | ‘9’ | ‘A’ | ... | ‘F’ | ‘a’ | ... | ‘f’ ``` There are three ways to form an identifier. First, an identifier can diff --git a/docs/_spec/03-types.md b/docs/_spec/03-types.md index 3c78b33e571c..cd70a4e34373 100644 --- a/docs/_spec/03-types.md +++ b/docs/_spec/03-types.md @@ -207,13 +207,13 @@ substitution ´[ a_1 := T_1 , \ldots , a_n := T_n ]´. Given the partial type definitions: ```scala -class TreeMap[A <: Comparable[A], B] { … } -class List[A] { … } -class I extends Comparable[I] { … } +class TreeMap[A <: Comparable[A], B] { ... } +class List[A] { ... } +class I extends Comparable[I] { ... } -class F[M[_], X] { … } -class S[K <: String] { … } -class G[M[ Z <: I ], I] { … } +class F[M[_], X] { ... } +class S[K <: String] { ... } +class G[M[ Z <: I ], I] { ... } ``` the following parameterized types are well-formed: @@ -255,20 +255,20 @@ A _tuple type_ ´(T_1 , \ldots , T_n)´ is an alias for the class `scala.Tuple´n´[´T_1´, … , ´T_n´]`, where ´n \geq 2´. Tuple classes are case classes whose fields can be accessed using -selectors `_1` , … , `_n`. Their functionality is +selectors `_1`, ..., `_n`. Their functionality is abstracted in a corresponding `Product` trait. The _n_-ary tuple class and product trait are defined at least as follows in the standard Scala library (they might also add other methods and implement other traits). ```scala -case class Tuple´_n´[+´T_1´, … , +´T_n´](_1: ´T_1´, … , _n: ´T_n´) -extends Product´_n´[´T_1´, … , ´T_n´] +case class Tuple´_n´[+´T_1´, ..., +´T_n´](_1: ´T_1´, ..., _n: ´T_n´) +extends Product´_n´[´T_1´, ..., ´T_n´] -trait Product´_n´[+´T_1´, … , +´T_n´] { +trait Product´_n´[+´T_1´, ..., +´T_n´] { override def productArity = ´n´ def _1: ´T_1´ - … + ... def _n: ´T_n´ } ``` @@ -302,7 +302,7 @@ RefineStat ::= Dcl | ``` -A _compound type_ ´T_1´ `with` … `with` ´T_n \\{ R \\}´ +A _compound type_ ´T_1´ `with` ... `with` ´T_n \\{ R \\}´ represents objects with members as given in the component types ´T_1 , \ldots , T_n´ and the refinement ´\\{ R \\}´. A refinement ´\\{ R \\}´ contains declarations and type definitions. @@ -323,7 +323,7 @@ definition within the refinement. This restriction does not apply to the method's result type. If no refinement is given, the empty refinement is implicitly added, -i.e. ´T_1´ `with` … `with` ´T_n´ is a shorthand for ´T_1´ `with` … `with` ´T_n \\{\\}´. +i.e. ´T_1´ `with` ... `with` ´T_n´ is a shorthand for ´T_1´ `with` ... `with` ´T_n \\{\\}´. A compound type may also consist of just a refinement ´\\{ R \\}´ with no preceding component types. Such a type is @@ -336,12 +336,12 @@ a parameter type that contains a refinement with structural declarations. ```scala case class Bird (val name: String) extends Object { - def fly(height: Int) = … -… + def fly(height: Int) = ... +... } case class Plane (val callsign: String) extends Object { - def fly(height: Int) = … -… + def fly(height: Int) = ... +... } def takeoff( runway: Int, @@ -415,8 +415,8 @@ types are defined in the Scala library for ´n´ between 0 and 22 as follows. ```scala package scala -trait Function´_n´[-´T_1´ , … , -´T_n´, +´U´] { - def apply(´x_1´: ´T_1´ , … , ´x_n´: ´T_n´): ´U´ +trait Function´_n´[-´T_1´, ..., -´T_n´, +´U´] { + def apply(´x_1´: ´T_1´, ..., ´x_n´: ´T_n´): ´U´ override def toString = "" } ``` @@ -724,7 +724,7 @@ These notions are defined mutually recursively as follows. given as follows. - The base types of a class type ´C´ with parents ´T_1 , \ldots , T_n´ are ´C´ itself, as well as the base types of the compound type - `´T_1´ with … with ´T_n´ { ´R´ }`. + `´T_1´ with ... with ´T_n´ { ´R´ }`. - The base types of an aliased type are the base types of its alias. - The base types of an abstract type are the base types of its upper bound. - The base types of a parameterized type @@ -861,8 +861,8 @@ The conformance relation ´(<:)´ is the smallest transitive relation that satis - A singleton type `´p´.type` conforms to the type of the path ´p´. - A singleton type `´p´.type` conforms to the type `scala.Singleton`. - A type projection `´T´#´t´` conforms to `´U´#´t´` if ´T´ conforms to ´U´. -- A parameterized type `´T´[´T_1´ , … , ´T_n´]` conforms to - `´T´[´U_1´ , … , ´U_n´]` if +- A parameterized type `´T´[´T_1´, ..., ´T_n´]` conforms to + `´T´[´U_1´, ..., ´U_n´]` if the following three conditions hold for ´i \in \{ 1 , \ldots , n \}´: 1. If the ´i´'th type parameter of ´T´ is declared covariant, then ´T_i <: U_i´. @@ -922,13 +922,13 @@ type ´C'´, if one of the following holds. subsumes a method declaration that defines ´x´ with type ´T'´, provided ´T <: T'´. - A type alias - `type ´t´[´T_1´ , … , ´T_n´] = ´T´` subsumes a type alias - `type ´t´[´T_1´ , … , ´T_n´] = ´T'´` if ´T \equiv T'´. -- A type declaration `type ´t´[´T_1´ , … , ´T_n´] >: ´L´ <: ´U´` subsumes - a type declaration `type ´t´[´T_1´ , … , ´T_n´] >: ´L'´ <: ´U'´` if + `type ´t´[´T_1´, ..., ´T_n´] = ´T´` subsumes a type alias + `type ´t´[´T_1´, ..., ´T_n´] = ´T'´` if ´T \equiv T'´. +- A type declaration `type ´t´[´T_1´, ..., ´T_n´] >: ´L´ <: ´U´` subsumes + a type declaration `type ´t´[´T_1´, ..., ´T_n´] >: ´L'´ <: ´U'´` if ´L' <: L´ and ´U <: U'´. - A type or class definition that binds a type name ´t´ subsumes an abstract - type declaration `type t[´T_1´ , … , ´T_n´] >: L <: U` if + type declaration `type t[´T_1´, ..., ´T_n´] >: L <: U` if ´L <: t <: U´. @@ -1024,7 +1024,7 @@ A value member of a volatile type cannot appear in a [path](#paths). A type is _volatile_ if it falls into one of four categories: -A compound type `´T_1´ with … with ´T_n´ {´R\,´}` +A compound type `´T_1´ with ... with ´T_n´ {´R\,´}` is volatile if one of the following three conditions hold. 1. One of ´T_2 , \ldots , T_n´ is a type parameter or abstract type, or diff --git a/docs/_spec/08-pattern-matching.md b/docs/_spec/08-pattern-matching.md index 7607b0db85e0..53dc3ffe4547 100644 --- a/docs/_spec/08-pattern-matching.md +++ b/docs/_spec/08-pattern-matching.md @@ -114,12 +114,12 @@ The expansion of interpolated string literals in patterns is the same as in expressions. If it occurs in a pattern, a interpolated string literal of either of the forms ``` -id"text0{ pat1 }text1 … { patn }textn" -id"""text0{ pat1 }text1 … { patn }textn""" +id"text0{ pat1 }text1 ... { patn }textn" +id"""text0{ pat1 }text1 ... { patn }textn""" ``` is equivalent to: ``` -StringContext("""text0""", …, """textn""").id(pat1, …, patn) +StringContext("""text0""", ..., """textn""").id(pat1, ..., patn) ``` You could define your own `StringContext` to shadow the default one that's in the `scala` package. diff --git a/docs/_spec/13-syntax-summary.md b/docs/_spec/13-syntax-summary.md index 6ece538e2ff1..e799a6f579b3 100644 --- a/docs/_spec/13-syntax-summary.md +++ b/docs/_spec/13-syntax-summary.md @@ -14,14 +14,14 @@ The lexical syntax of Scala is given by the following grammar in EBNF form: ```ebnf whiteSpace ::= ‘\u0020’ | ‘\u0009’ | ‘\u000D’ | ‘\u000A’ -upper ::= ‘A’ | … | ‘Z’ | ‘$’ and any character in Unicode categories Lu, Lt or Nl, +upper ::= ‘A’ | ... | ‘Z’ | ‘$’ and any character in Unicode categories Lu, Lt or Nl, and any character in Unicode categories Lo and Lm that doesn't have contributory property Other_Lowercase -lower ::= ‘a’ | … | ‘z’ | ‘_’ and any character in Unicode category Ll, +lower ::= ‘a’ | ... | ‘z’ | ‘_’ and any character in Unicode category Ll, and any character in Unicode categories Lo or Lm that has contributory property Other_Lowercase letter ::= upper | lower -digit ::= ‘0’ | … | ‘9’ +digit ::= ‘0’ | ... | ‘9’ paren ::= ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ delim ::= ‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ opchar ::= ‘!’ | ‘#’ | ‘%’ | ‘&’ | ‘*’ | ‘+’ | ‘-’ | ‘/’ | ‘:’ | @@ -29,7 +29,7 @@ opchar ::= ‘!’ | ‘#’ | ‘%’ | ‘&’ | ‘*’ | ‘+’ and any character in Unicode categories Sm or So printableChar ::= all characters in [\u0020, \u007E] inclusive UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit -hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ +hexDigit ::= ‘0’ | ... | ‘9’ | ‘A’ | ... | ‘F’ | ‘a’ | ... | ‘f’ charEscapeSeq ::= ‘\’ (‘b’ | ‘t’ | ‘n’ | ‘f’ | ‘r’ | ‘"’ | ‘'’ | ‘\’) escapeSeq ::= UnicodeEscape | charEscapeSeq op ::= opchar {opchar} diff --git a/docs/_spec/TODOreference/changed-features/overload-resolution.md b/docs/_spec/TODOreference/changed-features/overload-resolution.md index bd7782ded520..621515c2a7f8 100644 --- a/docs/_spec/TODOreference/changed-features/overload-resolution.md +++ b/docs/_spec/TODOreference/changed-features/overload-resolution.md @@ -66,11 +66,11 @@ as follows: Replace the sentence -> Otherwise, let `S1,…,Sm` be the vector of types obtained by typing each argument with an undefined expected type. +> Otherwise, let `S1,...,Sm` be the vector of types obtained by typing each argument with an undefined expected type. with the following paragraph: -> Otherwise, let `S1,…,Sm` be the vector of known types of all argument types, where the _known type_ of an argument `E` +> Otherwise, let `S1,...,Sm` be the vector of known types of all argument types, where the _known type_ of an argument `E` is determined as followed: - If `E` is a function value `(p_1, ..., p_n) => B` that misses some parameter types, the known type diff --git a/docs/_spec/TODOreference/syntax.md b/docs/_spec/TODOreference/syntax.md index e11629c8eaf9..d3526783a5eb 100644 --- a/docs/_spec/TODOreference/syntax.md +++ b/docs/_spec/TODOreference/syntax.md @@ -26,7 +26,7 @@ hexadecimal code: ``` UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit -hexDigit ::= ‘0’ | … | ‘9’ | ‘A’ | … | ‘F’ | ‘a’ | … | ‘f’ +hexDigit ::= ‘0’ | ... | ‘9’ | ‘A’ | ... | ‘F’ | ‘a’ | ... | ‘f’ ``` Informal descriptions are typeset as `“some comment”`. @@ -38,15 +38,15 @@ form. ``` whiteSpace ::= ‘\u0020’ | ‘\u0009’ | ‘\u000D’ | ‘\u000A’ -upper ::= ‘A’ | … | ‘Z’ | ‘\$’ | ‘_’ “… and Unicode category Lu” -lower ::= ‘a’ | … | ‘z’ “… and Unicode category Ll” -letter ::= upper | lower “… and Unicode categories Lo, Lt, Nl” -digit ::= ‘0’ | … | ‘9’ +upper ::= ‘A’ | ... | ‘Z’ | ‘\$’ | ‘_’ “... and Unicode category Lu” +lower ::= ‘a’ | ... | ‘z’ “... and Unicode category Ll” +letter ::= upper | lower “... and Unicode categories Lo, Lt, Nl” +digit ::= ‘0’ | ... | ‘9’ paren ::= ‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ delim ::= ‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ opchar ::= ‘!’ | ‘#’ | ‘%’ | ‘&’ | ‘*’ | ‘+’ | ‘-’ | ‘/’ | ‘:’ | ‘<’ | ‘=’ | ‘>’ | ‘?’ | ‘@’ | ‘\’ | ‘^’ | ‘|’ | ‘~’ - “… and Unicode categories Sm, So” + “... and Unicode categories Sm, So” printableChar ::= “all characters in [\u0020, \u007E] inclusive” charEscapeSeq ::= ‘\’ (‘b’ | ‘t’ | ‘n’ | ‘f’ | ‘r’ | ‘"’ | ‘'’ | ‘\’) @@ -65,7 +65,7 @@ spliceId ::= ‘$’ alphaid ; integerLiteral ::= (decimalNumeral | hexNumeral) [‘L’ | ‘l’] decimalNumeral ::= ‘0’ | nonZeroDigit [{digit | ‘_’} digit] hexNumeral ::= ‘0’ (‘x’ | ‘X’) hexDigit [{hexDigit | ‘_’} hexDigit] -nonZeroDigit ::= ‘1’ | … | ‘9’ +nonZeroDigit ::= ‘1’ | ... | ‘9’ floatingPointLiteral ::= [decimalNumeral] ‘.’ digit [{digit | ‘_’} digit] [exponentPart] [floatType] From 14a80c25027bdb7b1ddee864351761193c77a8fa Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Fri, 14 Oct 2022 14:46:14 +0200 Subject: [PATCH 06/11] replace \ldots by ... --- docs/_spec/03-types.md | 122 +++++------ .../04-basic-declarations-and-definitions.md | 50 ++--- docs/_spec/05-classes-and-objects.md | 54 ++--- docs/_spec/06-expressions.md | 200 +++++++++--------- docs/_spec/07-implicits.md | 32 +-- docs/_spec/08-pattern-matching.md | 124 +++++------ docs/_spec/09-top-level-definitions.md | 6 +- docs/_spec/11-annotations.md | 2 +- docs/_spec/12-the-scala-standard-library.md | 52 ++--- 9 files changed, 321 insertions(+), 321 deletions(-) diff --git a/docs/_spec/03-types.md b/docs/_spec/03-types.md index cd70a4e34373..205af416b9c5 100644 --- a/docs/_spec/03-types.md +++ b/docs/_spec/03-types.md @@ -191,16 +191,16 @@ SimpleType ::= SimpleType TypeArgs TypeArgs ::= ‘[’ Types ‘]’ ``` -A _parameterized type_ ´T[ T_1 , \ldots , T_n ]´ consists of a type -designator ´T´ and type parameters ´T_1 , \ldots , T_n´ where +A _parameterized type_ ´T[ T_1, ..., T_n ]´ consists of a type +designator ´T´ and type parameters ´T_1, ..., T_n´ where ´n \geq 1´. ´T´ must refer to a type constructor which takes ´n´ type -parameters ´a_1 , \ldots , a_n´. +parameters ´a_1, ..., a_n´. -Say the type parameters have lower bounds ´L_1 , \ldots , L_n´ and -upper bounds ´U_1, \ldots, U_n´. The parameterized type is +Say the type parameters have lower bounds ´L_1, ..., L_n´ and +upper bounds ´U_1, ..., U_n´. The parameterized type is 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 ]´. +substitution ´[ a_1 := T_1, ..., a_n := T_n ]´. ###### Example Parameterized Types @@ -251,8 +251,8 @@ G[S, Int] // illegal: S constrains its parameter to SimpleType ::= ‘(’ Types ‘)’ ``` -A _tuple type_ ´(T_1 , \ldots , T_n)´ is an alias for the -class `scala.Tuple´n´[´T_1´, … , ´T_n´]`, where ´n \geq 2´. +A _tuple type_ ´(T_1 , ... , T_n)´ is an alias for the +class `scala.Tuple´n´[´T_1´, ... , ´T_n´]`, where ´n \geq 2´. Tuple classes are case classes whose fields can be accessed using selectors `_1`, ..., `_n`. Their functionality is @@ -279,9 +279,9 @@ trait Product´_n´[+´T_1´, ..., +´T_n´] { AnnotType ::= SimpleType {Annotation} ``` -An _annotated type_ ´T´ ´a_1, \ldots, a_n´ +An _annotated type_ ´T´ ´a_1, ..., a_n´ attaches [annotations](11-annotations.html#user-defined-annotations) -´a_1 , \ldots , a_n´ to the type ´T´. +´a_1, ..., a_n´ to the type ´T´. ###### Example @@ -304,10 +304,10 @@ RefineStat ::= Dcl A _compound type_ ´T_1´ `with` ... `with` ´T_n \\{ R \\}´ represents objects with members as given in the component types -´T_1 , \ldots , T_n´ and the refinement ´\\{ R \\}´. A refinement +´T_1, ..., T_n´ and the refinement ´\\{ R \\}´. A refinement ´\\{ R \\}´ contains declarations and type definitions. If a declaration or definition overrides a declaration or definition in -one of the component types ´T_1 , \ldots , T_n´, the usual rules for +one of the component types ´T_1, ..., T_n´, the usual rules for [overriding](05-classes-and-objects.html#overriding) apply; otherwise the declaration or definition is said to be “structural” [^2]. @@ -380,13 +380,13 @@ ending in a colon ‘:’ are right-associative; all other operators are left-associative. In a sequence of consecutive type infix operations -´t_0 \, \mathit{op} \, t_1 \, \mathit{op_2} \, \ldots \, \mathit{op_n} \, t_n´, -all operators ´\mathit{op}\_1 , \ldots , \mathit{op}\_n´ must have the same +´t_0 \, \mathit{op} \, t_1 \, \mathit{op_2} \, ... \, \mathit{op_n} \, t_n´, +all operators ´\mathit{op}\_1, ..., \mathit{op}\_n´ must have the same associativity. If they are all left-associative, the sequence is interpreted as -´(\ldots (t_0 \mathit{op_1} t_1) \mathit{op_2} \ldots) \mathit{op_n} t_n´, +´(... (t_0 \mathit{op_1} t_1) \mathit{op_2} ...) \mathit{op_n} t_n´, otherwise it is interpreted as -´t_0 \mathit{op_1} (t_1 \mathit{op_2} ( \ldots \mathit{op_n} t_n) \ldots)´. +´t_0 \mathit{op_1} (t_1 \mathit{op_2} ( ... \mathit{op_n} t_n) ...)´. ### Function Types @@ -396,8 +396,8 @@ FunctionArgs ::= InfixType | ‘(’ [ ParamType {‘,’ ParamType } ] ‘)’ ``` -The type ´(T_1 , \ldots , T_n) \Rightarrow U´ represents the set of function -values that take arguments of types ´T_1 , \ldots , Tn´ and yield +The type ´(T_1, ..., T_n) \Rightarrow U´ represents the set of function +values that take arguments of types ´T_1, ..., Tn´ and yield results of type ´U´. In the case of exactly one argument type ´T \Rightarrow U´ is a shorthand for ´(T) \Rightarrow U´. An argument type of the form ´\Rightarrow T´ @@ -589,10 +589,10 @@ report as the internal types of defined identifiers. ### Method Types A _method type_ is denoted internally as ´(\mathit{Ps})U´, where ´(\mathit{Ps})´ -is a sequence of parameter names and types ´(p_1:T_1 , \ldots , p_n:T_n)´ +is a sequence of parameter names and types ´(p_1:T_1, ..., p_n:T_n)´ for some ´n \geq 0´ and ´U´ is a (value or method) type. This type -represents named methods that take arguments named ´p_1 , \ldots , p_n´ -of types ´T_1 , \ldots , T_n´ +represents named methods that take arguments named ´p_1, ..., p_n´ +of types ´T_1, ..., T_n´ and that return a result of type ´U´. Method types associate to the right: ´(\mathit{Ps}\_1)(\mathit{Ps}\_2)U´ is @@ -629,13 +629,13 @@ c: (Int) (String, String) String A polymorphic method type is denoted internally as `[´\mathit{tps}\,´]´T´` where `[´\mathit{tps}\,´]` is a type parameter section -`[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]` +`[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]` for some ´n \geq 0´ and ´T´ is a (value or method) type. This type represents named methods that -take type arguments `´S_1 , \ldots , S_n´` which +take type arguments `´S_1, ..., S_n´` which [conform](#parameterized-types) to the lower bounds -`´L_1 , \ldots , L_n´` and the upper bounds -`´U_1 , \ldots , U_n´` and that yield results of type ´T´. +`´L_1, ..., L_n´` and the upper bounds +`´U_1, ..., U_n´` and that yield results of type ´T´. ###### Example @@ -656,7 +656,7 @@ union : [A >: Nothing <: Comparable[A]] (x: Set[A], xs: Set[A]) Set[A] ### Type Constructors A _type constructor_ is represented internally much like a polymorphic method type. -`[´\pm´ ´a_1´ >: ´L_1´ <: ´U_1 , \ldots , \pm a_n´ >: ´L_n´ <: ´U_n´] ´T´` +`[´\pm´ ´a_1´ >: ´L_1´ <: ´U_1, ..., \pm a_n´ >: ´L_n´ <: ´U_n´] ´T´` represents a type that is expected by a [type constructor parameter](04-basic-declarations-and-definitions.html#type-parameters) or an [abstract type constructor binding](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases) with @@ -681,15 +681,15 @@ anonymous type `[+X] Iterable[X]`, which may be passed to the More than one values or methods are defined in the same scope with the 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´. +An overloaded type consisting of type alternatives ´T_1 \commadots T_n (n \geq 2)´ is denoted internally ´T_1 \overload ... \overload T_n´. ###### Example ```scala def println(): Unit -def println(s: String): Unit = ´\ldots´ -def println(x: Float): Unit = ´\ldots´ -def println(x: Float, width: Int): Unit = ´\ldots´ -def println[A](x: A)(tostring: A => String): Unit = ´\ldots´ +def println(s: String): Unit = ... +def println(x: Float): Unit = ... +def println(x: Float, width: Int): Unit = ... +def println[A](x: A)(tostring: A => String): Unit = ... ``` define a single function `println` which has an overloaded type. @@ -703,7 +703,7 @@ println: () Unit ´\overload´ ###### Example ```scala -def f(x: T): T = ´\ldots´ +def f(x: T): T = ... val f = 0 ``` define a function `f} which has type `(x: T)T ´\overload´ Int`. @@ -722,25 +722,25 @@ These notions are defined mutually recursively as follows. 1. The set of _base types_ of a type is a set of class types, given as follows. - - The base types of a class type ´C´ with parents ´T_1 , \ldots , T_n´ are + - The base types of a class type ´C´ with parents ´T_1, ..., T_n´ are ´C´ itself, as well as the base types of the compound type `´T_1´ with ... with ´T_n´ { ´R´ }`. - The base types of an aliased type are the base types of its alias. - The base types of an abstract type are the base types of its upper bound. - The base types of a parameterized type - `´C´[´T_1 , \ldots , T_n´]` are the base types + `´C´[´T_1, ..., T_n´]` are the base types of type ´C´, where every occurrence of a type parameter ´a_i´ of ´C´ has been replaced by the corresponding parameter type ´T_i´. - The base types of a singleton type `´p´.type` are the base types of the type of ´p´. - The base types of a compound type - `´T_1´ with ´\ldots´ with ´T_n´ { ´R´ }` + `´T_1´ with ... with ´T_n´ { ´R´ }` are the _reduced union_ of the base classes of all ´T_i´'s. This means: Let the multi-set ´\mathscr{S}´ be the multi-set-union of the base types of all ´T_i´'s. If ´\mathscr{S}´ contains several type instances of the same class, say - `´S^i´#´C´[´T^i_1 , \ldots , T^i_n´]` ´(i \in I)´, then + `´S^i´#´C´[´T^i_1, ..., T^i_n´]` ´(i \in I)´, then all those instances are replaced by one of them which conforms to all others. It is an error if no such instance exists. It follows that the @@ -759,15 +759,15 @@ These notions are defined mutually recursively as follows. 1. The notion of a type ´T´ _in class ´C´ seen from some prefix type ´S´_ makes sense only if the prefix type ´S´ has a type instance of class ´C´ as a base type, say - `´S'´#´C´[´T_1 , \ldots , T_n´]`. Then we define as follows. + `´S'´#´C´[´T_1, ..., T_n´]`. Then we define as follows. - If `´S´ = ´\epsilon´.type`, then ´T´ in ´C´ seen from ´S´ is ´T´ itself. - Otherwise, if ´S´ is an existential type `´S'´ forSome { ´Q´ }`, and ´T´ in ´C´ seen from ´S'´ is ´T'´, then ´T´ in ´C´ seen from ´S´ is `´T'´ forSome {´\,Q\,´}`. - Otherwise, if ´T´ is the ´i´'th type parameter of some class ´D´, then - - If ´S´ has a base type `´D´[´U_1 , \ldots , U_n´]`, for some type - parameters `[´U_1 , \ldots , U_n´]`, then ´T´ in ´C´ seen from ´S´ + - If ´S´ has a base type `´D´[´U_1, ..., U_n´]`, for some type + parameters `[´U_1, ..., U_n´]`, then ´T´ in ´C´ seen from ´S´ is ´U_i´. - Otherwise, if ´C´ is defined in a class ´C'´, then ´T´ in ´C´ seen from ´S´ is the same as ´T´ in ´C'´ seen from ´S'´. @@ -863,19 +863,19 @@ The conformance relation ´(<:)´ is the smallest transitive relation that satis - A type projection `´T´#´t´` conforms to `´U´#´t´` if ´T´ conforms to ´U´. - A parameterized type `´T´[´T_1´, ..., ´T_n´]` conforms to `´T´[´U_1´, ..., ´U_n´]` if - the following three conditions hold for ´i \in \{ 1 , \ldots , n \}´: + the following three conditions hold for ´i \in \{ 1, ..., n \}´: 1. If the ´i´'th type parameter of ´T´ is declared covariant, then ´T_i <: U_i´. 1. If the ´i´'th type parameter of ´T´ is declared contravariant, then ´U_i <: T_i´. 1. If the ´i´'th type parameter of ´T´ is declared neither covariant nor contravariant, then ´U_i \equiv T_i´. -- A compound type `´T_1´ with ´\ldots´ with ´T_n´ {´R\,´}` conforms to +- A compound type `´T_1´ with ... with ´T_n´ {´R\,´}` conforms to each of its component types ´T_i´. -- If ´T <: U_i´ for ´i \in \{ 1 , \ldots , n \}´ and for every +- If ´T <: U_i´ for ´i \in \{ 1, ..., n \}´ and for every binding ´d´ of a type or value ´x´ in ´R´ there exists a member binding of ´x´ in ´T´ which subsumes ´d´, then ´T´ conforms to the - compound type `´U_1´ with ´\ldots´ with ´U_n´ {´R\,´}`. + compound type `´U_1´ with ... with ´U_n´ {´R\,´}`. - The existential type `´T´ forSome {´\,Q\,´}` conforms to ´U´ if its [skolemization](#existential-types) conforms to ´U´. @@ -883,25 +883,25 @@ The conformance relation ´(<:)´ is the smallest transitive relation that satis if ´T´ conforms to one of the [type instances](#existential-types) of `´U´ forSome {´\,Q\,´}`. - If - ´T_i \equiv T_i'´ for ´i \in \{ 1 , \ldots , n\}´ and ´U´ conforms to ´U'´ - then the method type ´(p_1:T_1 , \ldots , p_n:T_n) U´ conforms to - ´(p_1':T_1' , \ldots , p_n':T_n') U'´. + ´T_i \equiv T_i'´ for ´i \in \{ 1, ..., n\}´ and ´U´ conforms to ´U'´ + then the method type ´(p_1:T_1, ..., p_n:T_n) U´ conforms to + ´(p_1':T_1', ..., p_n':T_n') U'´. - The polymorphic type - ´[a_1 >: L_1 <: U_1 , \ldots , a_n >: L_n <: U_n] T´ conforms to the + ´[a_1 >: L_1 <: U_1, ..., a_n >: L_n <: U_n] T´ conforms to the polymorphic type - ´[a_1 >: L_1' <: U_1' , \ldots , a_n >: L_n' <: U_n'] T'´ if, assuming - ´L_1' <: a_1 <: U_1' , \ldots , L_n' <: a_n <: U_n'´ + ´[a_1 >: L_1' <: U_1', ..., a_n >: L_n' <: U_n'] T'´ if, assuming + ´L_1' <: a_1 <: U_1', ..., L_n' <: a_n <: U_n'´ one has ´T <: T'´ and ´L_i <: L_i'´ and ´U_i' <: U_i´ - for ´i \in \{ 1 , \ldots , n \}´. + for ´i \in \{ 1, ..., n \}´. - Type constructors ´T´ and ´T'´ follow a similar discipline. We characterize ´T´ and ´T'´ by their type parameter clauses - ´[a_1 , \ldots , a_n]´ and - ´[a_1' , \ldots , a_n']´, where an ´a_i´ or ´a_i'´ may include a variance + ´[a_1, ..., a_n]´ and + ´[a_1', ..., a_n']´, where an ´a_i´ or ´a_i'´ may include a variance annotation, a higher-order type parameter clause, and bounds. Then, ´T´ - conforms to ´T'´ if any list ´[t_1 , \ldots , t_n]´ -- with declared + conforms to ´T'´ if any list ´[t_1, ..., t_n]´ -- with declared variances, bounds and higher-order type parameter clauses -- of valid type arguments for ´T'´ is also a valid list of type arguments for ´T´ and - ´T[t_1 , \ldots , t_n] <: T'[t_1 , \ldots , t_n]´. Note that this entails + ´T[t_1, ..., t_n] <: T'[t_1, ..., t_n]´. Note that this entails that: - The bounds on ´a_i´ must be weaker than the corresponding bounds declared for ´a'_i´. @@ -1027,11 +1027,11 @@ A type is _volatile_ if it falls into one of four categories: A compound type `´T_1´ with ... with ´T_n´ {´R\,´}` is volatile if one of the following three conditions hold. -1. One of ´T_2 , \ldots , T_n´ is a type parameter or abstract type, or +1. One of ´T_2, ..., T_n´ is a type parameter or abstract type, or 1. ´T_1´ is an abstract type and either the refinement ´R´ or a type ´T_j´ for ´j > 1´ contributes an abstract member to the compound type, or -1. one of ´T_1 , \ldots , T_n´ is a singleton type. +1. one of ´T_1, ..., T_n´ is a singleton type. Here, a type ´S´ _contributes an abstract member_ to a type ´T´ if ´S´ contains an abstract member that is also a member of ´T´. @@ -1059,18 +1059,18 @@ The erasure mapping is defined as follows. - The erasure of an abstract type is the erasure of its upper bound. - The erasure of the parameterized type `scala.Array´[T_1]´` is `scala.Array´[|T_1|]´`. -- The erasure of every other parameterized type ´T[T_1 , \ldots , T_n]´ is ´|T|´. +- The erasure of every other parameterized type ´T[T_1, ..., T_n]´ is ´|T|´. - The erasure of a singleton type `´p´.type` is the erasure of the type of ´p´. - The erasure of a type projection `´T´#´x´` is `|´T´|#´x´`. - The erasure of a compound type - `´T_1´ with ´\ldots´ with ´T_n´ {´R\,´}` is the erasure of the intersection - dominator of ´T_1 , \ldots , T_n´. + `´T_1´ with ... with ´T_n´ {´R\,´}` is the erasure of the intersection + dominator of ´T_1, ..., T_n´. - The erasure of an existential type `´T´ forSome {´\,Q\,´}` is ´|T|´. -The _intersection dominator_ of a list of types ´T_1 , \ldots , T_n´ is computed +The _intersection dominator_ of a list of types ´T_1, ..., T_n´ is computed as follows. -Let ´T_{i_1} , \ldots , T_{i_m}´ be the subsequence of types ´T_i´ +Let ´T_{i_1}, ..., T_{i_m}´ be the subsequence of types ´T_i´ which are not supertypes of some other type ´T_j´. If this subsequence contains a type designator ´T_c´ that refers to a class which is not a trait, diff --git a/docs/_spec/04-basic-declarations-and-definitions.md b/docs/_spec/04-basic-declarations-and-definitions.md index acaf2491d99b..0dd311e558b8 100644 --- a/docs/_spec/04-basic-declarations-and-definitions.md +++ b/docs/_spec/04-basic-declarations-and-definitions.md @@ -32,7 +32,7 @@ associate term names with types. The scope of a name introduced by a declaration or definition is the whole statement sequence containing the binding. However, there is a restriction on forward references in blocks: In a statement sequence -´s_1 \ldots s_n´ making up a block, if a simple name in ´s_i´ refers +´s_1 ... s_n´ making up a block, if a simple name in ´s_i´ refers to an entity defined by ´s_j´ where ´j \geq i´, then for all ´s_k´ between and including ´s_i´ and ´s_j´, @@ -138,12 +138,12 @@ as left-hand side. If ´p´ is some pattern other than a simple name or a name followed by a colon and a type, then the value definition `val ´p´ = ´e´` is expanded as follows: -1. If the pattern ´p´ has bound variables ´x_1 , \ldots , x_n´, where ´n > 1´: +1. If the pattern ´p´ has bound variables ´x_1, ..., x_n´, where ´n > 1´: ```scala -val ´\$x´ = ´e´ match {case ´p´ => (´x_1 , \ldots , x_n´)} +val ´\$x´ = ´e´ match {case ´p´ => (´x_1, ..., x_n´)} val ´x_1´ = ´\$x´._1 -´\ldots´ +... val ´x_n´ = ´\$x´._n ``` @@ -184,11 +184,11 @@ val xs = x´\$´._2 The name of any declared or defined value may not end in `_=`. -A value declaration `val ´x_1 , \ldots , x_n´: ´T´` is a shorthand for the +A value declaration `val ´x_1, ..., x_n´: ´T´` is a shorthand for the sequence of value declarations `val ´x_1´: ´T´; ...; val ´x_n´: ´T´`. -A value definition `val ´p_1 , \ldots , p_n´ = ´e´` is a shorthand for the +A value definition `val ´p_1, ..., p_n´ = ´e´` is a shorthand for the sequence of value definitions `val ´p_1´ = ´e´; ...; val ´p_n´ = ´e´`. -A value definition `val ´p_1 , \ldots , p_n: T´ = ´e´` is a shorthand for the +A value definition `val ´p_1, ..., p_n: T´ = ´e´` is a shorthand for the sequence of value definitions `val ´p_1: T´ = ´e´; ...; val ´p_n: T´ = ´e´`. ## Variable Declarations and Definitions @@ -283,11 +283,11 @@ d.hours = 8; d.minutes = 30; d.seconds = 0 d.hours = 25 // throws a DateError exception ``` -A variable declaration `var ´x_1 , \ldots , x_n´: ´T´` is a shorthand for the +A variable declaration `var ´x_1, ..., x_n´: ´T´` is a shorthand for the sequence of variable declarations `var ´x_1´: ´T´; ...; var ´x_n´: ´T´`. -A variable definition `var ´x_1 , \ldots , x_n´ = ´e´` is a shorthand for the +A variable definition `var ´x_1, ..., x_n´ = ´e´` is a shorthand for the sequence of variable definitions `var ´x_1´ = ´e´; ...; var ´x_n´ = ´e´`. -A variable definition `var ´x_1 , \ldots , x_n: T´ = ´e´` is a shorthand for +A variable definition `var ´x_1, ..., x_n: T´ = ´e´` is a shorthand for the sequence of variable definitions `var ´x_1: T´ = ´e´; ...; var ´x_n: T´ = ´e´`. @@ -407,7 +407,7 @@ definitions with lower bounds `>: ´L´` and upper bounds is deferred to [here](07-implicits.html#context-bounds-and-view-bounds). The most general form of a proper type parameter is -`´@a_1 \ldots @a_n´ ´\pm´ ´t´ >: ´L´ <: ´U´`. +`´@a_1 ... @a_n´ ´\pm´ ´t´ >: ´L´ <: ´U´`. Here, ´L´, and ´U´ are lower and upper bounds that constrain possible type arguments for the parameter. It is a compile-time error if ´L´ does not conform to ´U´. ´\pm´ is a _variance_, i.e. an optional prefix of either `+`, or @@ -426,7 +426,7 @@ TODO: this is a pretty awkward description of scoping and distinctness of binder The names of all type parameters must be pairwise different in their enclosing type parameter clause. The scope of a type parameter includes in each case the whole type parameter clause. Therefore it is possible that a type parameter appears as part of its own bounds or the bounds of other type parameters in the same clause. However, a type parameter may not be bounded directly or indirectly by itself. -A type constructor parameter adds a nested type parameter clause to the type parameter. The most general form of a type constructor parameter is `´@a_1 \ldots @a_n \pm t[\mathit{tps}\,]´ >: ´L´ <: ´U´`. +A type constructor parameter adds a nested type parameter clause to the type parameter. The most general form of a type constructor parameter is `´@a_1 ... @a_n \pm t[\mathit{tps}\,]´ >: ´L´ <: ´U´`. The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. Higher-order type parameters (the type parameters of a type parameter ´t´) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of ´t´. Therefore, their names must only be pairwise different from the names of other visible parameters. Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a `‘_’`, which is nowhere visible. @@ -491,11 +491,11 @@ changes at the following constructs. - The type of a mutable variable is always in invariant position. - The right-hand side of a type alias is always in invariant position. - The prefix ´S´ of a type selection `´S´#´T´` is always in invariant position. -- For a type argument ´T´ of a type `´S´[´\ldots T \ldots´ ]`: If the +- For a type argument ´T´ of a type `´S´[´... T ...´ ]`: If the corresponding type parameter is invariant, then ´T´ is in invariant position. If the corresponding type parameter is contravariant, the variance position of ´T´ is the opposite of - the variance position of the enclosing type `´S´[´\ldots T \ldots´ ]`. + the variance position of the enclosing type `´S´[´... T ...´ ]`. @@ -602,7 +602,7 @@ signature and ´T´ is its result type. A _function definition_ i.e. an expression which defines the function's result. A parameter signature consists of an optional type parameter clause `[´\mathit{tps}\,´]`, followed by zero or more value parameter clauses -`(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_n´)`. Such a declaration or definition +`(´\mathit{ps}_1´)...(´\mathit{ps}_n´)`. Such a declaration or definition introduces a value with a (possibly polymorphic) method type whose parameter types and result type are as given. @@ -635,7 +635,7 @@ For every parameter ´p_{i,j}´ with a default argument a method named expression. Here, ´n´ denotes the parameter's position in the method declaration. These methods are parametrized by the type parameter clause `[´\mathit{tps}\,´]` and all value parameter clauses -`(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_{i-1}´)` preceding ´p_{i,j}´. +`(´\mathit{ps}_1´)...(´\mathit{ps}_{i-1}´)` preceding ´p_{i,j}´. The `´f\$´default´\$´n` methods are inaccessible for user programs. ###### Example @@ -717,17 +717,17 @@ _repeated_ parameter inside the method is then the sequence type `scala.Seq[´T´]`. Methods with repeated parameters `´T´*` take a variable number of arguments of type ´T´. That is, if a method ´m´ with type -`(´p_1:T_1 , \ldots , p_n:T_n, p_s:S´*)´U´` is applied to arguments -´(e_1 , \ldots , e_k)´ where ´k \geq n´, then ´m´ is taken in that application -to have type ´(p_1:T_1 , \ldots , p_n:T_n, p_s:S , \ldots , p_{s'}:S)U´, with +`(´p_1:T_1, ..., p_n:T_n, p_s:S´*)´U´` is applied to arguments +´(e_1, ..., e_k)´ where ´k \geq n´, then ´m´ is taken in that application +to have type ´(p_1:T_1, ..., p_n:T_n, p_s:S, ..., p_{s'}:S)U´, with ´k - n´ occurrences of type ´S´ where any parameter names beyond ´p_s´ are fresh. The only exception to this rule is if the last argument is marked to be a _sequence argument_ via a `_*` type annotation. If ´m´ above is applied to arguments -`(´e_1 , \ldots , e_n, e'´: _*)`, then the type of ´m´ in +`(´e_1, ..., e_n, e'´: _*)`, then the type of ´m´ in that application is taken to be -`(´p_1:T_1, \ldots , p_n:T_n,p_{s}:´scala.Seq[´S´])`. +`(´p_1:T_1, ... , p_n:T_n,p_{s}:´scala.Seq[´S´])`. It is not allowed to define any default arguments in a parameter section with a repeated parameter. @@ -875,7 +875,7 @@ _importable_ if it is [accessible](05-classes-and-objects.html#modifiers). The most general form of an import expression is a list of _import selectors_ ```scala -{ ´x_1´ => ´y_1 , \ldots , x_n´ => ´y_n´, _ } +{ ´x_1´ => ´y_1, ..., x_n´ => ´y_n´, _ } ``` for ´n \geq 0´, where the final wildcard `‘_’` may be absent. It @@ -883,7 +883,7 @@ makes available each importable member `´p´.´x_i´` under the unqualified nam ´y_i´. I.e. every import selector `´x_i´ => ´y_i´` renames `´p´.´x_i´` to ´y_i´. If a final wildcard is present, all importable members ´z´ of -´p´ other than `´x_1 , \ldots , x_n,y_1 , \ldots , y_n´` are also made available +´p´ other than `´x_1, ..., x_n,y_1, ..., y_n´` are also made available under their own unqualified names. Import selectors work in the same way for type and term members. For @@ -918,9 +918,9 @@ i.e. it makes available without qualification all members of ´p´ (this is analogous to `import ´p´.*` in Java). An import clause with multiple import expressions -`import ´p_1´.´I_1 , \ldots , p_n´.´I_n´` is interpreted as a +`import ´p_1´.´I_1, ..., p_n´.´I_n´` is interpreted as a sequence of import clauses -`import ´p_1´.´I_1´; ´\ldots´; import ´p_n´.´I_n´`. +`import ´p_1´.´I_1´; ...; import ´p_n´.´I_n´`. ###### Example Consider the object definition: diff --git a/docs/_spec/05-classes-and-objects.md b/docs/_spec/05-classes-and-objects.md index 5c3a74e608a2..88ca4de54692 100644 --- a/docs/_spec/05-classes-and-objects.md +++ b/docs/_spec/05-classes-and-objects.md @@ -31,10 +31,10 @@ A _template_ defines the type signature, behavior and initial state of a trait or class of objects or of a single object. Templates form part of instance creation expressions, class definitions, and object definitions. A template -`´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´ { ´\mathit{stats}´ }` +`´sc´ with ´mt_1´ with ... with ´mt_n´ { ´\mathit{stats}´ }` consists of a constructor invocation ´sc´ which defines the template's _superclass_, trait references -`´mt_1 , \ldots , mt_n´` ´(n \geq 0)´, which define the +`´mt_1, ..., mt_n´` ´(n \geq 0)´, which define the template's _traits_, and a statement sequence ´\mathit{stats}´ which contains initialization code and additional member definitions for the template. @@ -43,7 +43,7 @@ Each trait reference ´mt_i´ must denote a [trait](#traits). By contrast, the superclass constructor ´sc´ normally refers to a class which is not a trait. It is possible to write a list of parents that starts with a trait reference, e.g. -`´mt_1´ with ´\ldots´ with ´mt_n´`. In that case the list +`´mt_1´ with ... with ´mt_n´`. In that case the list of parents is implicitly extended to include the supertype of ´mt_1´ as the first parent type. The new supertype must have at least one constructor that does not take parameters. In the following, we will @@ -53,7 +53,7 @@ constructor, not a trait reference. The list of parents of a template must be well-formed. This means that the class denoted by the superclass constructor ´sc´ must be a -subclass of the superclasses of all the traits ´mt_1 , \ldots , mt_n´. +subclass of the superclasses of all the traits ´mt_1, ..., mt_n´. In other words, the non-trait classes inherited by a template form a chain in the inheritance hierarchy which starts with the template's superclass. @@ -155,12 +155,12 @@ Constr ::= AnnotType {‘(’ [Exprs] ‘)’} Constructor invocations define the type, members, and initial state of objects created by an instance creation expression, or of parts of an object's definition which are inherited by a class or object -definition. A constructor invocation is a function application -`´x´.´c´[´\mathit{targs}´](´\mathit{args}_1´)´\ldots´(´\mathit{args}_n´)`, where ´x´ is a +definition. A constructor invocation is a method application +`´x´.´c´[´\mathit{targs}´](´\mathit{args}_1´)...(´\mathit{args}_n´)`, where ´x´ is a [stable identifier](03-types.html#paths), ´c´ is a type name which either designates a class or defines an alias type for one, ´\mathit{targs}´ is a type argument -list, ´\mathit{args}_1 , \ldots , \mathit{args}_n´ are argument lists, and there is a -constructor of that class which is [applicable](06-expressions.html#function-applications) +list, ´\mathit{args}_1, ..., \mathit{args}_n´ are argument lists, and there is a +constructor of that class which is [applicable](06-expressions.html#method-applications) to the given arguments. If the constructor invocation uses named or default arguments, it is transformed into a block expression using the same transformation as described [here](sec:named-default). @@ -172,11 +172,11 @@ using [local type inference](06-expressions.html#local-type-inference). If no ex arguments are given, an empty list `()` is implicitly supplied. An evaluation of a constructor invocation -`´x´.´c´[´\mathit{targs}´](´\mathit{args}_1´)´\ldots´(´\mathit{args}_n´)` +`´x´.´c´[´\mathit{targs}´](´\mathit{args}_1´)...(´\mathit{args}_n´)` consists of the following steps: - First, the prefix ´x´ is evaluated. -- Then, the arguments ´\mathit{args}_1 , \ldots , \mathit{args}_n´ are evaluated from +- Then, the arguments ´\mathit{args}_1, ..., \mathit{args}_n´ are evaluated from left to right. - Finally, the class being constructed is initialized by evaluating the template of the class referred to by ´c´. @@ -193,7 +193,7 @@ Let ´C´ be a class with template ´C_1´ with ... with ´C_n´ { ´\mathit{stats}´ }`. The _linearization_ of ´C´, ´\mathcal{L}(C)´ is defined as follows: $$ -\mathcal{L}(C) = C, \mathcal{L}(C_n) \; \vec{+} \; \ldots \; \vec{+} \; \mathcal{L}(C_1) +\mathcal{L}(C) = C, \mathcal{L}(C_n) \; \vec{+} \; ... \; \vec{+} \; \mathcal{L}(C_1) $$ Here ´\vec{+}´ denotes concatenation where elements of the right operand @@ -246,7 +246,7 @@ which is not a suffix of the linearization of `Iter`. ### Class Members -A class ´C´ defined by a template `´C_1´ with ´\ldots´ with ´C_n´ { ´\mathit{stats}´ }` +A class ´C´ defined by a template `´C_1´ with ... with ´C_n´ { ´\mathit{stats}´ }` can define members in its statement sequence ´\mathit{stats}´ and can inherit members from all parent classes. Scala adopts Java and C\#'s conventions for static overloading of @@ -694,7 +694,7 @@ ClassTemplateOpt ::= ‘extends’ ClassTemplate | [[‘extends’] TemplateBo The most general form of class definition is ```scala -class ´c´[´\mathit{tps}\,´] ´as´ ´m´(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_n´) extends ´t´ ´\quad(n \geq 0)´. +class ´c´[´\mathit{tps}\,´] ´as´ ´m´(´\mathit{ps}_1´)...(´\mathit{ps}_n´) extends ´t´ ´\quad(n \geq 0)´. ``` Here, @@ -714,7 +714,7 @@ Here, - ´m´ is an [access modifier](#modifiers) such as `private` or `protected`, possibly with a qualification. If such an access modifier is given it applies to the primary constructor of the class. - - ´(\mathit{ps}\_1)\ldots(\mathit{ps}\_n)´ are formal value parameter clauses for + - ´(\mathit{ps}\_1)...(\mathit{ps}\_n)´ are formal value parameter clauses for the _primary constructor_ of the class. The scope of a formal value parameter includes all subsequent parameter sections and the template ´t´. However, a formal value parameter may not form part of the types of any of the parent classes or members of the class template ´t´. @@ -737,12 +737,12 @@ Here, - ´t´ is a [template](#templates) of the form ```scala - ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_m´ { ´\mathit{stats}´ } // ´m \geq 0´ + ´sc´ with ´mt_1´ with ... with ´mt_m´ { ´\mathit{stats}´ } // ´m \geq 0´ ``` which defines the base classes, behavior and initial state of objects of the class. The extends clause - `extends ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_m´` + `extends ´sc´ with ´mt_1´ with ... with ´mt_m´` can be omitted, in which case `extends scala.AnyRef` is assumed. The class body `{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body @@ -789,14 +789,14 @@ SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} A class may have additional constructors besides the primary constructor. These are defined by constructor definitions of the form -`def this(´\mathit{ps}_1´)´\ldots´(´\mathit{ps}_n´) = ´e´`. Such a +`def this(´\mathit{ps}_1´)...(´\mathit{ps}_n´) = ´e´`. Such a definition introduces an additional constructor for the enclosing class, with parameters as given in the formal parameter lists ´\mathit{ps}_1 -, \ldots , \mathit{ps}_n´, and whose evaluation is defined by the constructor +, ..., \mathit{ps}_n´, and whose evaluation is defined by the constructor expression ´e´. The scope of each formal parameter is the subsequent parameter sections and the constructor expression ´e´. A constructor expression is either a self constructor -invocation `this(´\mathit{args}_1´)´\ldots´(´\mathit{args}_n´)` or a block +invocation `this(´\mathit{args}_1´)...(´\mathit{args}_n´)` or a block which begins with a self constructor invocation. The self constructor invocation must construct a generic instance of the class. I.e. if the class in question has name ´C´ and type parameters @@ -861,16 +861,16 @@ implicitly added to such a parameter, unless the parameter already carries a `val` or `var` modifier. Hence, an accessor definition for the parameter is [generated](#class-definitions). -A case class definition of `´c´[´\mathit{tps}\,´](´\mathit{ps}_1\,´)´\ldots´(´\mathit{ps}_n´)` with type +A case class definition of `´c´[´\mathit{tps}\,´](´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)` with type parameters ´\mathit{tps}´ and value parameters ´\mathit{ps}´ implies the definition of a companion object, which serves as an [extractor object](08-pattern-matching.html#extractor-patterns). It has the following shape: ```scala object ´c´ { - def apply[´\mathit{tps}\,´](´\mathit{ps}_1\,´)´\ldots´(´\mathit{ps}_n´): ´c´[´\mathit{tps}\,´] = new ´c´[´\mathit{Ts}\,´](´\mathit{xs}_1\,´)´\ldots´(´\mathit{xs}_n´) + def apply[´\mathit{tps}\,´](´\mathit{ps}_1\,´)...(´\mathit{ps}_n´): ´c´[´\mathit{tps}\,´] = new ´c´[´\mathit{Ts}\,´](´\mathit{xs}_1\,´)...(´\mathit{xs}_n´) def unapply[´\mathit{tps}\,´](´x´: ´c´[´\mathit{tps}\,´]) = if (x eq null) scala.None - else scala.Some(´x.\mathit{xs}_{11}, \ldots , x.\mathit{xs}_{1k}´) + else scala.Some(´x.\mathit{xs}_{11}, ... , x.\mathit{xs}_{1k}´) } ``` @@ -878,7 +878,7 @@ Here, ´\mathit{Ts}´ stands for the vector of types defined in the type parameter section ´\mathit{tps}´, each ´\mathit{xs}\_i´ denotes the parameter names of the parameter section ´\mathit{ps}\_i´, and -´\mathit{xs}\_{11}, \ldots , \mathit{xs}\_{1k}´ denote the names of all parameters +´\mathit{xs}\_{11}, ... , \mathit{xs}\_{1k}´ denote the names of all parameters in the first parameter section ´\mathit{xs}\_1´. If a type parameter section is missing in the class, it is also missing in the `apply` and `unapply` methods. @@ -905,7 +905,7 @@ class already has a member (directly defined or inherited) with that name, or th class has a repeated parameter. The method is defined as follows: ```scala -def copy[´\mathit{tps}\,´](´\mathit{ps}'_1\,´)´\ldots´(´\mathit{ps}'_n´): ´c´[´\mathit{tps}\,´] = new ´c´[´\mathit{Ts}\,´](´\mathit{xs}_1\,´)´\ldots´(´\mathit{xs}_n´) +def copy[´\mathit{tps}\,´](´\mathit{ps}'_1\,´)...(´\mathit{ps}'_n´): ´c´[´\mathit{tps}\,´] = new ´c´[´\mathit{Ts}\,´](´\mathit{xs}_1\,´)...(´\mathit{xs}_n´) ``` Again, `´\mathit{Ts}´` stands for the vector of types defined in the type parameter section `´\mathit{tps}´` @@ -1090,11 +1090,11 @@ most general form is ´t´ is a [template](#templates) of the form ```scala -´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´ { ´\mathit{stats}´ } +´sc´ with ´mt_1´ with ... with ´mt_n´ { ´\mathit{stats}´ } ``` which defines the base classes, behavior and initial state of ´m´. -The extends clause `extends ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´` +The extends clause `extends ´sc´ with ´mt_1´ with ... with ´mt_n´` can be omitted, in which case `extends scala.AnyRef` is assumed. The class body `{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body @@ -1105,7 +1105,7 @@ conforming to the template ´t´. It is roughly equivalent to the following definition of a lazy value: ```scala -lazy val ´m´ = new ´sc´ with ´mt_1´ with ´\ldots´ with ´mt_n´ { this: ´m.type´ => ´\mathit{stats}´ } +lazy val ´m´ = new ´sc´ with ´mt_1´ with ... with ´mt_n´ { this: ´m.type´ => ´\mathit{stats}´ } ``` Note that the value defined by an object definition is instantiated diff --git a/docs/_spec/06-expressions.md b/docs/_spec/06-expressions.md index f574d7ad2469..36c31af8969c 100644 --- a/docs/_spec/06-expressions.md +++ b/docs/_spec/06-expressions.md @@ -62,12 +62,12 @@ expression: If the type of an expression would be an existential type [skolemization](03-types.html#existential-types) of ´T´. Skolemization is reversed by type packing. Assume an expression ´e´ of -type ´T´ and let ´t_1[\mathit{tps}\_1] >: L_1 <: U_1 , \ldots , t_n[\mathit{tps}\_n] >: L_n <: U_n´ be +type ´T´ and let ´t_1[\mathit{tps}\_1] >: L_1 <: U_1, ..., t_n[\mathit{tps}\_n] >: L_n <: U_n´ be all the type variables created by skolemization of some part of ´e´ which are free in ´T´. Then the _packed type_ of ´e´ is ```scala -´T´ forSome { type ´t_1[\mathit{tps}\_1] >: L_1 <: U_1´; ´\ldots´; type ´t_n[\mathit{tps}\_n] >: L_n <: U_n´ }. +´T´ forSome { type ´t_1[\mathit{tps}\_1] >: L_1 <: U_1´; ...; type ´t_n[\mathit{tps}\_n] >: L_n <: U_n´ }. ``` ## Literals @@ -246,9 +246,9 @@ ArgumentExprs ::= ‘(’ [Exprs] ‘)’ Exprs ::= Expr {‘,’ Expr} ``` -An application `´f(e_1 , \ldots , e_m)´` applies the function `´f´` to the argument expressions `´e_1, \ldots , e_m´`. For this expression to be well-typed, the function must be *applicable* to its arguments, which is defined next by case analysis on ´f´'s type. +An application `´f(e_1, ..., e_m)´` applies the function `´f´` to the argument expressions `´e_1, ..., e_m´`. For this expression to be well-typed, the function must be *applicable* to its arguments, which is defined next by case analysis on ´f´'s type. -If ´f´ has a method type `(´p_1´:´T_1 , \ldots , p_n´:´T_n´)´U´`, each argument expression ´e_i´ is typed with the corresponding parameter type ´T_i´ as expected type. Let ´S_i´ be the type of argument ´e_i´ ´(i = 1 , \ldots , m)´. The method ´f´ must be _applicable_ to its arguments ´e_1, \ldots , e_n´ of types ´S_1 , \ldots , S_n´. We say that an argument expression ´e_i´ is a _named_ argument if it has the form `´x_i=e'_i´` and `´x_i´` is one of the parameter names `´p_1, \ldots, p_n´`. +If ´f´ has a method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´`, each argument expression ´e_i´ is typed with the corresponding parameter type ´T_i´ as expected type. Let ´S_i´ be the type of argument ´e_i´ ´(i = 1, ..., m)´. The method ´f´ must be _applicable_ to its arguments ´e_1, ..., e_n´ of types ´S_1, ..., S_n´. We say that an argument expression ´e_i´ is a _named_ argument if it has the form `´x_i=e'_i´` and `´x_i´` is one of the parameter names `´p_1, ..., p_n´`. Once the types ´S_i´ have been determined, the method ´f´ of the above method type is said to be applicable if all of the following conditions hold: - for every named argument ´p_j=e_i'´ the type ´S_i´ is [compatible](03-types.html#compatibility) with the parameter type ´T_j´; @@ -258,12 +258,12 @@ Once the types ´S_i´ have been determined, the method ´f´ of the above metho If ´f´ is a polymorphic method, [local type inference](#local-type-inference) is used to instantiate ´f´'s type parameters. The polymorphic method is applicable if type inference can determine type arguments so that the instantiated method is applicable. -If ´f´ has some value type, the application is taken to be equivalent to `´f´.apply(´e_1 , \ldots , e_m´)`, +If ´f´ has some value type, the application is taken to be equivalent to `´f´.apply(´e_1, ..., e_m´)`, i.e. the application of an `apply` method defined by ´f´. The value `´f´` is applicable to the given arguments if `´f´.apply` is applicable. -The application `´f´(´e_1 , \ldots , e_n´)` evaluates ´f´ and then each argument -´e_1 , \ldots , e_n´ from left to right, except for arguments that correspond to +The application `´f´(´e_1, ..., e_n´)` evaluates ´f´ and then each argument +´e_1, ..., e_n´ from left to right, except for arguments that correspond to a by-name parameter (see below). Each argument expression is converted to the type of its corresponding formal parameter. After that, the application is rewritten to the function's right hand side, with actual arguments substituted @@ -338,7 +338,7 @@ If an application is to use named arguments ´p = e´ or default arguments, the following conditions must hold. - For every named argument ´p_i = e_i´ which appears left of a positional argument - in the argument list ´e_1 \ldots e_m´, the argument position ´i´ coincides with + in the argument list ´e_1 ... e_m´, the argument position ´i´ coincides with the position of parameter ´p_i´ in the parameter list of the applied method. - The names ´x_i´ of all named arguments are pairwise distinct and no named argument defines a parameter which is already specified by a @@ -367,16 +367,16 @@ the form ```scala { val q = ´p´ val ´x_1´ = expr´_1´ - ´\ldots´ + ... val ´x_k´ = expr´_k´ - q.´m´[´\mathit{targs}´](´\mathit{args}_1´)´, \ldots ,´(´\mathit{args}_l´) + q.´m´[´\mathit{targs}´](´\mathit{args}_1´), ...,(´\mathit{args}_l´) } ``` -where every argument in ´(\mathit{args}\_1) , \ldots , (\mathit{args}\_l)´ is a reference to -one of the values ´x_1 , \ldots , x_k´. To integrate the current application +where every argument in ´(\mathit{args}\_1), ..., (\mathit{args}\_l)´ is a reference to +one of the values ´x_1, ..., x_k´. To integrate the current application into the block, first a value definition using a fresh name ´y_i´ is created -for every argument in ´e_1 , \ldots , e_m´, which is initialised to ´e_i´ for +for every argument in ´e_1, ..., e_m´, which is initialised to ´e_i´ for positional arguments and to ´e'_i´ for named arguments of the form `´x_i=e'_i´`. Then, for every parameter which is not specified by the argument list, a value definition using a fresh name ´z_i´ is created, @@ -386,33 +386,33 @@ this parameter. Let ´\mathit{args}´ be a permutation of the generated names ´y_i´ and ´z_i´ such such that the position of each name matches the position of its corresponding -parameter in the method type `(´p_1:T_1 , \ldots , p_n:T_n´)´U´`. +parameter in the method type `(´p_1:T_1, ..., p_n:T_n´)´U´`. The final result of the transformation is a block of the form ```scala { val q = ´p´ val ´x_1´ = expr´_1´ - ´\ldots´ + ... val ´x_l´ = expr´_k´ val ´y_1´ = ´e_1´ - ´\ldots´ + ... val ´y_m´ = ´e_m´ - val ´z_1´ = ´q.m\$default\$i[\mathit{targs}](\mathit{args}_1), \ldots ,(\mathit{args}_l)´ - ´\ldots´ - val ´z_d´ = ´q.m\$default\$j[\mathit{targs}](\mathit{args}_1), \ldots ,(\mathit{args}_l)´ - q.´m´[´\mathit{targs}´](´\mathit{args}_1´)´, \ldots ,´(´\mathit{args}_l´)(´\mathit{args}´) + val ´z_1´ = ´q.m\$default\$i[\mathit{targs}](\mathit{args}_1), ..., (\mathit{args}_l)´ + ... + val ´z_d´ = ´q.m\$default\$j[\mathit{targs}](\mathit{args}_1), ..., (\mathit{args}_l)´ + q.´m´[´\mathit{targs}´](´\mathit{args}_1´), ..., (´\mathit{args}_l´)(´\mathit{args}´) } ``` ### Signature Polymorphic Methods -For invocations of signature polymorphic methods of the target platform `´f´(´e_1 , \ldots , e_m´)`, -the invoked method has a different method type `(´p_1´:´T_1 , \ldots , p_n´:´T_n´)´U´` at each call -site. The parameter types `´T_ , \ldots , T_n´` are the types of the argument expressions -`´e_1 , \ldots , e_m´`. If the declared return type `´R´` of the signature polymorphic method is +For invocations of signature polymorphic methods of the target platform `´f´(´e_1, ..., e_m´)`, +the invoked method has a different method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´` at each call +site. The parameter types `´T_, ..., T_n´` are the types of the argument expressions +`´e_1, ..., e_m´`. If the declared return type `´R´` of the signature polymorphic method is any type other than `scala.AnyRef`, then the return type `´U´` is `´R´`. Otherwise, `´U´` is the expected type at the call site. If the expected type is undefined then -`´U´` is `scala.AnyRef`. The parameter names `´p_1 , \ldots , p_n´` are fresh. +`´U´` is `scala.AnyRef`. The parameter names `´p_1, ..., p_n´` are fresh. ###### Note @@ -456,19 +456,19 @@ because otherwise the underscore would be considered part of the name. SimpleExpr ::= SimpleExpr TypeArgs ``` -A _type application_ `´e´[´T_1 , \ldots , T_n´]` instantiates +A _type application_ `´e´[´T_1, ..., T_n´]` instantiates a polymorphic value ´e´ of type -`[´a_1´ >: ´L_1´ <: ´U_1, \ldots , a_n´ >: ´L_n´ <: ´U_n´]´S´` +`[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´` with argument types -`´T_1 , \ldots , T_n´`. Every argument type ´T_i´ must obey +`´T_1, ..., T_n´`. Every argument type ´T_i´ must obey the corresponding bounds ´L_i´ and ´U_i´. That is, for each ´i = 1 -, \ldots , n´, we must have ´\sigma L_i <: T_i <: \sigma -U_i´, where ´\sigma´ is the substitution ´[a_1 := T_1 , \ldots , a_n +, ..., n´, we must have ´\sigma L_i <: T_i <: \sigma +U_i´, where ´\sigma´ is the substitution ´[a_1 := T_1, ..., a_n := T_n]´. The type of the application is ´\sigma S´. If the function part ´e´ is of some value type, the type application is taken to be equivalent to -`´e´.apply[´T_1 , \ldots ,´ T´_n´]`, i.e. the application of an `apply` method defined by +`´e´.apply[´T_1 , ...,´ T´_n´]`, i.e. the application of an `apply` method defined by ´e´. Type applications can be omitted if @@ -482,9 +482,9 @@ and the expected result type. SimpleExpr ::= ‘(’ [Exprs] ‘)’ ``` -A _tuple expression_ `(´e_1 , \ldots , e_n´)` is an alias +A _tuple expression_ `(´e_1´, ..., ´e_n´)` is an alias for the class instance creation -`scala.Tuple´n´(´e_1 , \ldots , e_n´)`, where ´n \geq 2´. +`scala.Tuple´n´(´e_1´, ..., ´e_n´)`, where ´n \geq 2´. The empty tuple `()` is the unique value of type `scala.Unit`. @@ -562,8 +562,8 @@ BlockExpr ::= ‘{’ CaseClauses ‘}’ Block ::= BlockStat {semi BlockStat} [ResultExpr] ``` -A _block expression_ `{´s_1´; ´\ldots´; ´s_n´; ´e\,´}` is -constructed from a sequence of block statements ´s_1 , \ldots , s_n´ +A _block expression_ `{´s_1´; ...; ´s_n´; ´e\,´}` is +constructed from a sequence of block statements ´s_1, ..., s_n´ and a final expression ´e´. The statement sequence may not contain two definitions or declarations that bind the same name in the same namespace. The final expression can be omitted, in which @@ -573,11 +573,11 @@ The expected type of the final expression ´e´ is the expected type of the block. The expected type of all preceding statements is undefined. -The type of a block `´s_1´; ´\ldots´; ´s_n´; ´e´` is +The type of a block `´s_1´; ...; ´s_n´; ´e´` is `´T´ forSome {´\,Q\,´}`, where ´T´ is the type of ´e´ and ´Q´ contains [existential clauses](03-types.html#existential-types) for every value or type name which is free in ´T´ -and which is defined locally in one of the statements ´s_1 , \ldots , s_n´. +and which is defined locally in one of the statements ´s_1, ..., s_n´. We say the existential clause _binds_ the occurrence of the value or type name. Specifically, @@ -599,7 +599,7 @@ Evaluation of the block entails evaluation of its statement sequence, followed by an evaluation of the final expression ´e´, which defines the result of the block. -A block expression `{´c_1´; ´\ldots´; ´c_n´}` where ´s_1 , \ldots , s_n´ are +A block expression `{´c_1´; ...; ´c_n´}` where ´s_1, ..., s_n´ are case clauses forms a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions). ###### Example @@ -696,22 +696,22 @@ parts of an expression as follows. expression, then operators with higher precedence bind more closely than operators with lower precedence. - If there are consecutive infix - operations ´e_0; \mathit{op}\_1; e_1; \mathit{op}\_2 \ldots \mathit{op}\_n; e_n´ - with operators ´\mathit{op}\_1 , \ldots , \mathit{op}\_n´ of the same precedence, + operations ´e_0; \mathit{op}\_1; e_1; \mathit{op}\_2 ... \mathit{op}\_n; e_n´ + with operators ´\mathit{op}\_1, ..., \mathit{op}\_n´ of the same precedence, then all these operators must have the same associativity. If all operators are left-associative, the sequence is interpreted as - ´(\ldots(e_0;\mathit{op}\_1;e_1);\mathit{op}\_2\ldots);\mathit{op}\_n;e_n´. + ´(...(e_0;\mathit{op}\_1;e_1);\mathit{op}\_2...);\mathit{op}\_n;e_n´. Otherwise, if all operators are right-associative, the sequence is interpreted as - ´e_0;\mathit{op}\_1;(e_1;\mathit{op}\_2;(\ldots \mathit{op}\_n;e_n)\ldots)´. + ´e_0;\mathit{op}\_1;(e_1;\mathit{op}\_2;(... \mathit{op}\_n;e_n)...)´. - Postfix operators always have lower precedence than infix operators. E.g. ´e_1;\mathit{op}\_1;e_2;\mathit{op}\_2´ is always equivalent to ´(e_1;\mathit{op}\_1;e_2);\mathit{op}\_2´. The right-hand operand of a left-associative operator may consist of -several arguments enclosed in parentheses, e.g. ´e;\mathit{op};(e_1,\ldots,e_n)´. -This expression is then interpreted as ´e.\mathit{op}(e_1,\ldots,e_n)´. +several arguments enclosed in parentheses, e.g. ´e;\mathit{op};(e_1,...,e_n)´. +This expression is then interpreted as ´e.\mathit{op}(e_1,...,e_n)´. A left-associative binary operation ´e_1;\mathit{op};e_2´ is interpreted as ´e_1.\mathit{op}(e_2)´. If ´\mathit{op}´ is @@ -778,8 +778,8 @@ Here are examples of well-typed and ill-typed expressions. Expr1 ::= PostfixExpr ‘:’ Annotation {Annotation} ``` -An _annotated expression_ `´e´: @´a_1´ ´\ldots´ @´a_n´` -attaches [annotations](11-annotations.html#user-defined-annotations) ´a_1 , \ldots , a_n´ to the +An _annotated expression_ `´e´: @´a_1´ ... @´a_n´` +attaches [annotations](11-annotations.html#user-defined-annotations) ´a_1, ..., a_n´ to the expression ´e´. ## Assignments @@ -977,35 +977,35 @@ comprehensions have been eliminated. - A for comprehension ```scala - for (´p´ <- ´e´; ´p'´ <- ´e'; \ldots´) yield ´e''´ + for (´p´ <- ´e´; ´p'´ <- ´e'; ...´) yield ´e''´ ``` - where `´\ldots´` is a (possibly empty) + where `...` is a (possibly empty) sequence of generators, definitions, or guards, is translated to ```scala - ´e´.flatMap { case ´p´ => for (´p'´ <- ´e'; \ldots´) yield ´e''´ } + ´e´.flatMap { case ´p´ => for (´p'´ <- ´e'; ...´) yield ´e''´ } ``` - A for loop ```scala - for (´p´ <- ´e´; ´p'´ <- ´e'; \ldots´) ´e''´ + for (´p´ <- ´e´; ´p'´ <- ´e'; ...´) ´e''´ ``` - where `´\ldots´` is a (possibly empty) + where `...` is a (possibly empty) sequence of generators, definitions, or guards, is translated to ```scala - ´e´.foreach { case ´p´ => for (´p'´ <- ´e'; \ldots´) ´e''´ } + ´e´.foreach { case ´p´ => for (´p'´ <- ´e'; ...´) ´e''´ } ``` - A generator `´p´ <- ´e´` followed by a guard `if ´g´` is translated to a single generator - `´p´ <- ´e´.withFilter((´x_1 , \ldots , x_n´) => ´g\,´)` where - ´x_1 , \ldots , x_n´ are the free variables of ´p´. + `´p´ <- ´e´.withFilter((´x_1, ..., x_n´) => ´g\,´)` where + ´x_1, ..., x_n´ are the free variables of ´p´. - A generator `´p´ <- ´e´` followed by a value definition `´p'´ = ´e'´` is translated to the following generator of pairs of values, where @@ -1137,7 +1137,7 @@ where the handler ´h´ is usually a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions) ```scala -{ case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ } +{ case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` This expression is evaluated by evaluating the block @@ -1187,7 +1187,7 @@ Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’ Binding ::= (id | ‘_’) [‘:’ Type] ``` -The anonymous function of arity ´n´, `(´x_1´: ´T_1 , \ldots , x_n´: ´T_n´) => e` maps parameters ´x_i´ of types ´T_i´ to a result given by expression ´e´. The scope of each formal parameter ´x_i´ is ´e´. Formal parameters must have pairwise distinct names. +The anonymous function of arity ´n´, `(´x_1´: ´T_1, ..., x_n´: ´T_n´) => e` maps parameters ´x_i´ of types ´T_i´ to a result given by expression ´e´. The scope of each formal parameter ´x_i´ is ´e´. Formal parameters must have pairwise distinct names. In the case of a single untyped formal parameter, `(´x\,´) => ´e´` can be abbreviated to `´x´ => ´e´`. If an anonymous function `(´x´: ´T\,´) => ´e´` with a single typed parameter appears as the result expression of a block, it can be abbreviated to `´x´: ´T´ => e`. @@ -1196,12 +1196,12 @@ A formal parameter may also be a wildcard represented by an underscore `_`. In t A named parameter of an anonymous function may be optionally preceded by an `implicit` modifier. In that case the parameter is labeled [`implicit`](07-implicits.html#implicit-parameters-and-views); however the parameter section itself does not count as an [implicit parameter section](07-implicits.html#implicit-parameters). Hence, arguments to anonymous functions always have to be given explicitly. ### Translation -If the expected type of the anonymous function is of the shape `scala.Function´n´[´S_1 , \ldots , S_n´, ´R\,´]`, or can be [SAM-converted](#sam-conversion) to such a function type, the type `´T_i´` of a parameter `´x_i´` can be omitted, as far as `´S_i´` is defined in the expected type, and `´T_i´ = ´S_i´` is assumed. Furthermore, the expected type when type checking ´e´ is ´R´. +If the expected type of the anonymous function is of the shape `scala.Function´n´[´S_1´, ..., ´S_n´, ´R\,´]`, or can be [SAM-converted](#sam-conversion) to such a function type, the type `´T_i´` of a parameter `´x_i´` can be omitted, as far as `´S_i´` is defined in the expected type, and `´T_i´ = ´S_i´` is assumed. Furthermore, the expected type when type checking ´e´ is ´R´. -If there is no expected type for the function literal, all formal parameter types `´T_i´` must be specified explicitly, and the expected type of ´e´ is undefined. The type of the anonymous function is `scala.Function´n´[´T_1 , \ldots , T_n´, ´R\,´]`, where ´R´ is the [packed type](#expression-typing) of ´e´. ´R´ must be equivalent to a type which does not refer to any of the formal parameters ´x_i´. +If there is no expected type for the function literal, all formal parameter types `´T_i´` must be specified explicitly, and the expected type of ´e´ is undefined. The type of the anonymous function is `scala.Function´n´[´T_1´, ..., ´T_n´, ´R\,´]`, where ´R´ is the [packed type](#expression-typing) of ´e´. ´R´ must be equivalent to a type which does not refer to any of the formal parameters ´x_i´. The eventual run-time value of an anonymous function is determined by the expected type: - - a subclass of one of the builtin function types, `scala.Function´n´[´S_1 , \ldots , S_n´, ´R\,´]` (with ´S_i´ and ´R´ fully defined), + - a subclass of one of the builtin function types, `scala.Function´n´[´S_1, ..., S_n´, ´R\,´]` (with ´S_i´ and ´R´ fully defined), - a [single-abstract-method (SAM) type](#sam-conversion); - `PartialFunction[´T´, ´U´]` - some other type. @@ -1209,8 +1209,8 @@ The eventual run-time value of an anonymous function is determined by the expect The standard anonymous function evaluates in the same way as the following instance creation expression: ```scala -new scala.Function´n´[´T_1 , \ldots , T_n´, ´T´] { - def apply(´x_1´: ´T_1 , \ldots , x_n´: ´T_n´): ´T´ = ´e´ +new scala.Function´n´[´T_1, ..., T_n´, ´T´] { + def apply(´x_1´: ´T_1, ..., x_n´: ´T_n´): ´T´ = ´e´ } ``` @@ -1220,7 +1220,7 @@ The underlying platform may provide more efficient ways of constructing these in When a `PartialFunction` is required, an additional member `isDefinedAt` is synthesized, which simply returns `true`. -However, if the function literal has the shape `x => x match { $\ldots$ }`, +However, if the function literal has the shape `x => x match { $...$ }`, then `isDefinedAt` is derived from the pattern match in the following way: each case from the match expression evaluates to `true`, and if there is no default case, @@ -1268,7 +1268,7 @@ An expression ´e´ of syntactic category `Expr` _binds_ an underscore section (2) there is no other expression of syntactic category `Expr` which is properly contained in ´e´ and which itself properly contains ´u´. -If an expression ´e´ binds underscore sections ´u_1 , \ldots , u_n´, in this order, it is equivalent to +If an expression ´e´ binds underscore sections ´u_1, ..., u_n´, in this order, it is equivalent to the anonymous function `(´u'_1´, ... ´u'_n´) => ´e'´` where each ´u_i'´ results from ´u_i´ by replacing the underscore with a fresh identifier and ´e'´ results from ´e´ by replacing each underscore section ´u_i´ by ´u_i'´. @@ -1296,7 +1296,7 @@ include at least the expressions of the following forms: - A string literal - A class constructed with [`Predef.classOf`](12-the-scala-standard-library.html#the-predef-object) - An element of an enumeration from the underlying platform -- A literal array, of the form `Array´(c_1 , \ldots , c_n)´`, +- A literal array, of the form `Array´(c_1, ..., c_n)´`, where all of the ´c_i´'s are themselves constant expressions - An identifier defined by a [constant value definition](04-basic-declarations-and-definitions.html#value-declarations-and-definitions). @@ -1354,16 +1354,16 @@ is applied to pick a unique member. An expression ´e´ of polymorphic type ```scala -[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´ +[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´ ``` which does not appear as the function part of a type application is converted to a type instance of ´T´ by determining with [local type inference](#local-type-inference) -instance types `´T_1 , \ldots , T_n´` -for the type variables `´a_1 , \ldots , a_n´` and +instance types `´T_1, ..., T_n´` +for the type variables `´a_1, ..., a_n´` and implicitly embedding ´e´ in the [type application](#type-applications) -`´e´[´T_1 , \ldots , T_n´]`. +`´e´[´T_1, ..., T_n´]`. ###### Numeric Widening If ´e´ has a primitive number type which [weakly conforms](03-types.html#weak-conformance) @@ -1456,24 +1456,24 @@ member. The way this is done depends on whether or not ´e´ is used as a function. Let ´\mathscr{A}´ be the set of members referenced by ´e´. Assume first that ´e´ appears as a function in an application, as in -`´e´(´e_1 , \ldots , e_m´)`. +`´e´(´e_1´, ..., ´e_m´)`. One first determines the set of functions that is potentially [applicable](#function-applications) based on the _shape_ of the arguments. The *shape* of an argument expression ´e´, written ´\mathit{shape}(e)´, is a type that is defined as follows: - - For a function expression `(´p_1´: ´T_1 , \ldots , p_n´: ´T_n´) => ´b´: (Any ´, \ldots ,´ Any) => ´\mathit{shape}(b)´`, + - For a function expression `(´p_1´: ´T_1, ..., p_n´: ´T_n´) => ´b´: (Any, ..., Any) => ´\mathit{shape}(b)´`, where `Any` occurs ´n´ times in the argument type. - For a pattern-matching anonymous function definition `{ case ... }`: `PartialFunction[Any, Nothing]`. - For a named argument `´n´ = ´e´`: ´\mathit{shape}(e)´. - For all other expressions: `Nothing`. Let ´\mathscr{B}´ be the set of alternatives in ´\mathscr{A}´ that are [_applicable_](#function-applications) -to expressions ´(e_1 , \ldots , e_n)´ of types ´(\mathit{shape}(e_1) , \ldots , \mathit{shape}(e_n))´. +to expressions ´(e_1, ..., e_n)´ of types ´(\mathit{shape}(e_1), ..., \mathit{shape}(e_n))´. If there is precisely one alternative in ´\mathscr{B}´, that alternative is chosen. -Otherwise, let ´S_1 , \ldots , S_m´ be the list of types obtained by typing each argument as follows. +Otherwise, let ´S_1, ..., S_m´ be the list of types obtained by typing each argument as follows. Normally, an argument is typed without an expected type, except when all alternatives explicitly specify the same parameter type for this argument (a missing parameter type, @@ -1501,12 +1501,12 @@ given `´k´`. Then, the expected type for `´e_i´` is derived as follows: (and a potentially varying result type), the expected type encodes these argument types and the SAM class. For every member ´m´ in ´\mathscr{B}´ one determines whether it is applicable -to expressions (´e_1 , \ldots , e_m´) of types ´S_1, \ldots , S_m´. +to expressions (´e_1, ..., e_m´) of types ´S_1, ..., S_m´. It is an error if none of the members in ´\mathscr{B}´ is applicable. If there is one single applicable alternative, that alternative is chosen. Otherwise, let ´\mathscr{CC}´ be the set of applicable alternatives which don't employ any default argument -in the application to ´e_1 , \ldots , e_m´. +in the application to ´e_1, ..., e_m´. It is again an error if ´\mathscr{CC}´ is empty. Otherwise, one chooses the _most specific_ alternative among the alternatives @@ -1524,20 +1524,20 @@ question: given so the method is not more specific than the value. --> -- A parameterized method ´m´ of type `(´p_1:T_1, \ldots , p_n:T_n´)´U´` is +- A parameterized method ´m´ of type `(´p_1:T_1, ..., p_n:T_n´)´U´` is _as specific as_ some other member ´m'´ of type ´S´ if ´m'´ is [applicable](#function-applications) - to arguments `(´p_1 , \ldots , p_n´)` of types ´T_1 , \ldots , T_n´. -- A polymorphic method of type `[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´` is + to arguments `(´p_1, ..., p_n´)` of types ´T_1, ..., T_n´. +- A polymorphic method of type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´` is as specific as some other member of type ´S´ if ´T´ is as specific as ´S´ - under the assumption that for ´i = 1 , \ldots , n´ each ´a_i´ is an abstract type name + under the assumption that for ´i = 1, ..., n´ each ´a_i´ is an abstract type name bounded from below by ´L_i´ and from above by ´U_i´. - A member of any other type is always as specific as a parameterized method or a polymorphic method. - Given two members of types ´T´ and ´U´ which are neither parameterized nor polymorphic method types, the member of type ´T´ is as specific as the member of type ´U´ if the existential dual of ´T´ conforms to the existential dual of ´U´. Here, the existential dual of a polymorphic type - `[´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´` is - `´T´ forSome { type ´a_1´ >: ´L_1´ <: ´U_1´ ´, \ldots ,´ type ´a_n´ >: ´L_n´ <: ´U_n´}`. + `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´` is + `´T´ forSome { type ´a_1´ >: ´L_1´ <: ´U_1´, ..., type ´a_n´ >: ´L_n´ <: ´U_n´}`. The existential dual of every other type is the type itself. The _relative weight_ of an alternative ´A´ over an alternative ´B´ is a @@ -1580,8 +1580,8 @@ Consider the following definitions: ```scala class A extends B {} -def f(x: B, y: B) = ´\ldots´ -def f(x: A, y: B) = ´\ldots´ +def f(x: B, y: B) = ... +def f(x: A, y: B) = ... val a: A val b: B ``` @@ -1591,7 +1591,7 @@ definition of ´f´ whereas the application `f(a, a)` refers to the second. Assume now we add a third overloaded definition ```scala -def f(x: B, y: A) = ´\ldots´ +def f(x: B, y: A) = ... ``` Then the application `f(a, a)` is rejected for being ambiguous, since @@ -1600,12 +1600,12 @@ no most specific applicable signature exists. ### Local Type Inference Local type inference infers type arguments to be passed to expressions -of polymorphic type. Say ´e´ is of type [´a_1´ >: ´L_1´ <: ´U_1, \ldots , a_n´ >: ´L_n´ <: ´U_n´]´T´ +of polymorphic type. Say ´e´ is of type [´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´ and no explicit type parameters are given. Local type inference converts this expression to a type -application `´e´[´T_1 , \ldots , T_n´]`. The choice of the -type arguments ´T_1 , \ldots , T_n´ depends on the context in which +application `´e´[´T_1, ..., T_n´]`. The choice of the +type arguments ´T_1, ..., T_n´ depends on the context in which the expression appears and on the expected type ´\mathit{pt}´. There are three cases. @@ -1613,9 +1613,9 @@ There are three cases. If the expression appears as the prefix of a selection with a name ´x´, then type inference is _deferred_ to the whole expression ´e.x´. That is, if ´e.x´ has type ´S´, it is now treated as having -type [´a_1´ >: ´L_1´ <: ´U_1 , \ldots , a_n´ >: ´L_n´ <: ´U_n´]´S´, +type [´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´, and local type inference is applied in turn to infer type arguments -for ´a_1 , \ldots , a_n´, using the context in which ´e.x´ appears. +for ´a_1, ..., a_n´, using the context in which ´e.x´ appears. ###### Case 2: Values If the expression ´e´ appears as a value without being applied to @@ -1631,7 +1631,7 @@ parameters ´a_i´ such that unless it is a singleton type corresponding to an object or a constant value definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. - All type parameter bounds are respected, i.e. - ´\sigma L_i <: \sigma a_i´ and ´\sigma a_i <: \sigma U_i´ for ´i = 1 , \ldots , n´. + ´\sigma L_i <: \sigma a_i´ and ´\sigma a_i <: \sigma U_i´ for ´i = 1, ..., n´. - The expression's type conforms to the expected type, i.e. ´\sigma T <: \sigma \mathit{pt}´. @@ -1647,21 +1647,21 @@ an _optimal solution_ of the given constraint system for the type ´T´. ###### Case 3: Methods The last case applies if the expression -´e´ appears in an application ´e(d_1 , \ldots , d_m)´. In that case -´T´ is a method type ´(p_1:R_1 , \ldots , p_m:R_m)T'´. Without loss of +´e´ appears in an application ´e(d_1, ..., d_m)´. In that case +´T´ is a method type ´(p_1:R_1, ..., p_m:R_m)T'´. Without loss of generality we can assume that the result type ´T'´ is a value type; if it is a method type we apply [eta-expansion](#eta-expansion-section) to convert it to a function type. One computes first the types ´S_j´ of the argument expressions ´d_j´, using two alternative schemes. Each argument expression ´d_j´ is typed first with the expected type ´R_j´, -in which the type parameters ´a_1 , \ldots , a_n´ are taken as type +in which the type parameters ´a_1, ..., a_n´ are taken as type constants. If this fails, the argument ´d_j´ is typed instead with an expected type ´R_j'´ which results from ´R_j´ by replacing every type -parameter in ´a_1 , \ldots , a_n´ with _undefined_. +parameter in ´a_1, ..., a_n´ with _undefined_. In a second step, type arguments are inferred by solving a constraint system which relates the method's type with the expected type -´\mathit{pt}´ and the argument types ´S_1 , \ldots , S_m´. Solving the +´\mathit{pt}´ and the argument types ´S_1, ..., S_m´. Solving the constraint system means finding a substitution ´\sigma´ of types ´T_i´ for the type parameters ´a_i´ such that @@ -1670,11 +1670,11 @@ finding a substitution ´\sigma´ of types ´T_i´ for the type parameters unless it is a singleton type corresponding to an object or a constant value definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. - All type parameter bounds are respected, i.e. ´\sigma L_i <: \sigma a_i´ and - ´\sigma a_i <: \sigma U_i´ for ´i = 1 , \ldots , n´. + ´\sigma a_i <: \sigma U_i´ for ´i = 1, ..., n´. - The method's result type ´T'´ conforms to the expected type, i.e. ´\sigma T' <: \sigma \mathit{pt}´. - Each argument type [weakly conforms](03-types.html#weak-conformance) to the corresponding formal parameter - type, i.e. ´\sigma S_j <:_w \sigma R_j´ for ´j = 1 , \ldots , m´. + type, i.e. ´\sigma S_j <:_w \sigma R_j´ for ´j = 1, ..., m´. It is a compile time error if no such substitution exists. If several solutions exist, an optimal one for the type ´T'´ is chosen. @@ -1788,18 +1788,18 @@ _Eta-expansion_ converts an expression of method type to an equivalent expression of function type. It proceeds in two steps. First, one identifies the maximal sub-expressions of ´e´; let's -say these are ´e_1 , \ldots , e_m´. For each of these, one creates a +say these are ´e_1, ..., e_m´. For each of these, one creates a fresh name ´x_i´. Let ´e'´ be the expression resulting from replacing every maximal subexpression ´e_i´ in ´e´ by the corresponding fresh name ´x_i´. Second, one creates a fresh name ´y_i´ -for every argument type ´T_i´ of the method (´i = 1 , \ldots , +for every argument type ´T_i´ of the method (´i = 1 , ..., n´). The result of eta-conversion is then: ```scala { val ´x_1´ = ´e_1´; - ´\ldots´ + ... val ´x_m´ = ´e_m´; - (´y_1: T_1 , \ldots , y_n: T_n´) => ´e'´(´y_1 , \ldots , y_n´) + (´y_1: T_1, ..., y_n: T_n´) => ´e'´(´y_1, ..., y_n´) } ``` diff --git a/docs/_spec/07-implicits.md b/docs/_spec/07-implicits.md index 6f38fdd48074..47dc4ca0b0d4 100644 --- a/docs/_spec/07-implicits.md +++ b/docs/_spec/07-implicits.md @@ -45,7 +45,7 @@ object Monoids { ## 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 ´p_1´,...,´p_n´)` of a method marks the parameters ´p_1, ..., p_n´ as implicit. A method or constructor can have only one implicit parameter list, and it must be the last parameter list given. @@ -71,18 +71,18 @@ Here, we say a class ´C´ is _associated_ with a type ´T´ if it is a [base cl 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 compound type `´T_1´ with ... with ´T_n´`, + the union of the parts of ´T_1, ..., T_n´, as well as ´T´ itself; +- if ´T´ is a parameterized type `´S´[´T_1, ..., T_n´]`, + the union of the parts of ´S´ and ´T_1, ..., 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´; +- if ´T´ denotes an implicit conversion to a type with a method with argument types ´T_1, ..., T_n´ and result type ´U´, + the union of the parts of ´T_1, ..., T_n´ and ´U´; - the parts of quantified (existential or universal) 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. @@ -268,7 +268,7 @@ 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)´. +- For a compound type, `´\mathit{ttcs}(T_1´ with ... with ´T_n)´` ´~=~ \mathit{ttcs}(T_1) \cup ... \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: @@ -277,7 +277,7 @@ the type: - 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)´ +- For a compound type, `´\operatorname{complexity}(T_1´ with ... with ´T_n)´` ´= \Sigma\operatorname{complexity}(T_i)´ The _covering set_ ´\mathit{cs}(T)´ of a type ´T´ is the set of type designators mentioned in a type. For example, given the following, @@ -495,31 +495,31 @@ Then the following rules apply. 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 +1. If ´T´ is some other class type ´S´#´C[U_1, ..., 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´, + manifests determined for ´M'[U_1], ..., M'[U_n]´. +1. If ´T´ is some other class type with type arguments ´U_1, ..., 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]´. + manifests determined for ´M'[U_1], ..., 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´` + `´T_1´ with ... 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]´. + determined for ´M[T_1], ..., 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´. + of the types ´T_1, ..., 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/docs/_spec/08-pattern-matching.md b/docs/_spec/08-pattern-matching.md index 53dc3ffe4547..f7203e831438 100644 --- a/docs/_spec/08-pattern-matching.md +++ b/docs/_spec/08-pattern-matching.md @@ -194,20 +194,20 @@ one is a variable pattern. SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ ``` -A _constructor pattern_ is of the form ´c(p_1 , \ldots , p_n)´ where ´n +A _constructor pattern_ is of the form ´c(p_1, ..., p_n)´ where ´n \geq 0´. It consists of a stable identifier ´c´, followed by element -patterns ´p_1 , \ldots , p_n´. The constructor ´c´ is a simple or +patterns ´p_1, ..., p_n´. The constructor ´c´ is a simple or qualified name which denotes a [case class](05-classes-and-objects.html#case-classes). If the case class is monomorphic, then it must conform to the expected type of the pattern, and the formal parameter types of ´x´'s [primary constructor](05-classes-and-objects.html#class-definitions) -are taken as the expected types of the element patterns ´p_1, \ldots , +are taken as the expected types of the element patterns ´p_1, ..., p_n´. If the case class is polymorphic, then its type parameters are instantiated so that the instantiation of ´c´ conforms to the expected type of the pattern. The instantiated formal parameter types of ´c´'s primary constructor are then taken as the expected types of the -component patterns ´p_1, \ldots , p_n´. The pattern matches all -objects created from constructor invocations ´c(v_1 , \ldots , v_n)´ +component patterns ´p_1, ..., p_n´. The pattern matches all +objects created from constructor invocations ´c(v_1, ..., v_n)´ where each element pattern ´p_i´ matches the corresponding value ´v_i´. @@ -220,8 +220,8 @@ repeated parameter. This is further discussed [here](#pattern-sequences). SimplePattern ::= ‘(’ [Patterns] ‘)’ ``` -A _tuple pattern_ `(´p_1 , \ldots , p_n´)` is an alias -for the constructor pattern `scala.Tuple´n´(´p_1 , \ldots , p_n´)`, +A _tuple pattern_ `(´p_1´, ..., ´p_n´)` is an alias +for the constructor pattern `scala.Tuple´n´(´p_1´, ..., ´p_n´)`, where ´n \geq 2´. The empty tuple `()` is the unique value of type `scala.Unit`. @@ -231,7 +231,7 @@ where ´n \geq 2´. The empty tuple SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ ``` -An _extractor pattern_ ´x(p_1 , \ldots , p_n)´ where ´n \geq 0´ is of +An _extractor pattern_ ´x(p_1, ..., p_n)´ where ´n \geq 0´ is of the same syntactic form as a constructor pattern. However, instead of a case class, the stable identifier ´x´ denotes an object which has a member method named `unapply` or `unapplySeq` that matches @@ -245,7 +245,7 @@ method `get` with return type `T`, and a method `isEmpty` with a return type that conforms to `Boolean`. `Option[T]` is an extractor type for type `T`. An `unapply` method in an object ´x´ _matches_ the pattern -´x(p_1 , \ldots , p_n)´ if it has a single parameter (and, optionally, an +´x(p_1, ..., p_n)´ if it has a single parameter (and, optionally, an implicit parameter list) and one of the following applies: * ´n=0´ and `unapply`'s result type conforms to `Boolean`. In this case @@ -257,18 +257,18 @@ implicit parameter list) and one of the following applies: values ´v´ for which `´x´.unapply(´v´)` yields a value ´u´ for which `´u´.isEmpty` yields `false`, `´u´.get` yields a value ´v_1´, and ´p_1´ matches ´v_1´. * ´n>1´ and `unapply`'s result type is - an extractor type for some type ´T´ with members ´\_1 , \ldots , \_n´ returning - types ´T_1 , \ldots , T_n´. In this case, the argument patterns ´p_1 - , \ldots , p_n´ are typed in turn with expected types ´T_1 , \ldots , + an extractor type for some type ´T´ with members ´\_1, ..., \_n´ returning + types ´T_1, ..., T_n´. In this case, the argument patterns ´p_1 + , ..., p_n´ are typed in turn with expected types ´T_1 , ..., T_n´. The extractor pattern matches then all values ´v´ for which `´x´.unapply(´v´)` yields a value ´u´ for which `´u´.isEmpty` yields `false`, `´u´.get` yields some value ´t´, and each pattern ´p_i´ matches the corresponding value ´t._1´ from - ´t._1 , \ldots , t._n´. + ´t._1, ..., t._n´. An `unapplySeq` method in an object ´x´ matches the pattern -´x(q_1 , \ldots , q_m, p_1 , \ldots , p_n)´ if it takes exactly one argument -and its result type is of the form `Option[(´T_1 , \ldots , T_m´, Seq[S])]` (if `m = 0`, the type `Option[Seq[S]]` is also accepted). +´x(q_1, ..., q_m, p_1, ..., p_n)´ if it takes exactly one argument +and its result type is of the form `Option[(´T_1, ..., T_m´, Seq[S])]` (if `m = 0`, the type `Option[Seq[S]]` is also accepted). This case is further discussed [below](#pattern-sequences). ###### Example 1 @@ -330,9 +330,9 @@ object Extractor { SimplePattern ::= StableId ‘(’ [Patterns ‘,’] [varid ‘@’] ‘_’ ‘*’ ‘)’ ``` -A _pattern sequence_ ´p_1 , \ldots , p_n´ appears in two contexts. -First, in a constructor pattern ´c(q_1 , \ldots , q_m, p_1 , \ldots , p_n)´, where ´c´ is a case class which has ´m+1´ primary constructor parameters, ending in a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type `S*`. -Second, in an extractor pattern ´x(q_1 , \ldots , q_m, p_1 , \ldots , p_n)´ if the extractor object ´x´ does not have an `unapply` method, +A _pattern sequence_ ´p_1, ..., p_n´ appears in two contexts. +First, in a constructor pattern ´c(q_1, ..., q_m, p_1, ..., p_n)´, where ´c´ is a case class which has ´m+1´ primary constructor parameters, ending in a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type `S*`. +Second, in an extractor pattern ´x(q_1, ..., q_m, p_1, ..., p_n)´ if the extractor object ´x´ does not have an `unapply` method, but it does define an `unapplySeq` method with a result type that is an extractor type for type `(T_1, ... , T_m, Seq[S])` (if `m = 0`, an extractor type for the type `Seq[S]` is also accepted). The expected type for the patterns ´p_i´ is ´S´. The last pattern in a pattern sequence may be a _sequence wildcard_ `_*`. @@ -340,9 +340,9 @@ Each element pattern ´p_i´ is type-checked with ´S´ as expected type, unless it is a sequence wildcard. If a final sequence wildcard is present, the pattern matches all values ´v´ that are sequences which start with elements matching patterns -´p_1 , \ldots , p_{n-1}´. If no final sequence wildcard is given, the +´p_1, ..., p_{n-1}´. If no final sequence wildcard is given, the pattern matches all values ´v´ that are sequences of -length ´n´ which consist of elements matching patterns ´p_1 , \ldots , +length ´n´ which consist of elements matching patterns ´p_1 , ..., p_n´. ### Infix Operation Patterns @@ -356,9 +356,9 @@ constructor or extractor pattern ´\mathit{op}(p, q)´. The precedence and associativity of operators in patterns is the same as in [expressions](06-expressions.html#prefix,-infix,-and-postfix-operations). -An infix operation pattern ´p;\mathit{op};(q_1 , \ldots , q_n)´ is a +An infix operation pattern ´p;\mathit{op};(q_1, ..., q_n)´ is a shorthand for the constructor or extractor pattern ´\mathit{op}(p, q_1 -, \ldots , q_n)´. +, ..., q_n)´. ### Pattern Alternatives @@ -366,7 +366,7 @@ shorthand for the constructor or extractor pattern ´\mathit{op}(p, q_1 Pattern ::= Pattern1 { ‘|’ Pattern1 } ``` -A _pattern alternative_ `´p_1´ | ´\ldots´ | ´p_n´` +A _pattern alternative_ `´p_1´ | ... | ´p_n´` consists of a number of alternative patterns ´p_i´. All alternative patterns are type checked with the expected type of the pattern. They may not bind variables other than wildcards. The alternative pattern @@ -398,9 +398,9 @@ A pattern ´p´ is _irrefutable_ for a type ´T´, if one of the following appli 1. ´p´ is a variable pattern, 1. ´p´ is a typed pattern ´x: T'´, and ´T <: T'´, -1. ´p´ is a constructor pattern ´c(p_1 , \ldots , p_n)´, the type ´T´ +1. ´p´ is a constructor pattern ´c(p_1, ..., p_n)´, the type ´T´ is an instance of class ´c´, the [primary constructor](05-classes-and-objects.html#class-definitions) - of type ´T´ has argument types ´T_1 , \ldots , T_n´, and each ´p_i´ is + of type ´T´ has argument types ´T_1, ..., T_n´, and each ´p_i´ is irrefutable for ´T_i´. 1. ´p´ is an extractor pattern for which the extractor type is `Some[´T´]` for some type ´T´ @@ -438,11 +438,11 @@ A type pattern ´T´ is of one of the following forms: denoted by the literal ´lit´ (the `==` method is used to compare the matched value to ´lit´). -* A compound type pattern `´T_1´ with ´\ldots´ with ´T_n´` where each ´T_i´ is a +* A compound type pattern `´T_1´ with ... with ´T_n´` where each ´T_i´ is a type pattern. This type pattern matches all values that are matched by each of the type patterns ´T_i´. -* A parameterized type pattern ´T[a_1 , \ldots , a_n]´, where the ´a_i´ +* A parameterized type pattern ´T[a_1, ..., a_n]´, where the ´a_i´ are type variable patterns or wildcards `_`. This type pattern matches all values which match ´T´ for some arbitrary instantiation of the type variables and wildcards. The @@ -472,46 +472,46 @@ pattern. ### 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 +´T'´ are renamed to fresh variable names. Let ´a_1, ..., a_n´ be the type variables in ´T´. These type variables are considered bound in the pattern. Let the expected type of the pattern be ´\mathit{pt}´. Type parameter inference constructs first a set of subtype constraints over the type variables ´a_i´. The initial constraints set ´\mathcal{C}\_0´ reflects just the bounds of these type variables. That is, assuming ´T´ has -bound type variables ´a_1 , \ldots , a_n´ which correspond to class -type parameters ´a_1' , \ldots , a_n'´ with lower bounds ´L_1, \ldots , L_n´ -and upper bounds ´U_1 , \ldots , U_n´, ´\mathcal{C}_0´ contains the constraints +bound type variables ´a_1, ..., a_n´ which correspond to class +type parameters ´a_1', ..., a_n'´ with lower bounds ´L_1, ..., L_n´ +and upper bounds ´U_1, ..., U_n´, ´\mathcal{C}_0´ contains the constraints $$ \begin{cases} -a_i &<: \sigma U_i & \quad (i = 1, \ldots , n) \\\\ -\sigma L_i &<: a_i & \quad (i = 1, \ldots , n) +a_i &<: \sigma U_i & \quad (i = 1, ..., n) \\\\ +\sigma L_i &<: a_i & \quad (i = 1, ..., n) \end{cases} $$ -where ´\sigma´ is the substitution ´[a_1' := a_1 , \ldots , a_n' :=a_n]´. +where ´\sigma´ is the substitution ´[a_1' := a_1, ..., a_n' :=a_n]´. The set ´\mathcal{C}_0´ is then augmented by further subtype constraints. There are two cases. ###### Case 1 -If there exists a substitution ´\sigma´ over the type variables ´a_i , \ldots , a_n´ such that ´\sigma T´ conforms to ´\mathit{pt}´, one determines the weakest subtype constraints -´\mathcal{C}\_1´ over the type variables ´a_1, \ldots , a_n´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}_1´ implies that ´T´ conforms to ´\mathit{pt}´. +If there exists a substitution ´\sigma´ over the type variables ´a_i, ..., a_n´ such that ´\sigma T´ conforms to ´\mathit{pt}´, one determines the weakest subtype constraints +´\mathcal{C}\_1´ over the type variables ´a_1, ..., a_n´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}_1´ implies that ´T´ conforms to ´\mathit{pt}´. ###### Case 2 Otherwise, if ´T´ can not be made to conform to ´\mathit{pt}´ by instantiating its type variables, one determines all type variables in ´\mathit{pt}´ which are defined as type parameters of a method enclosing -the pattern. Let the set of such type parameters be ´b_1 , \ldots , +the pattern. Let the set of such type parameters be ´b_1 , ..., b_m´. Let ´\mathcal{C}\_0'´ be the subtype constraints reflecting the bounds of the type variables ´b_i´. If ´T´ denotes an instance type of a final class, let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type -variables ´a_1 , \ldots , a_n´ and ´b_1 , \ldots , b_m´ such that +variables ´a_1, ..., a_n´ and ´b_1, ..., b_m´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that ´T´ conforms to ´\mathit{pt}´. If ´T´ does not denote an instance type of a final class, let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type variables -´a_1 , \ldots , a_n´ and ´b_1 , \ldots , b_m´ such that ´\mathcal{C}\_0 \wedge +´a_1, ..., a_n´ and ´b_1, ..., b_m´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that it is possible to construct a type ´T'´ which conforms to both ´T´ and ´\mathit{pt}´. It is a static error if there is no satisfiable set of constraints ´\mathcal{C}\_2´ with this property. @@ -521,13 +521,13 @@ variables which imply the established constraint system. The process is different for the two cases above. ###### Case 1 -We take ´a_i >: L_i <: U_i´ where each ´L_i´ is minimal and each ´U_i´ is maximal wrt ´<:´ such that ´a_i >: L_i <: U_i´ for ´i = 1, \ldots, n´ implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_1´. +We take ´a_i >: L_i <: U_i´ where each ´L_i´ is minimal and each ´U_i´ is maximal wrt ´<:´ such that ´a_i >: L_i <: U_i´ for ´i = 1, ..., n´ implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_1´. ###### Case 2 We take ´a_i >: L_i <: U_i´ and ´b\_i >: L_i' <: U_i' ´ where each ´L_i´ and ´L_j'´ is minimal and each ´U_i´ and ´U_j'´ is maximal such that -´a_i >: L_i <: U_i´ for ´i = 1 , \ldots , n´ and -´b_j >: L_j' <: U_j'´ for ´j = 1 , \ldots , m´ +´a_i >: L_i <: U_i´ for ´i = 1, ..., n´ and +´b_j >: L_j' <: U_j'´ for ´j = 1, ..., m´ implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}_2´. In both cases, local type inference is permitted to limit the @@ -536,10 +536,10 @@ to be understood relative to the set of types of acceptable complexity. ### Type parameter inference for constructor patterns -Assume a constructor pattern ´C(p_1 , \ldots , p_n)´ where class ´C´ -has type parameters ´a_1 , \ldots , a_n´. These type parameters +Assume a constructor pattern ´C(p_1, ..., p_n)´ where class ´C´ +has type parameters ´a_1, ..., a_n´. These type parameters are inferred in the same way as for the typed pattern -`(_: ´C[a_1 , \ldots , a_n]´)`. +`(_: ´C[a_1, ..., a_n]´)`. ###### Example Consider the program fragment: @@ -625,7 +625,7 @@ function's declared result type, `Number`. A _pattern matching expression_ ```scala -e match { case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ } +e match { case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` consists of a selector expression ´e´ and a number ´n > 0´ of @@ -636,9 +636,9 @@ The scope of the pattern variables in ´p_i´ comprises the pattern's guard and the corresponding block ´b_i´. Let ´T´ be the type of the selector expression ´e´ and let ´a_1 -, \ldots , a_m´ be the type parameters of all methods enclosing +, ..., a_m´ be the type parameters of all methods enclosing the pattern matching expression. For every ´a_i´, let ´L_i´ be its -lower bound and ´U_i´ be its higher bound. Every pattern ´p \in \{p_1, , \ldots , p_n\}´ +lower bound and ´U_i´ be its higher bound. Every pattern ´p \in \{p_1,, ..., p_n\}´ can be typed in two ways. First, it is attempted to type ´p´ with ´T´ as its expected type. If this fails, ´p´ is instead typed with a modified expected type ´T'´ which results from @@ -646,12 +646,12 @@ instead typed with a modified expected type ´T'´ which results from *undefined*. If this second step fails also, a compile-time error results. If the second step succeeds, let ´T_p´ be the type of pattern ´p´ seen as an expression. One then determines minimal bounds -´L_11 , \ldots , L_m'´ and maximal bounds ´U_1' , \ldots , U_m'´ such +´L_11, ..., L_m'´ and maximal bounds ´U_1', ..., U_m'´ such that for all ´i´, ´L_i <: L_i'´ and ´U_i' <: U_i´ and the following constraint system is satisfied: $$ -L_1 <: a_1 <: U_1\;\wedge\;\ldots\;\wedge\;L_m <: a_m <: U_m \ \Rightarrow\ T_p <: T +L_1 <: a_1 <: U_1\;\wedge\;...\;\wedge\;L_m <: a_m <: U_m \ \Rightarrow\ T_p <: T $$ If no such bounds can be found, a compile time error results. If such @@ -742,23 +742,23 @@ conforms to its expected type, `T`. An anonymous function can be defined by a sequence of cases ```scala -{ case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ } +{ case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` which appear as an expression without a prior `match`. The expected type of such an expression must in part be defined. It must -be either `scala.Function´k´[´S_1 , \ldots , S_k´, ´R´]` for some ´k > 0´, +be either `scala.Function´k´[´S_1, ..., S_k´, ´R´]` for some ´k > 0´, or `scala.PartialFunction[´S_1´, ´R´]`, where the -argument type(s) ´S_1 , \ldots , S_k´ must be fully determined, but the result type +argument type(s) ´S_1, ..., S_k´ must be fully determined, but the result type ´R´ may be undetermined. If the expected type is [SAM-convertible](06-expressions.html#sam-conversion) -to `scala.Function´k´[´S_1 , \ldots , S_k´, ´R´]`, +to `scala.Function´k´[´S_1, ..., S_k´, ´R´]`, the expression is taken to be equivalent to the anonymous function: ```scala -(´x_1: S_1 , \ldots , x_k: S_k´) => (´x_1 , \ldots , x_k´) match { - case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ +(´x_1: S_1, ..., x_k: S_k´) => (´x_1, ..., x_k´) match { + case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` @@ -768,9 +768,9 @@ equivalent to the following instance creation expression, where ´T´ is the weak least upper bound of the types of all ´b_i´. ```scala -new scala.Function´k´[´S_1 , \ldots , S_k´, ´T´] { - def apply(´x_1: S_1 , \ldots , x_k: S_k´): ´T´ = (´x_1 , \ldots , x_k´) match { - case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ +new scala.Function´k´[´S_1, ..., S_k´, ´T´] { + def apply(´x_1: S_1, ..., x_k: S_k´): ´T´ = (´x_1, ..., x_k´) match { + case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } } ``` @@ -781,10 +781,10 @@ the expression is taken to be equivalent to the following instance creation expr ```scala new scala.PartialFunction[´S´, ´T´] { def apply(´x´: ´S´): ´T´ = x match { - case ´p_1´ => ´b_1´ ´\ldots´ case ´p_n´ => ´b_n´ + case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } def isDefinedAt(´x´: ´S´): Boolean = { - case ´p_1´ => true ´\ldots´ case ´p_n´ => true + case ´p_1´ => true ... case ´p_n´ => true case _ => false } } @@ -792,7 +792,7 @@ new scala.PartialFunction[´S´, ´T´] { Here, ´x´ is a fresh name and ´T´ is the weak least upper bound of the types of all ´b_i´. The final default case in the `isDefinedAt` -method is omitted if one of the patterns ´p_1 , \ldots , p_n´ is +method is omitted if one of the patterns ´p_1, ..., p_n´ is already a variable or wildcard pattern. ###### Example diff --git a/docs/_spec/09-top-level-definitions.md b/docs/_spec/09-top-level-definitions.md index 33c436e8d77b..3588d26f6034 100644 --- a/docs/_spec/09-top-level-definitions.md +++ b/docs/_spec/09-top-level-definitions.md @@ -27,7 +27,7 @@ A _compilation unit_ ```scala package ´p_1´; -´\ldots´ +... package ´p_n´; ´\mathit{stats}´ ``` @@ -37,10 +37,10 @@ clauses is equivalent to a compilation unit consisting of the packaging ```scala -package ´p_1´ { ´\ldots´ +package ´p_1´ { ... package ´p_n´ { ´\mathit{stats}´ - } ´\ldots´ + } ... } ``` diff --git a/docs/_spec/11-annotations.md b/docs/_spec/11-annotations.md index 388d99b60e56..9f806ff5a471 100644 --- a/docs/_spec/11-annotations.md +++ b/docs/_spec/11-annotations.md @@ -14,7 +14,7 @@ chapter: 11 ## Definition Annotations associate meta-information with definitions. -A simple annotation has the form `@´c´` or `@´c(a_1 , \ldots , a_n)´`. +A simple annotation has the form `@´c´` or `@´c(a_1, ..., a_n)´`. Here, ´c´ is a constructor of a class ´C´, which must conform to the class `scala.Annotation`. diff --git a/docs/_spec/12-the-scala-standard-library.md b/docs/_spec/12-the-scala-standard-library.md index 80d66c0c4166..9bbc12e463dd 100644 --- a/docs/_spec/12-the-scala-standard-library.md +++ b/docs/_spec/12-the-scala-standard-library.md @@ -56,10 +56,10 @@ abstract class Any { final def != (that: Any): Boolean = !(this == that) /** Hash code; abstract here */ - def hashCode: Int = ´\ldots´ + def hashCode: Int = ... /** Textual representation; abstract here */ - def toString: String = ´\ldots´ + def toString: String = ... /** Type test; needs to be inlined to work as given */ def isInstanceOf[a]: Boolean @@ -78,11 +78,11 @@ final class AnyVal extends Any /** The root class of all reference types */ class AnyRef extends Any { def equals(that: Any): Boolean = this eq that - final def eq(that: AnyRef): Boolean = ´\ldots´ // reference equality + final def eq(that: AnyRef): Boolean = ... // reference equality final def ne(that: AnyRef): Boolean = !(this eq that) - def hashCode: Int = ´\ldots´ // hashCode computed from allocation address - def toString: String = ´\ldots´ // toString computed from hashCode and class name + def hashCode: Int = ... // hashCode computed from allocation address + def toString: String = ... // toString computed from hashCode and class name def synchronized[T](body: => T): T // execute `body` in while locking `this`. } @@ -353,13 +353,13 @@ right operand. ### The `Tuple` classes -Scala defines tuple classes `Tuple´n´` for ´n = 2 , \ldots , 22´. +Scala defines tuple classes `Tuple´n´` for ´n = 2, ..., 22´. These are defined as follows. ```scala package scala case class Tuple´n´[+T_1, ..., +T_n](_1: T_1, ..., _´n´: T_´n´) { - def toString = "(" ++ _1 ++ "," ++ ´\ldots´ ++ "," ++ _´n´ ++ ")" + def toString = "(" ++ _1 ++ "," ++ ... ++ "," ++ _´n´ ++ ")" } ``` @@ -397,10 +397,10 @@ informational purposes only: ```scala final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { - def length: Int = ´\ldots´ - def apply(i: Int): T = ´\ldots´ - def update(i: Int, x: T): Unit = ´\ldots´ - override def clone(): Array[T] = ´\ldots´ + def length: Int = ... + def apply(i: Int): T = ... + def update(i: Int, x: T): Unit = ... + override def clone(): Array[T] = ... } ``` @@ -502,46 +502,46 @@ package scala object Array { /** copies array elements from `src` to `dest`. */ def copy(src: AnyRef, srcPos: Int, - dest: AnyRef, destPos: Int, length: Int): Unit = ´\ldots´ + dest: AnyRef, destPos: Int, length: Int): Unit = ... /** Returns an array of length 0 */ def empty[T: ClassTag]: Array[T] = /** Create an array with given elements. */ - def apply[T: ClassTag](xs: T*): Array[T] = ´\ldots´ + def apply[T: ClassTag](xs: T*): Array[T] = ... /** Creates array with given dimensions */ - def ofDim[T: ClassTag](n1: Int): Array[T] = ´\ldots´ + def ofDim[T: ClassTag](n1: Int): Array[T] = ... /** Creates a 2-dimensional array */ - def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = ´\ldots´ - ´\ldots´ + def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = ... + ... /** Concatenate all argument arrays into a single array. */ - def concat[T: ClassTag](xss: Array[T]*): Array[T] = ´\ldots´ + def concat[T: ClassTag](xss: Array[T]*): Array[T] = ... /** Returns an array that contains the results of some element computation a number * of times. */ - def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = ´\ldots´ + def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = ... /** Returns a two-dimensional array that contains the results of some element * computation a number of times. */ - def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = ´\ldots´ - ´\ldots´ + def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = ... + ... /** Returns an array containing values of a given function over a range of integer * values starting from 0. */ - def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = ´\ldots´ + def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = ... /** Returns a two-dimensional array containing values of a given function * over ranges of integer values starting from `0`. */ - def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = ´\ldots´ - ´\ldots´ + def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = ... + ... /** Returns an array containing a sequence of increasing integers in a range. */ - def range(start: Int, end: Int): Array[Int] = ´\ldots´ + def range(start: Int, end: Int): Array[Int] = ... /** Returns an array containing equally spaced values in some integer interval. */ - def range(start: Int, end: Int, step: Int): Array[Int] = ´\ldots´ + def range(start: Int, end: Int, step: Int): Array[Int] = ... /** Returns an array containing repeated applications of a function to a start value. */ - def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = ´\ldots´ + def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = ... /** Enables pattern matching over arrays */ def unapplySeq[A](x: Array[A]): Option[IndexedSeq[A]] = Some(x) From 95b703f237d06dbc05842495356c232b69e6f6ea Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Tue, 18 Oct 2022 16:19:08 +0200 Subject: [PATCH 07/11] Reformat to 1sentence=1line convention --- docs/_spec/01-lexical-syntax.md | 308 ++-- docs/_spec/02-identifiers-names-and-scopes.md | 97 +- docs/_spec/03-types.md | 713 +++------- .../04-basic-declarations-and-definitions.md | 538 +++---- docs/_spec/05-classes-and-objects.md | 890 ++++-------- docs/_spec/06-expressions.md | 1266 ++++++----------- docs/_spec/07-implicits.md | 348 ++--- docs/_spec/08-pattern-matching.md | 589 +++----- docs/_spec/09-top-level-definitions.md | 104 +- docs/_spec/10-xml-expressions-and-patterns.md | 61 +- docs/_spec/11-annotations.md | 192 +-- docs/_spec/12-the-scala-standard-library.md | 437 +++--- docs/_spec/13-syntax-summary.md | 3 +- docs/_spec/README.md | 4 + 14 files changed, 1899 insertions(+), 3651 deletions(-) diff --git a/docs/_spec/01-lexical-syntax.md b/docs/_spec/01-lexical-syntax.md index 46bd876b4077..032cf3703bb9 100644 --- a/docs/_spec/01-lexical-syntax.md +++ b/docs/_spec/01-lexical-syntax.md @@ -9,22 +9,16 @@ chapter: 1 Scala source code consists of Unicode text. The program text is tokenized as described in this chapter. -See the last section for special support for XML literals, -which are parsed in _XML mode_. +See the last section for special support for XML literals, which are parsed in _XML mode_. -To construct tokens, characters are distinguished according to the following -classes (Unicode general category given in parentheses): +To construct tokens, characters are distinguished according to the following classes (Unicode general category given in parentheses): 1. Whitespace characters. `\u0020 | \u0009 | \u000D | \u000A`. -1. Letters, which include lower case letters (`Ll`), upper case letters (`Lu`), - title case letters (`Lt`), other letters (`Lo`), modifier letters (`Lm`), - letter numerals (`Nl`) and the two characters `\u0024 ‘$’` and `\u005F ‘_’`. +1. Letters, which include lower case letters (`Ll`), upper case letters (`Lu`), title case letters (`Lt`), other letters (`Lo`), modifier letters (`Lm`), letter numerals (`Nl`) and the two characters `\u0024 ‘$’` and `\u005F ‘_’`. 1. Digits `‘0’ | ... | ‘9’`. 1. Parentheses `‘(’ | ‘)’ | ‘[’ | ‘]’ | ‘{’ | ‘}’ `. 1. Delimiter characters ``‘`’ | ‘'’ | ‘"’ | ‘.’ | ‘;’ | ‘,’ ``. -1. Operator characters. These consist of all printable ASCII characters - (`\u0020` - `\u007E`) that are in none of the sets above, mathematical - symbols (`Sm`) and other symbols (`So`). +1. Operator characters. These consist of all printable ASCII characters (`\u0020` - `\u007E`) that are in none of the sets above, mathematical symbols (`Sm`) and other symbols (`So`). ## Identifiers @@ -44,19 +38,16 @@ UnicodeEscape ::= ‘\’ ‘u’ {‘u’} hexDigit hexDigit hexDigit hexDigit hexDigit ::= ‘0’ | ... | ‘9’ | ‘A’ | ... | ‘F’ | ‘a’ | ... | ‘f’ ``` -There are three ways to form an identifier. First, an identifier can -start with a letter, followed by an arbitrary sequence of -letters and digits. This may be followed by underscore `‘_‘` -characters and another string composed of either letters and digits or -of operator characters. Second, an identifier can start with an operator -character followed by an arbitrary sequence of operator characters. -The preceding two forms are called _plain_ identifiers. Finally, -an identifier may also be formed by an arbitrary string between -backquotes (host systems may impose some restrictions on which -strings are legal for identifiers). The identifier then is composed -of all characters excluding the backquotes themselves. +There are three ways to form an identifier. +First, an identifier can start with a letter, followed by an arbitrary sequence of letters and digits. +This may be followed by underscore `‘_‘` characters and another string composed of either letters and digits or of operator characters. +Second, an identifier can start with an operator character followed by an arbitrary sequence of operator characters. +The preceding two forms are called _plain_ identifiers. +Finally, an identifier may also be formed by an arbitrary string between backquotes (host systems may impose some restrictions on which strings are legal for identifiers). +The identifier then is composed of all characters excluding the backquotes themselves. -As usual, the longest match rule applies. For instance, the string +As usual, the longest match rule applies. +For instance, the string ```scala big_bob++=`def` @@ -65,15 +56,9 @@ big_bob++=`def` decomposes into the three identifiers `big_bob`, `++=`, and `def`. -The rules for pattern matching further distinguish between -_variable identifiers_, which start with a lower case letter -or `_`, and _constant identifiers_, which do not. +The rules for pattern matching further distinguish between _variable identifiers_, which start with a lower case letter or `_`, and _constant identifiers_, which do not. -For this purpose, lower case letters include not only a-z, -but also all characters in Unicode category Ll (lowercase letter), -as well as all letters that have contributory property -Other_Lowercase, except characters in category Nl (letter numerals), -which are never taken as lower case. +For this purpose, lower case letters include not only a-z, but also all characters in Unicode category Ll (lowercase letter), as well as all letters that have contributory property Other_Lowercase, except characters in category Nl (letter numerals), which are never taken as lower case. The following are examples of variable identifiers: @@ -94,8 +79,7 @@ Some examples of constant identifiers are The ‘$’ character is reserved for compiler-synthesized identifiers. User programs should not define identifiers that contain ‘$’ characters. -The following names are reserved words instead of being members of the -syntactic class `id` of lexical identifiers. +The following names are reserved words instead of being members of the syntactic class `id` of lexical identifiers. ```scala abstract case catch class def @@ -109,8 +93,7 @@ val var while with yield _ : = => <- <: <% >: # @ ``` -The Unicode operators `\u21D2` ‘´\Rightarrow´’ and `\u2190` ‘´\leftarrow´’, which have the ASCII -equivalents `=>` and `<-`, are also reserved. +The Unicode operators `\u21D2` ‘´\Rightarrow´’ and `\u2190` ‘´\leftarrow´’, which have the ASCII equivalents `=>` and `<-`, are also reserved. > Here are examples of identifiers: > ```scala @@ -131,24 +114,21 @@ equivalents `=>` and `<-`, are also reserved. semi ::= ‘;’ | nl {nl} ``` -Scala is a line-oriented language where statements may be terminated by -semi-colons or newlines. A newline in a Scala source text is treated -as the special token “nl” if the three following criteria are satisfied: +Scala is a line-oriented language where statements may be terminated by semi-colons or newlines. +A newline in a Scala source text is treated as the special token “nl” if the three following criteria are satisfied: 1. The token immediately preceding the newline can terminate a statement. 1. The token immediately following the newline can begin a statement. 1. The token appears in a region where newlines are enabled. -The tokens that can terminate a statement are: literals, identifiers -and the following delimiters and reserved words: +The tokens that can terminate a statement are: literals, identifiers and the following delimiters and reserved words: ```scala this null true false return type _ ) ] } ``` -The tokens that can begin a statement are all Scala tokens _except_ -the following delimiters and reserved words: +The tokens that can begin a statement are all Scala tokens _except_ the following delimiters and reserved words: ```scala catch else extends finally forSome match @@ -161,64 +141,39 @@ A `case` token can begin a statement only if followed by a Newlines are enabled in: -1. all of a Scala source file, except for nested regions where newlines - are disabled, and -1. the interval between matching `{` and `}` brace tokens, - except for nested regions where newlines are disabled. +1. all of a Scala source file, except for nested regions where newlines are disabled, and +1. the interval between matching `{` and `}` brace tokens, except for nested regions where newlines are disabled. Newlines are disabled in: -1. the interval between matching `(` and `)` parenthesis tokens, except for - nested regions where newlines are enabled, and -1. the interval between matching `[` and `]` bracket tokens, except for nested - regions where newlines are enabled. -1. The interval between a `case` token and its matching - `=>` token, except for nested regions where newlines are - enabled. +1. the interval between matching `(` and `)` parenthesis tokens, except for nested regions where newlines are enabled, and +1. the interval between matching `[` and `]` bracket tokens, except for nested regions where newlines are enabled. +1. The interval between a `case` token and its matching `=>` token, except for nested regions where newlines are enabled. 1. Any regions analyzed in [XML mode](#xml-mode). -Note that the brace characters of `{...}` escapes in XML and -string literals are not tokens, -and therefore do not enclose a region where newlines -are enabled. - -Normally, only a single `nl` token is inserted between two -consecutive non-newline tokens which are on different lines, even if there are multiple lines -between the two tokens. However, if two tokens are separated by at -least one completely blank line (i.e a line which contains no -printable characters), then two `nl` tokens are inserted. - -The Scala grammar (given in full [here](13-syntax-summary.html)) -contains productions where optional `nl` tokens, but not -semicolons, are accepted. This has the effect that a new line in one of these -positions does not terminate an expression or statement. These positions can -be summarized as follows: - -Multiple newline tokens are accepted in the following places (note -that a semicolon in place of the newline would be illegal in every one -of these cases): - -- between the condition of a - [conditional expression](06-expressions.html#conditional-expressions) - or [while loop](06-expressions.html#while-loop-expressions) and the next - following expression, -- between the enumerators of a - [for-comprehension](06-expressions.html#for-comprehensions-and-for-loops) - and the next following expression, and -- after the initial `type` keyword in a - [type definition or declaration](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases). +Note that the brace characters of `{...}` escapes in XML and string literals are not tokens, and therefore do not enclose a region where newlines are enabled. + +Normally, only a single `nl` token is inserted between two consecutive non-newline tokens which are on different lines, even if there are multiple lines between the two tokens. +However, if two tokens are separated by at least one completely blank line (i.e a line which contains no printable characters), then two `nl` tokens are inserted. + +The Scala grammar (given in full [here](13-syntax-summary.html)) contains productions where optional `nl` tokens, but not semicolons, are accepted. +This has the effect that a new line in one of these positions does not terminate an expression or statement. +These positions can be summarized as follows: + +Multiple newline tokens are accepted in the following places (note that a semicolon in place of the newline would be illegal in every one of these cases): + +- between the condition of a [conditional expression](06-expressions.html#conditional-expressions) or [while loop](06-expressions.html#while-loop-expressions) and the next following expression, +- between the enumerators of a [for-comprehension](06-expressions.html#for-comprehensions-and-for-loops) and the next following expression, and +- after the initial `type` keyword in a [type definition or declaration](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases). A single new line token is accepted -- in front of an opening brace ‘{’, if that brace is a legal - continuation of the current statement or expression, -- 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 an opening brace ‘{’, if that brace is a legal continuation of the current statement or expression, +- 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-annotations.html#user-defined-annotations). -> The newline tokens between the two lines are not -> treated as statement separators. +> The newline tokens between the two lines are not treated as statement separators. > > ```scala > if (x > 0) @@ -245,8 +200,7 @@ A single new line token is accepted > } > ``` > -> With an additional newline character, the same code is interpreted as -> an object creation followed by a local block: +> With an additional newline character, the same code is interpreted as an object creation followed by a local block: > > ```scala > new Iterator[Int] @@ -265,8 +219,7 @@ A single new line token is accepted > x > 10 > ``` > -> With an additional newline character, the same code is interpreted as -> two expressions: +> With an additional newline character, the same code is interpreted as two expressions: > > ```scala > x < 0 || @@ -281,8 +234,7 @@ A single new line token is accepted > (y: Int) = x + y > ``` > -> With an additional newline character, the same code is interpreted as -> an abstract function definition and a syntactically illegal statement: +> 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) @@ -297,8 +249,7 @@ A single new line token is accepted > protected class Data { ... } > ``` > -> With an additional newline character, the same code is interpreted as -> an attribute and a separate statement (which is syntactically illegal). +> With an additional newline character, the same code is interpreted as an attribute and a separate statement (which is syntactically illegal). > > ```scala > @serializable @@ -308,9 +259,8 @@ A single new line token is accepted ## Literals -There are literals for integer numbers, floating point numbers, -characters, booleans, symbols, strings. The syntax of these literals is in -each case as in Java. +There are literals for integer numbers, floating point numbers, characters, booleans, symbols, strings. +The syntax of these literals is in each case as in Java. -> 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`. @@ -407,8 +344,7 @@ whitespace character between the two tokens. booleanLiteral ::= ‘true’ | ‘false’ ``` -The boolean literals `true` and `false` are -members of type `Boolean`. +The boolean literals `true` and `false` are members of type `Boolean`. ### Character Literals @@ -417,9 +353,7 @@ characterLiteral ::= ‘'’ (charNoQuoteOrNewline | escapeSeq) ‘'’ ``` A character literal is a single character enclosed in quotes. -The character can be any Unicode character except the single quote -delimiter or `\u000A` (LF) or `\u000D` (CR); -or any Unicode character represented by an +The character can be any Unicode character except the single quote delimiter or `\u000A` (LF) or `\u000D` (CR); or any Unicode character represented by an [escape sequence](#escape-sequences). > ```scala @@ -434,9 +368,7 @@ stringElement ::= charNoDoubleQuoteOrNewline | escapeSeq ``` A string literal is a sequence of characters in double quotes. -The characters can be any Unicode character except the double quote -delimiter or `\u000A` (LF) or `\u000D` (CR); -or any Unicode character represented by an [escape sequence](#escape-sequences). +The characters can be any Unicode character except the double quote delimiter or `\u000A` (LF) or `\u000D` (CR); or any Unicode character represented by an [escape sequence](#escape-sequences). If the string literal contains a double quote character, it must be escaped using `"\""`. @@ -455,13 +387,10 @@ stringLiteral ::= ‘"""’ multiLineChars ‘"""’ multiLineChars ::= {[‘"’] [‘"’] charNoDoubleQuote} {‘"’} ``` -A multi-line string literal is a sequence of characters enclosed in -triple quotes `""" ... """`. The sequence of characters is -arbitrary, except that it may contain three or more consecutive quote characters -only at the very end. Characters -must not necessarily be printable; newlines or other -control characters are also permitted. [Escape sequences](#escape-sequences) are -not processed, except for Unicode escapes (this is deprecated since 2.13.2). +A multi-line string literal is a sequence of characters enclosed in triple quotes `""" ... """`. +The sequence of characters is arbitrary, except that it may contain three or more consecutive quote characters only at the very end. +Characters must not necessarily be printable; newlines or other control characters are also permitted. +[Escape sequences](#escape-sequences) are not processed, except for Unicode escapes (this is deprecated since 2.13.2). > ```scala > """the present string @@ -477,8 +406,7 @@ not processed, except for Unicode escapes (this is deprecated since 2.13.2). > lines. > ``` > -> The Scala library contains a utility method `stripMargin` -> which can be used to strip leading whitespace from multi-line strings. +> The Scala library contains a utility method `stripMargin` which can be used to strip leading whitespace from multi-line strings. > The expression > > ```scala @@ -513,35 +441,28 @@ alphaid ::= upper idrest ``` -An interpolated string consists of an identifier starting with a letter immediately -followed by a string literal. There may be no whitespace characters or comments -between the leading identifier and the opening quote `"` of the string. -The string literal in an interpolated string can be standard (single quote) -or multi-line (triple quote). +An interpolated string consists of an identifier starting with a letter immediately followed by a string literal. +There may be no whitespace characters or comments between the leading identifier and the opening quote `"` of the string. +The string literal in an interpolated string can be standard (single quote) or multi-line (triple quote). -Inside an interpolated string none of the usual escape characters are interpreted -no matter whether the string literal is normal (enclosed in single quotes) or -multi-line (enclosed in triple quotes). Note that the sequence `\"` does not -close a normal string literal (enclosed in single quotes). +Inside an interpolated string none of the usual escape characters are interpreted no matter whether the string literal is normal (enclosed in single quotes) or multi-line (enclosed in triple quotes). +Note that the sequence `\"` does not close a normal string literal (enclosed in single quotes). There are three forms of dollar sign escape. The most general form encloses an expression in `${` and `}`, i.e. `${expr}`. -The expression enclosed in the braces that follow the leading `$` character is of -syntactical category BlockExpr. Hence, it can contain multiple statements, -and newlines are significant. Single ‘$’-signs are not permitted in isolation -in an interpolated string. A single ‘$’-sign can still be obtained by doubling the ‘$’ -character: ‘$$’. A single ‘"’-sign can be obtained by the sequence ‘\$"’. - -The simpler form consists of a ‘$’-sign followed by an identifier starting with -a letter and followed only by letters, digits, and underscore characters, e.g., `$id`. -The simpler form is expanded by putting braces around the identifier, -e.g., `$id` is equivalent to `${id}`. In the following, unless we explicitly state otherwise, -we assume that this expansion has already been performed. - -The expanded expression is type checked normally. Usually, `StringContext` will resolve to -the default implementation in the scala package, -but it could also be user-defined. Note that new interpolators can also be added through -implicit conversion of the built-in `scala.StringContext`. +The expression enclosed in the braces that follow the leading `$` character is of syntactical category BlockExpr. +Hence, it can contain multiple statements, and newlines are significant. +Single ‘$’-signs are not permitted in isolation in an interpolated string. +A single ‘$’-sign can still be obtained by doubling the ‘$’ character: ‘$$’. +A single ‘"’-sign can be obtained by the sequence ‘\$"’. + +The simpler form consists of a ‘$’-sign followed by an identifier starting with a letter and followed only by letters, digits, and underscore characters, e.g., `$id`. +The simpler form is expanded by putting braces around the identifier, e.g., `$id` is equivalent to `${id}`. +In the following, unless we explicitly state otherwise, we assume that this expansion has already been performed. + +The expanded expression is type checked normally. +Usually, `StringContext` will resolve to the default implementation in the scala package, but it could also be user-defined. +Note that new interpolators can also be added through implicit conversion of the built-in `scala.StringContext`. One could write an extension ```scala @@ -565,11 +486,9 @@ The following character escape sequences are recognized in character and string | `‘\‘ ‘'‘` | `\u0027` | single quote | `'` | | `‘\‘ ‘\‘` | `\u005c` | backslash | `\` | -In addition, Unicode escape sequences of the form `\uxxxx`, where each `x` is a hex digit are -recognized in character and string literals. +In addition, Unicode escape sequences of the form `\uxxxx`, where each `x` is a hex digit are recognized in character and string literals. -It is a compile time error if a backslash character in a character or -string literal does not start a valid escape sequence. +It is a compile time error if a backslash character in a character or string literal does not start a valid escape sequence. ### Symbol literals @@ -579,30 +498,23 @@ symbolLiteral ::= ‘'’ plainid A symbol literal `'x` is deprecated shorthand for the expression `scala.Symbol("x")`. -The `apply` method of `Symbol`'s companion object -caches weak references to `Symbol`s, thus ensuring that -identical symbol literals are equivalent with respect to reference -equality. +The `apply` method of `Symbol`'s companion object caches weak references to `Symbol`s, thus ensuring that identical symbol literals are equivalent with respect to reference equality. ## Whitespace and Comments -Tokens may be separated by whitespace characters -and/or comments. Comments come in two forms: +Tokens may be separated by whitespace characters and/or comments. +Comments come in two forms: -A single-line comment is a sequence of characters which starts with -`//` and extends to the end of the line. +A single-line comment is a sequence of characters which starts with `//` and extends to the end of the line. -A multi-line comment is a sequence of characters between -`/*` and `*/`. Multi-line comments may be nested, -but are required to be properly nested. Therefore, a comment like -`/* /* */` will be rejected as having an unterminated -comment. +A multi-line comment is a sequence of characters between `/*` and `*/`. +Multi-line comments may be nested, but are required to be properly nested. +Therefore, a comment like `/* /* */` will be rejected as having an unterminated comment. ## Trailing Commas in Multi-line Expressions -If a comma (`,`) is followed immediately, ignoring whitespace, by a newline and -a closing parenthesis (`)`), bracket (`]`), or brace (`}`), then the comma is -treated as a "trailing comma" and is ignored. For example: +If a comma (`,`) is followed immediately, ignoring whitespace, by a newline and a closing parenthesis (`)`), bracket (`]`), or brace (`}`), then the comma is treated as a "trailing comma" and is ignored. +For example: ```scala foo( @@ -614,11 +526,8 @@ foo( ## XML mode -In order to allow literal inclusion of XML fragments, lexical analysis -switches from Scala mode to XML mode when encountering an opening -angle bracket ‘<’ in the following circumstance: The ‘<’ must be -preceded either by whitespace, an opening parenthesis or an opening -brace and immediately followed by a character starting an XML name. +In order to allow literal inclusion of XML fragments, lexical analysis switches from Scala mode to XML mode when encountering an opening angle bracket ‘<’ in the following circumstance: +The ‘<’ must be preceded either by whitespace, an opening parenthesis or an opening brace and immediately followed by a character starting an XML name. ```ebnf ( whitespace | ‘(’ | ‘{’ ) ‘<’ (XNameStart | ‘!’ | ‘?’) @@ -628,20 +537,13 @@ brace and immediately followed by a character starting an XML name. The scanner switches from XML mode to Scala mode if either -- the XML expression or the XML pattern started by the initial ‘<’ has been - successfully parsed, or if -- the parser encounters an embedded Scala expression or pattern and - forces the Scanner - back to normal mode, until the Scala expression or pattern is - successfully parsed. In this case, since code and XML fragments can be - nested, the parser has to maintain a stack that reflects the nesting - of XML and Scala expressions adequately. +- the XML expression or the XML pattern started by the initial ‘<’ has been successfully parsed, or if +- the parser encounters an embedded Scala expression or pattern and forces the Scanner back to normal mode, until the Scala expression or pattern is successfully parsed. +In this case, since code and XML fragments can be nested, the parser has to maintain a stack that reflects the nesting of XML and Scala expressions adequately. -Note that no Scala tokens are constructed in XML mode, and that comments are interpreted -as text. +Note that no Scala tokens are constructed in XML mode, and that comments are interpreted as text. -> The following value definition uses an XML literal with two embedded -> Scala expressions: +> The following value definition uses an XML literal with two embedded Scala expressions: > > ```scala > val b = diff --git a/docs/_spec/02-identifiers-names-and-scopes.md b/docs/_spec/02-identifiers-names-and-scopes.md index b8bde8cfd1a9..2b34ae8844cf 100644 --- a/docs/_spec/02-identifiers-names-and-scopes.md +++ b/docs/_spec/02-identifiers-names-and-scopes.md @@ -6,8 +6,8 @@ chapter: 2 # Identifiers, Names and Scopes -Names in Scala identify types, values, methods, and classes which are -collectively called _entities_. Names are introduced by local +Names in Scala identify types, values, methods, and classes which are collectively called _entities_. +Names are introduced by local [definitions and declarations](04-basic-declarations-and-definitions.html#basic-declarations-and-definitions), [inheritance](05-classes-and-objects.html#class-members), [import clauses](04-basic-declarations-and-definitions.html#import-clauses), or @@ -16,29 +16,22 @@ which are collectively called _bindings_. Bindings of different kinds have precedence defined on them: -1. Definitions and declarations that are local, inherited, or made - available by a package clause and also defined in the same compilation unit - as the reference to them, have the highest precedence. +1. Definitions and declarations that are local, inherited, or made available by a package clause and also defined in the same compilation unit as the reference to them, have the highest precedence. 1. Explicit imports have the next highest precedence. 1. Wildcard imports have the next highest precedence. -1. Definitions made available by a package clause, but not also defined in the - same compilation unit as the reference to them, as well as imports which - are supplied by the compiler but not explicitly written in source code, - have the lowest precedence. +1. Definitions made available by a package clause, but not also defined in the same compilation unit as the reference to them, as well as imports which are supplied by the compiler but not explicitly written in source code, have the lowest precedence. -There are two different name spaces, one for [types](03-types.html#types) -and one for [terms](06-expressions.html#expressions). The same name may designate a -type and a term, depending on the context where the name is used. +There are two different name spaces, one for [types](03-types.html#types) and one for [terms](06-expressions.html#expressions). +The same name may designate a type and a term, depending on the context where the name is used. A binding has a _scope_ in which the entity defined by a single -name can be accessed using a simple name. Scopes are nested. A binding -in some inner scope _shadows_ bindings of lower precedence in the -same scope as well as bindings of the same or lower precedence in outer -scopes. +name can be accessed using a simple name. +Scopes are nested. +A binding in some inner scope _shadows_ bindings of lower precedence in the same scope as well as bindings of the same or lower precedence in outer scopes. -Note that shadowing is only a partial order. In the following example, -neither binding of `x` shadows the other. Consequently, the -reference to `x` in the last line of the block is ambiguous. +Note that shadowing is only a partial order. +In the following example, neither binding of `x` shadows the other. +Consequently, the reference to `x` in the last line of the block is ambiguous. ```scala val x = 1 @@ -48,32 +41,24 @@ locally { } ``` -A reference to an unqualified (type- or term-) identifier ´x´ is bound -by the unique binding, which +A reference to an unqualified (type- or term-) identifier ´x´ is bound by the unique binding, which - defines an entity with name ´x´ in the same namespace as the identifier, and -- shadows all other bindings that define entities with name ´x´ in that - namespace. - -It is an error if no such binding exists. If ´x´ is bound by an -import clause, then the simple name ´x´ is taken to be equivalent to -the qualified name to which ´x´ is mapped by the import clause. If ´x´ -is bound by a definition or declaration, then ´x´ refers to the entity -introduced by that binding. In that case, the type of ´x´ is the type -of the referenced entity. - -A reference to a qualified (type- or term-) identifier ´e.x´ refers to -the member of the type ´T´ of ´e´ which has the name ´x´ in the same -namespace as the identifier. It is an error if ´T´ is not a [value type](03-types.html#value-types). +- shadows all other bindings that define entities with name ´x´ in that namespace. + +It is an error if no such binding exists. +If ´x´ is bound by an import clause, then the simple name ´x´ is taken to be equivalent to the qualified name to which ´x´ is mapped by the import clause. +If ´x´ is bound by a definition or declaration, then ´x´ refers to the entity introduced by that binding. +In that case, the type of ´x´ is the type of the referenced entity. + +A reference to a qualified (type- or term-) identifier ´e.x´ refers to the member of the type ´T´ of ´e´ which has the name ´x´ in the same 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´. Binding precedence implies that the way source is bundled in files affects name resolution. -In particular, imported names have higher precedence than names, defined in other files, -that might otherwise be visible because they are defined in -either the current package or an enclosing package. +In particular, imported names have higher precedence than names, defined in other files, that might otherwise be visible because they are defined in either the current package or an enclosing package. -Note that a package definition is taken as lowest precedence, since packages -are open and can be defined across arbitrary compilation units. +Note that a package definition is taken as lowest precedence, since packages are open and can be defined across arbitrary compilation units. ```scala package util { @@ -85,8 +70,8 @@ package util { } ``` -The compiler supplies imports in a preamble to every source file. This preamble -conceptually has the following form, where braces indicate nested scopes: +The compiler supplies imports in a preamble to every source file. +This preamble conceptually has the following form, where braces indicate nested scopes: ```scala import java.lang._ @@ -99,16 +84,12 @@ import java.lang._ } ``` -These imports are taken as lowest precedence, so that they are always shadowed -by user code, which may contain competing imports and definitions. -They also increase the nesting depth as shown, so that later imports -shadow earlier ones. +These imports are taken as lowest precedence, so that they are always shadowed by user code, which may contain competing imports and definitions. +They also increase the nesting depth as shown, so that later imports shadow earlier ones. -As a convenience, multiple bindings of a type identifier to the same -underlying type is permitted. This is possible when import clauses introduce -a binding of a member type alias with the same binding precedence, typically -through wildcard imports. This allows redundant type aliases to be imported -without introducing an ambiguity. +As a convenience, multiple bindings of a type identifier to the same underlying type is permitted. +This is possible when import clauses introduce a binding of a member type alias with the same binding precedence, typically through wildcard imports. +This allows redundant type aliases to be imported without introducing an ambiguity. ```scala object X { type T = annotation.tailrec } @@ -119,8 +100,7 @@ object Z { } ``` -Similarly, imported aliases of names introduced by package statements are -allowed, even though the names are strictly ambiguous: +Similarly, imported aliases of names introduced by package statements are allowed, even though the names are strictly ambiguous: ```scala // c.scala @@ -132,16 +112,12 @@ package p { class X extends C } package q { class Y extends C } ``` -The reference to `C` in the definition of `X` is strictly ambiguous -because `C` is available by virtue of the package clause in -a different file, and can't shadow the imported name. But because -the references are the same, the definition is taken as though it -did shadow the import. +The reference to `C` in the definition of `X` is strictly ambiguous because `C` is available by virtue of the package clause in a different file, and can't shadow the imported name. +But because the references are the same, the definition is taken as though it did shadow the import. ###### Example -Assume the following two definitions of objects named `X` in packages `p` and `q` -in separate compilation units. +Assume the following two definitions of objects named `X` in packages `p` and `q` in separate compilation units. ```scala package p { @@ -153,8 +129,7 @@ package q { } ``` -The following program illustrates different kinds of bindings and -precedences between them. +The following program illustrates different kinds of bindings and precedences between them. ```scala package p { // `X' bound by package clause diff --git a/docs/_spec/03-types.md b/docs/_spec/03-types.md index 205af416b9c5..664ddea49713 100644 --- a/docs/_spec/03-types.md +++ b/docs/_spec/03-types.md @@ -29,40 +29,29 @@ chapter: 3 Types ::= Type {‘,’ Type} ``` -We distinguish between proper types and type constructors, which -take type parameters and yield types. A subset of proper types -called _value types_ represents sets of (first-class) values. +We distinguish between proper types and type constructors, which take type parameters and yield types. +A subset of proper types called _value types_ represents sets of (first-class) values. Value types are either _concrete_ or _abstract_. -Every concrete value type can be represented as a _class type_, i.e. a -[type designator](#type-designators) that refers to a -[class or a trait](05-classes-and-objects.html#class-definitions) [^1], or as a -[compound type](#compound-types) representing an -intersection of types, possibly with a [refinement](#compound-types) -that further constrains the types of its members. +Every concrete value type can be represented as a _class type_, i.e. a [type designator](#type-designators) that refers to a [class or a trait](05-classes-and-objects.html#class-definitions) [^1], or as a [compound type](#compound-types) representing an intersection of types, possibly with a [refinement](#compound-types) that further constrains the types of its members. + -Abstract value types are introduced by [type parameters](04-basic-declarations-and-definitions.html#type-parameters) -and [abstract type bindings](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases). +Abstract value types are introduced by [type parameters](04-basic-declarations-and-definitions.html#type-parameters) and [abstract type bindings](04-basic-declarations-and-definitions.html#type-declarations-and-type-aliases). Parentheses in types can be used for grouping. [^1]: We assume that objects and packages also implicitly define a class (of the same name as the object or package, but inaccessible to user programs). -Non-value types capture properties of identifiers that -[are not values](#non-value-types). For example, a -[type constructor](#type-constructors) does not directly specify a type of -values. However, when a type constructor is applied to the correct type -arguments, it yields a proper type, which may be a value type. +Non-value types capture properties of identifiers that [are not values](#non-value-types). +For example, a [type constructor](#type-constructors) does not directly specify a type of values. +However, when a type constructor is applied to the correct type arguments, it yields a proper type, which may be a value type. -Non-value types are expressed indirectly in Scala. E.g., a method type is -described by writing down a method signature, which in itself is not a real -type, although it gives rise to a corresponding [method type](#method-types). -Type constructors are another example, as one can write -`type Swap[m[_, _], a,b] = m[b, a]`, but there is no syntax to write -the corresponding anonymous type function directly. +Non-value types are expressed indirectly in Scala. +E.g., a method type is described by writing down a method signature, which in itself is not a real type, although it gives rise to a corresponding [method type](#method-types). +Type constructors are another example, as one can write `type Swap[m[_, _], a,b] = m[b, a]`, but there is no syntax to write the corresponding anonymous type function directly. ## Paths @@ -75,30 +64,24 @@ StableId ::= id ClassQualifier ::= ‘[’ id ‘]’ ``` -Paths are not types themselves, but they can be a part of named types -and in that function form a central role in Scala's type system. +Paths are not types themselves, but they can be a part of named types and in that function form a central role in Scala's type system. A path is one of the following. - The empty path ε (which cannot be written explicitly in user programs). - ´C.´`this`, where ´C´ references a class. - The path `this` is taken as a shorthand for ´C.´`this` where - ´C´ is the name of the class directly enclosing the reference. + The path `this` is taken as a shorthand for ´C.´`this` where ´C´ is the name of the class directly enclosing the reference. - ´p.x´ where ´p´ is a path and ´x´ is a stable member of ´p´. - _Stable members_ are packages or members introduced by object definitions or - by value definitions of [non-volatile types](#volatile-types). + _Stable members_ are packages or members introduced by object definitions or by value definitions of [non-volatile types](#volatile-types). - ´C.´`super`´.x´ or ´C.´`super`´[M].x´ - where ´C´ references a class and ´x´ references a - stable member of the super class or designated parent class ´M´ of ´C´. - The prefix `super` is taken as a shorthand for ´C.´`super` where - ´C´ is the name of the class directly enclosing the reference. + where ´C´ references a class and ´x´ references a stable member of the super class or designated parent class ´M´ of ´C´. + The prefix `super` is taken as a shorthand for ´C.´`super` where ´C´ is the name of the class directly enclosing the reference. A _stable identifier_ is a path which ends in an identifier. ## Value Types -Every value in Scala has a type which is of one of the following -forms. +Every value in Scala has a type which is of one of the following forms. ### Singleton Types @@ -106,12 +89,9 @@ forms. SimpleType ::= Path ‘.’ ‘type’ ``` -A _singleton type_ is of the form ´p.´`type`. Where ´p´ is a path pointing to a -value which [conforms](06-expressions.html#expression-typing) to -`scala.AnyRef`, the type denotes the set of values consisting of `null` and the -value denoted by ´p´ (i.e., the value ´v´ for which `v eq p`). Where the path -does not conform to `scala.AnyRef` the type denotes the set consisting of only -the value denoted by ´p´. +A _singleton type_ is of the form ´p.´`type`. +Where ´p´ is a path pointing to a value which [conforms](06-expressions.html#expression-typing) to `scala.AnyRef`, the type denotes the set of values consisting of `null` and the value denoted by ´p´ (i.e., the value ´v´ for which `v eq p`). +Where the path does not conform to `scala.AnyRef` the type denotes the set consisting of only the value denoted by ´p´. @@ -121,21 +101,17 @@ the value denoted by ´p´. SimpleType ::= Literal ``` -A literal type `lit` is a special kind of singleton type which denotes the -single literal value `lit`. Thus, the type ascription `1: 1` gives the most -precise type to the literal value `1`: the literal type `1`. +A literal type `lit` is a special kind of singleton type which denotes the single literal value `lit`. +Thus, the type ascription `1: 1` gives the most precise type to the literal value `1`: the literal type `1`. At run time, an expression `e` is considered to have literal type `lit` if `e == lit`. -Concretely, the result of `e.isInstanceOf[lit]` and `e match { case _ : lit => }` is -determined by evaluating `e == lit`. +Concretely, the result of `e.isInstanceOf[lit]` and `e match { case _ : lit => }` is determined by evaluating `e == lit`. -Literal types are available for all types for which there is dedicated syntax -except `Unit`. This includes the numeric types (other than `Byte` and `Short` -which don't currently have syntax), `Boolean`, `Char` and `String`. +Literal types are available for all types for which there is dedicated syntax except `Unit`. +This includes the numeric types (other than `Byte` and `Short` which don't currently have syntax), `Boolean`, `Char` and `String`. ### Stable Types -A _stable type_ is a singleton type, a literal type, -or a type that is declared to be a subtype of trait `scala.Singleton`. +A _stable type_ is a singleton type, a literal type, or a type that is declared to be a subtype of trait `scala.Singleton`. ### Type Projection @@ -143,8 +119,7 @@ or a type that is declared to be a subtype of trait `scala.Singleton`. SimpleType ::= SimpleType ‘#’ id ``` -A _type projection_ ´T´#´x´ references the type member named -´x´ of type ´T´. +A _type projection_ ´T´#´x´ references the type member named ´x´ of type ´T´. -The names of all type parameters must be pairwise different in their enclosing type parameter clause. The scope of a type parameter includes in each case the whole type parameter clause. Therefore it is possible that a type parameter appears as part of its own bounds or the bounds of other type parameters in the same clause. However, a type parameter may not be bounded directly or indirectly by itself. +The names of all type parameters must be pairwise different in their enclosing type parameter clause. +The scope of a type parameter includes in each case the whole type parameter clause. +Therefore it is possible that a type parameter appears as part of its own bounds or the bounds of other type parameters in the same clause. +However, a type parameter may not be bounded directly or indirectly by itself. -A type constructor parameter adds a nested type parameter clause to the type parameter. The most general form of a type constructor parameter is `´@a_1 ... @a_n \pm t[\mathit{tps}\,]´ >: ´L´ <: ´U´`. +A type constructor parameter adds a nested type parameter clause to the type parameter. +The most general form of a type constructor parameter is `´@a_1 ... @a_n \pm t[\mathit{tps}\,]´ >: ´L´ <: ´U´`. -The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. Higher-order type parameters (the type parameters of a type parameter ´t´) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of ´t´. Therefore, their names must only be pairwise different from the names of other visible parameters. Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a `‘_’`, which is nowhere visible. +The above scoping restrictions are generalized to the case of nested type parameter clauses, which declare higher-order type parameters. +Higher-order type parameters (the type parameters of a type parameter ´t´) are only visible in their immediately surrounding parameter clause (possibly including clauses at a deeper nesting level) and in the bounds of ´t´. +Therefore, their names must only be pairwise different from the names of other visible parameters. +Since the names of higher-order type parameters are thus often irrelevant, they may be denoted with a `‘_’`, which is nowhere visible. ###### Example Here are some well-formed type parameter clauses: @@ -456,53 +405,32 @@ The following type parameter clauses are illegal: ## Variance Annotations -Variance annotations indicate how instances of parameterized types -vary with respect to [subtyping](03-types.html#conformance). A -‘+’ variance indicates a covariant dependency, a -‘-’ variance indicates a contravariant dependency, and a -missing variance indication indicates an invariant dependency. - -A variance annotation constrains the way the annotated type variable -may appear in the type or class which binds the type parameter. In a -type definition `type ´T´[´\mathit{tps}\,´] = ´S´`, or a type -declaration `type ´T´[´\mathit{tps}\,´] >: ´L´ <: ´U´` type parameters labeled -‘+’ must only appear in covariant position whereas -type parameters labeled ‘-’ must only appear in contravariant -position. Analogously, for a class definition -`class ´C´[´\mathit{tps}\,´](´\mathit{ps}\,´) extends ´T´ { ´x´: ´S´ => ...}`, -type parameters labeled -‘+’ must only appear in covariant position in the -self type ´S´ and the template ´T´, whereas type -parameters labeled ‘-’ must only appear in contravariant -position. - -The variance position of a type parameter in a type or template is -defined as follows. Let the opposite of covariance be contravariance, -and the opposite of invariance be itself. The top-level of the type -or template is always in covariant position. The variance position -changes at the following constructs. - -- The variance position of a method parameter is the opposite of the - variance position of the enclosing parameter clause. -- The variance position of a type parameter is the opposite of the - variance position of the enclosing type parameter clause. -- The variance position of the lower bound of a type declaration or type parameter - is the opposite of the variance position of the type declaration or parameter. +Variance annotations indicate how instances of parameterized types vary with respect to [subtyping](03-types.html#conformance). +A ‘+’ variance indicates a covariant dependency, a ‘-’ variance indicates a contravariant dependency, and a missing variance indication indicates an invariant dependency. + +A variance annotation constrains the way the annotated type variable may appear in the type or class which binds the type parameter. +In a type definition `type ´T´[´\mathit{tps}\,´] = ´S´`, or a type declaration `type ´T´[´\mathit{tps}\,´] >: ´L´ <: ´U´` type parameters labeled ‘+’ must only appear in covariant position whereas type parameters labeled ‘-’ must only appear in contravariant position. +Analogously, for a class definition `class ´C´[´\mathit{tps}\,´](´\mathit{ps}\,´) extends ´T´ { ´x´: ´S´ => ...}`, type parameters labeled ‘+’ must only appear in covariant position in the self type ´S´ and the template ´T´, whereas type parameters labeled ‘-’ must only appear in contravariant position. + +The variance position of a type parameter in a type or template is defined as follows. +Let the opposite of covariance be contravariance, and the opposite of invariance be itself. +The top-level of the type or template is always in covariant position. +The variance position changes at the following constructs. + +- The variance position of a method parameter is the opposite of the variance position of the enclosing parameter clause. +- The variance position of a type parameter is the opposite of the variance position of the enclosing type parameter clause. +- The variance position of the lower bound of a type declaration or type parameter is the opposite of the variance position of the type declaration or parameter. - The type of a mutable variable is always in invariant position. - The right-hand side of a type alias is always in invariant position. - The prefix ´S´ of a type selection `´S´#´T´` is always in invariant position. -- For a type argument ´T´ of a type `´S´[´... T ...´ ]`: If the - corresponding type parameter is invariant, then ´T´ is in - invariant position. If the corresponding type parameter is - contravariant, the variance position of ´T´ is the opposite of - the variance position of the enclosing type `´S´[´... T ...´ ]`. +- For a type argument ´T´ of a type `´S´[´... T ...´ ]`: +If the corresponding type parameter is invariant, then ´T´ is in invariant position. +If the corresponding type parameter is contravariant, the variance position of ´T´ is the opposite of the variance position of the enclosing type `´S´[´... T ...´ ]`. -References to the type parameters in -[object-private or object-protected values, types, variables, or methods](05-classes-and-objects.html#modifiers) of the class are not -checked for their variance position. In these members the type parameter may -appear anywhere without restricting its legal variance annotations. +References to the type parameters in [object-private or object-protected values, types, variables, or methods](05-classes-and-objects.html#modifiers) of the class are not checked for their variance position. +In these members the type parameter may appear anywhere without restricting its legal variance annotations. ###### Example The following variance annotation is legal. @@ -513,16 +441,14 @@ abstract class P[+A, +B] { } ``` -With this variance annotation, type instances -of ´P´ subtype covariantly with respect to their arguments. +With this variance annotation, type instances of ´P´ subtype covariantly with respect to their arguments. For instance, ```scala P[IOException, String] <: P[Throwable, AnyRef] ``` -If the members of ´P´ are mutable variables, -the same variance annotation becomes illegal. +If the members of ´P´ are mutable variables, the same variance annotation becomes illegal. ```scala abstract class Q[+A, +B](x: A, y: B) { @@ -531,8 +457,7 @@ abstract class Q[+A, +B](x: A, y: B) { } ``` -If the mutable variables are object-private, the class definition -becomes legal again: +If the mutable variables are object-private, the class definition becomes legal again: ```scala abstract class R[+A, +B](x: A, y: B) { @@ -543,8 +468,7 @@ abstract class R[+A, +B](x: A, y: B) { ###### Example -The following variance annotation is illegal, since ´a´ appears -in contravariant position in the parameter of `append`: +The following variance annotation is illegal, since ´a´ appears in contravariant position in the parameter of `append`: ```scala abstract class Sequence[+A] { @@ -554,8 +478,7 @@ abstract class Sequence[+A] { } ``` -The problem can be avoided by generalizing the type of `append` -by means of a lower bound: +The problem can be avoided by generalizing the type of `append` by means of a lower bound: ```scala abstract class Sequence[+A] { @@ -571,11 +494,8 @@ abstract class OutputChannel[-A] { } ``` -With that annotation, we have that -`OutputChannel[AnyRef]` conforms to `OutputChannel[String]`. -That is, a -channel on which one can write any object can substitute for a channel -on which one can write only strings. +With that annotation, we have that `OutputChannel[AnyRef]` conforms to `OutputChannel[String]`. +That is, a channel on which one can write any object can substitute for a channel on which one can write only strings. ## Function Declarations and Definitions @@ -595,47 +515,27 @@ ParamType ::= Type | Type ‘*’ ``` -A _function declaration_ has the form `def ´f\,\mathit{psig}´: ´T´`, where -´f´ is the function's name, ´\mathit{psig}´ is its parameter -signature and ´T´ is its result type. A _function definition_ -`def ´f\,\mathit{psig}´: ´T´ = ´e´` also includes a _function body_ ´e´, -i.e. an expression which defines the function's result. A parameter -signature consists of an optional type parameter clause `[´\mathit{tps}\,´]`, -followed by zero or more value parameter clauses -`(´\mathit{ps}_1´)...(´\mathit{ps}_n´)`. Such a declaration or definition -introduces a value with a (possibly polymorphic) method type whose -parameter types and result type are as given. - -The type of the function body is expected to [conform](06-expressions.html#expression-typing) -to the function's declared -result type, if one is given. If the function definition is not -recursive, the result type may be omitted, in which case it is -determined from the packed type of the function body. - -A _type parameter clause_ ´\mathit{tps}´ consists of one or more -[type declarations](#type-declarations-and-type-aliases), which introduce type -parameters, possibly with bounds. The scope of a type parameter includes -the whole signature, including any of the type parameter bounds as -well as the function body, if it is present. - -A _value parameter clause_ ´\mathit{ps}´ consists of zero or more formal -parameter bindings such as `´x´: ´T´` or `´x: T = e´`, which bind value -parameters and associate them with their types. +A _function declaration_ has the form `def ´f\,\mathit{psig}´: ´T´`, where ´f´ is the function's name, ´\mathit{psig}´ is its parameter signature and ´T´ is its result type. +A _function definition_ `def ´f\,\mathit{psig}´: ´T´ = ´e´` also includes a _function body_ ´e´, i.e. an expression which defines the function's result. +A parameter signature consists of an optional type parameter clause `[´\mathit{tps}\,´]`, followed by zero or more value parameter clauses `(´\mathit{ps}_1´)...(´\mathit{ps}_n´)`. +Such a declaration or definition introduces a value with a (possibly polymorphic) method type whose parameter types and result type are as given. + +The type of the function body is expected to [conform](06-expressions.html#expression-typing) to the function's declared result type, if one is given. +If the function definition is not recursive, the result type may be omitted, in which case it is determined from the packed type of the function body. + +A _type parameter clause_ ´\mathit{tps}´ consists of one or more [type declarations](#type-declarations-and-type-aliases), which introduce type parameters, possibly with bounds. +The scope of a type parameter includes the whole signature, including any of the type parameter bounds as well as the function body, if it is present. + +A _value parameter clause_ ´\mathit{ps}´ consists of zero or more formal parameter bindings such as `´x´: ´T´` or `´x: T = e´`, which bind value parameters and associate them with their types. ### Default Arguments -Each value parameter -declaration may optionally define a default argument. The default argument -expression ´e´ is type-checked with an expected type ´T'´ obtained -by replacing all occurrences of the function's type parameters in ´T´ by -the undefined type. - -For every parameter ´p_{i,j}´ with a default argument a method named -`´f\$´default´\$´n` is generated which computes the default argument -expression. Here, ´n´ denotes the parameter's position in the method -declaration. These methods are parametrized by the type parameter clause -`[´\mathit{tps}\,´]` and all value parameter clauses -`(´\mathit{ps}_1´)...(´\mathit{ps}_{i-1}´)` preceding ´p_{i,j}´. +Each value parameter declaration may optionally define a default argument. +The default argument expression ´e´ is type-checked with an expected type ´T'´ obtained by replacing all occurrences of the function's type parameters in ´T´ by the undefined type. + +For every parameter ´p_{i,j}´ with a default argument a method named `´f\$´default´\$´n` is generated which computes the default argument expression. +Here, ´n´ denotes the parameter's position in the method declaration. +These methods are parametrized by the type parameter clause `[´\mathit{tps}\,´]` and all value parameter clauses `(´\mathit{ps}_1´)...(´\mathit{ps}_{i-1}´)` preceding ´p_{i,j}´. The `´f\$´default´\$´n` methods are inaccessible for user programs. ###### Example @@ -646,22 +546,19 @@ def compare[T](a: T = 0)(b: T = a) = (a == b) ``` the default expression `0` is type-checked with an undefined expected -type. When applying `compare()`, the default value `0` is inserted -and `T` is instantiated to `Int`. The methods computing the default -arguments have the form: +type. +When applying `compare()`, the default value `0` is inserted and `T` is instantiated to `Int`. +The methods computing the default arguments have the form: ```scala def compare´\$´default´\$´1[T]: Int = 0 def compare´\$´default´\$´2[T](a: T): T = a ``` -The scope of a formal value parameter name ´x´ comprises all subsequent -parameter clauses, as well as the method return type and the function body, if -they are given. Both type parameter names and value parameter names must -be pairwise distinct. +The scope of a formal value parameter name ´x´ comprises all subsequent parameter clauses, as well as the method return type and the function body, if they are given. +Both type parameter names and value parameter names must be pairwise distinct. -A default value which depends on earlier parameters uses the actual arguments -if they are provided, not the default arguments. +A default value which depends on earlier parameters uses the actual arguments if they are provided, not the default arguments. ```scala def f(a: Int = 0)(b: Int = a + 1) = b // OK @@ -669,8 +566,7 @@ def f(a: Int = 0)(b: Int = a + 1) = b // OK f(10)() // returns 11 (not 1) ``` -If an [implicit argument](07-implicits.html#implicit-parameters) -is not found by implicit search, it may be supplied using a default argument. +If an [implicit argument](07-implicits.html#implicit-parameters) is not found by implicit search, it may be supplied using a default argument. ```scala implicit val i: Int = 2 @@ -684,16 +580,12 @@ f // "hihi" ParamType ::= ‘=>’ Type ``` -The type of a value parameter may be prefixed by `=>`, e.g. -`´x´: => ´T´`. The type of such a parameter is then the -parameterless method type `=> ´T´`. This indicates that the -corresponding argument is not evaluated at the point of function -application, but instead is evaluated at each use within the -function. That is, the argument is evaluated using _call-by-name_. +The type of a value parameter may be prefixed by `=>`, e.g. `´x´: => ´T´`. +The type of such a parameter is then the parameterless method type `=> ´T´`. +This indicates that the corresponding argument is not evaluated at the point of function application, but instead is evaluated at each use within the function. +That is, the argument is evaluated using _call-by-name_. -The by-name modifier is disallowed for parameters of classes that -carry a `val` or `var` prefix, including parameters of case -classes for which a `val` prefix is implicitly generated. +The by-name modifier is disallowed for parameters of classes that carry a `val` or `var` prefix, including parameters of case classes for which a `val` prefix is implicitly generated. ###### Example The declaration @@ -702,8 +594,7 @@ The declaration def whileLoop (cond: => Boolean) (stat: => Unit): Unit ``` -indicates that both parameters of `whileLoop` are evaluated using -call-by-name. +indicates that both parameters of `whileLoop` are evaluated using call-by-name. ### Repeated Parameters @@ -711,30 +602,16 @@ call-by-name. ParamType ::= Type ‘*’ ``` -The last value parameter of a parameter section may be suffixed by -`'*'`, e.g. `(..., ´x´:´T´*)`. The type of such a -_repeated_ parameter inside the method is then the sequence type -`scala.Seq[´T´]`. Methods with repeated parameters -`´T´*` take a variable number of arguments of type ´T´. -That is, if a method ´m´ with type -`(´p_1:T_1, ..., p_n:T_n, p_s:S´*)´U´` is applied to arguments -´(e_1, ..., e_k)´ where ´k \geq n´, then ´m´ is taken in that application -to have type ´(p_1:T_1, ..., p_n:T_n, p_s:S, ..., p_{s'}:S)U´, with -´k - n´ occurrences of type -´S´ where any parameter names beyond ´p_s´ are fresh. The only exception to -this rule is if the last argument is -marked to be a _sequence argument_ via a `_*` type -annotation. If ´m´ above is applied to arguments -`(´e_1, ..., e_n, e'´: _*)`, then the type of ´m´ in -that application is taken to be -`(´p_1:T_1, ... , p_n:T_n,p_{s}:´scala.Seq[´S´])`. - -It is not allowed to define any default arguments in a parameter section -with a repeated parameter. +The last value parameter of a parameter section may be suffixed by `'*'`, e.g. `(..., ´x´:´T´*)`. +The type of such a _repeated_ parameter inside the method is then the sequence type `scala.Seq[´T´]`. +Methods with repeated parameters `´T´*` take a variable number of arguments of type ´T´. +That is, if a method ´m´ with type `(´p_1:T_1, ..., p_n:T_n, p_s:S´*)´U´` is applied to arguments ´(e_1, ..., e_k)´ where ´k \geq n´, then ´m´ is taken in that application to have type ´(p_1:T_1, ..., p_n:T_n, p_s:S, ..., p_{s'}:S)U´, with ´k - n´ occurrences of type ´S´ where any parameter names beyond ´p_s´ are fresh. The only exception to this rule is if the last argument is marked to be a _sequence argument_ via a `_*` type annotation. +If ´m´ above is applied to arguments `(´e_1, ..., e_n, e'´: _*)`, then the type of ´m´ in that application is taken to be `(´p_1:T_1, ... , p_n:T_n,p_{s}:´scala.Seq[´S´])`. + +It is not allowed to define any default arguments in a parameter section with a repeated parameter. ###### Example -The following method definition computes the sum of the squares of a -variable number of integer arguments. +The following method definition computes the sum of the squares of a variable number of integer arguments. ```scala def sum(args: Int*) = { @@ -744,8 +621,7 @@ def sum(args: Int*) = { } ``` -The following applications of this method yield `0`, `1`, -`6`, in that order. +The following applications of this method yield `0`, `1`, `6`, in that order. ```scala sum() @@ -765,8 +641,7 @@ The following application of method `sum` is ill-formed: sum(xs) // ***** error: expected: Int, found: List[Int] ``` -By contrast, the following application is well formed and yields again -the result `6`: +By contrast, the following application is well formed and yields again the result `6`: ```scala sum(xs: _*) @@ -779,17 +654,12 @@ FunDcl ::= FunSig FunDef ::= FunSig [nl] ‘{’ Block ‘}’ ``` -Special syntax exists for procedures, i.e. functions that return the -`Unit` value `()`. -A _procedure declaration_ is a function declaration where the result type -is omitted. The result type is then implicitly completed to the -`Unit` type. E.g., `def ´f´(´\mathit{ps}´)` is equivalent to -`def ´f´(´\mathit{ps}´): Unit`. +Special syntax exists for procedures, i.e. functions that return the `Unit` value `()`. +A _procedure declaration_ is a function declaration where the result type is omitted. +The result type is then implicitly completed to the `Unit` type. E.g., `def ´f´(´\mathit{ps}´)` is equivalent to `def ´f´(´\mathit{ps}´): Unit`. -A _procedure definition_ is a function definition where the result type -and the equals sign are omitted; its defining expression must be a block. -E.g., `def ´f´(´\mathit{ps}´) {´\mathit{stats}´}` is equivalent to -`def ´f´(´\mathit{ps}´): Unit = {´\mathit{stats}´}`. +A _procedure definition_ is a function definition where the result type and the equals sign are omitted; its defining expression must be a block. +E.g., `def ´f´(´\mathit{ps}´) {´\mathit{stats}´}` is equivalent to `def ´f´(´\mathit{ps}´): Unit = {´\mathit{stats}´}`. ###### Example Here is a declaration and a definition of a procedure named `write`: @@ -816,14 +686,10 @@ object Terminal extends Writer { ### Method Return Type Inference -A class member definition ´m´ that overrides some other function ´m'´ -in a base class of ´C´ may leave out the return type, even if it is -recursive. In this case, the return type ´R'´ of the overridden -function ´m'´, seen as a member of ´C´, is taken as the return type of -´m´ for each recursive invocation of ´m´. That way, a type ´R´ for the -right-hand side of ´m´ can be determined, which is then taken as the -return type of ´m´. Note that ´R´ may be different from ´R'´, as long -as ´R´ conforms to ´R'´. +A class member definition ´m´ that overrides some other function ´m'´ in a base class of ´C´ may leave out the return type, even if it is recursive. +In this case, the return type ´R'´ of the overridden function ´m'´, seen as a member of ´C´, is taken as the return type of ´m´ for each recursive invocation of ´m´. +That way, a type ´R´ for the right-hand side of ´m´ can be determined, which is then taken as the return type of ´m´. +Note that ´R´ may be different from ´R'´, as long as ´R´ conforms to ´R'´. ###### Example Assume the following definitions: @@ -837,8 +703,7 @@ class C extends I { } ``` -Here, it is OK to leave out the result type of `factorial` -in `C`, even though the method is recursive. +Here, it is OK to leave out the result type of `factorial` in `C`, even though the method is recursive. Member definitions fall into two categories: concrete and abstract. -Members of class ´C´ are either _directly defined_ (i.e. they appear in -´C´'s statement sequence ´\mathit{stats}´) or they are _inherited_. There are two rules -that determine the set of members of a class, one for each category: - -A _concrete member_ of a class ´C´ is any concrete definition ´M´ in -some class ´C_i \in \mathcal{L}(C)´, except if there is a preceding class -´C_j \in \mathcal{L}(C)´ where ´j < i´ which directly defines a concrete -member ´M'´ matching ´M´. - -An _abstract member_ of a class ´C´ is any abstract definition ´M´ -in some class ´C_i \in \mathcal{L}(C)´, except if ´C´ contains already a -concrete member ´M'´ matching ´M´, or if there is a preceding class -´C_j \in \mathcal{L}(C)´ where ´j < i´ which directly defines an abstract -member ´M'´ matching ´M´. - -This definition also determines the [overriding](#overriding) relationships -between matching members of a class ´C´ and its parents. +Members of class ´C´ are either _directly defined_ (i.e. they appear in ´C´'s statement sequence ´\mathit{stats}´) or they are _inherited_. +There are two rules that determine the set of members of a class, one for each category: + +A _concrete member_ of a class ´C´ is any concrete definition ´M´ in some class ´C_i \in \mathcal{L}(C)´, except if there is a preceding clas ´C_j \in \mathcal{L}(C)´ where ´j < i´ which directly defines a concrete member ´M'´ matching ´M´. + +An _abstract member_ of a class ´C´ is any abstract definition ´M´ in some class ´C_i \in \mathcal{L}(C)´, except if ´C´ contains already a concrete member ´M'´ matching ´M´, or if there is a preceding class ´C_j \in \mathcal{L}(C)´ where ´j < i´ which directly defines an abstract member ´M'´ matching ´M´. + +This definition also determines the [overriding](#overriding) relationships between matching members of a class ´C´ and its parents. First, a concrete definition always overrides an abstract definition. -Second, for definitions ´M´ and ´M´' which are both concrete or both abstract, -´M´ overrides ´M'´ if ´M´ appears in a class that precedes (in the -linearization of ´C´) the class in which ´M'´ is defined. +Second, for definitions ´M´ and ´M´' which are both concrete or both abstract, ´M´ overrides ´M'´ if ´M´ appears in a class that precedes (in the linearization of ´C´) the class in which ´M'´ is defined. -It is an error if a template directly defines two matching members. It -is also an error if a template contains two members (directly defined -or inherited) with the same name and the same [erased type](03-types.html#type-erasure). -Finally, a template is not allowed to contain two methods (directly -defined or inherited) with the same name which both define default arguments. +It is an error if a template directly defines two matching members. +It is also an error if a template contains two members (directly defined or inherited) with the same name and the same [erased type](03-types.html#type-erasure). +Finally, a template is not allowed to contain two methods (directly defined or inherited) with the same name which both define default arguments. ###### Example Consider the trait definitions: @@ -314,64 +231,46 @@ trait C extends A { override def f: Int = 4 ; def g: Int } trait D extends B with C { def h: Int } ``` -Then trait `D` has a directly defined abstract member `h`. It -inherits member `f` from trait `C` and member `g` from -trait `B`. +Then trait `D` has a directly defined abstract member `h`. +It inherits member `f` from trait `C` and member `g` from trait `B`. ### Overriding -A member ´M´ of class ´C´ that [matches](#class-members) -a non-private member ´M'´ of a -base class of ´C´ is said to _override_ that member. In this case -the binding of the overriding member ´M´ must [subsume](03-types.html#conformance) -the binding of the overridden member ´M'´. -Furthermore, the following restrictions on modifiers apply to ´M´ and -´M'´: +A member ´M´ of class ´C´ that [matches](#class-members) a non-private member ´M'´ of a base class of ´C´ is said to _override_ that member. +In this case the binding of the overriding member ´M´ must [subsume](03-types.html#conformance) the binding of the overridden member ´M'´. +Furthermore, the following restrictions on modifiers apply to ´M´ and ´M'´: - ´M'´ must not be labeled `final`. - ´M´ must not be [`private`](#modifiers). -- If ´M´ is labeled `private[´C´]` for some enclosing class or package ´C´, - then ´M'´ must be labeled `private[´C'´]` for some class or package ´C'´ where - ´C'´ equals ´C´ or ´C'´ is contained in ´C´. +- If ´M´ is labeled `private[´C´]` for some enclosing class or package ´C´, then ´M'´ must be labeled `private[´C'´]` for some class or package ´C'´ where ´C'´ equals ´C´ or ´C'´ is contained in ´C´. -- If ´M´ is labeled `protected`, then ´M'´ must also be - labeled `protected`. +- If ´M´ is labeled `protected`, then ´M'´ must also be labeled `protected`. - If ´M'´ is not an abstract member, then ´M´ must be labeled `override`. - Furthermore, one of two possibilities must hold: +Furthermore, one of two possibilities must hold: - either ´M´ is defined in a subclass of the class where is ´M'´ is defined, - - or both ´M´ and ´M'´ override a third member ´M''´ which is defined - in a base class of both the classes containing ´M´ and ´M'´ -- If ´M'´ is [incomplete](#modifiers) in ´C´ then ´M´ must be - labeled `abstract override`. -- If ´M´ and ´M'´ are both concrete value definitions, then either none - of them is marked `lazy` or both must be marked `lazy`. + - or both ´M´ and ´M'´ override a third member ´M''´ which is defined in a base class of both the classes containing ´M´ and ´M'´ +- If ´M'´ is [incomplete](#modifiers) in ´C´ then ´M´ must be labeled `abstract override`. +- If ´M´ and ´M'´ are both concrete value definitions, then either none of them is marked `lazy` or both must be marked `lazy`. - A stable member can only be overridden by a stable member. - For example, this is not allowed: +For example, this is not allowed: ```scala class X { val stable = 1} class Y extends X { override var stable = 1 } // error ``` -Another restriction applies to abstract type members: An abstract type -member with a [volatile type](03-types.html#volatile-types) as its upper -bound may not override an abstract type member which does not have a -volatile upper bound. +Another restriction applies to abstract type members: +An abstract type member with a [volatile type](03-types.html#volatile-types) as its upper bound may not override an abstract type member which does not have a volatile upper bound. -A special rule concerns parameterless methods. If a parameterless -method defined as `def ´f´: ´T´ = ...` or `def ´f´ = ...` overrides a method of -type ´()T'´ which has an empty parameter list, then ´f´ is also -assumed to have an empty parameter list. +A special rule concerns parameterless methods. +If a parameterless method defined as `def ´f´: ´T´ = ...` or `def ´f´ = ...` overrides a method of type ´()T'´ which has an empty parameter list, then ´f´ is also assumed to have an empty parameter list. -An overriding method inherits all default arguments from the definition -in the superclass. By specifying default arguments in the overriding method -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). +An overriding method inherits all default arguments from the definition in the superclass. +By specifying default arguments in the overriding method 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 @@ -384,12 +283,9 @@ trait B extends Root { type T <: B } trait C extends A with B ``` -Then the class definition `C` is not well-formed because the -binding of `T` in `C` is -`type T <: B`, -which fails to subsume the binding `type T <: A` of `T` -in type `A`. The problem can be solved by adding an overriding -definition of type `T` in class `C`: +Then the class definition `C` is not well-formed because the binding of `T` in `C` is `type T <: B`, which fails to subsume the binding `type T <: A` of `T` +in type `A`. +The problem can be solved by adding an overriding definition of type `T` in class `C`: ```scala class C extends A with B { type T <: C } @@ -397,18 +293,15 @@ class C extends A with B { type T <: C } ### Inheritance Closure -Let ´C´ be a class type. The _inheritance closure_ of ´C´ is the -smallest set ´\mathscr{S}´ of types such that +Let ´C´ be a class type. +The _inheritance closure_ of ´C´ is the smallest set ´\mathscr{S}´ of types such that - ´C´ is in ´\mathscr{S}´. -- If ´T´ is in ´\mathscr{S}´, then every type ´T'´ which forms syntactically - a part of ´T´ is also in ´\mathscr{S}´. -- If ´T´ is a class type in ´\mathscr{S}´, then all [parents](#templates) - of ´T´ are also in ´\mathscr{S}´. +- If ´T´ is in ´\mathscr{S}´, then every type ´T'´ which forms syntactically a part of ´T´ is also in ´\mathscr{S}´. +- If ´T´ is a class type in ´\mathscr{S}´, then all [parents](#templates) of ´T´ are also in ´\mathscr{S}´. -It is a static error if the inheritance closure of a class type -consists of an infinite number of types. (This restriction is -necessary to make subtyping decidable[^kennedy]). +It is a static error if the inheritance closure of a class type consists of an infinite number of types. +(This restriction is necessary to make subtyping decidable[^kennedy]). [^kennedy]: Kennedy, Pierce. [On Decidability of Nominal Subtyping with Variance.]( https://research.microsoft.com/pubs/64041/fool2007.pdf) in FOOL 2007 @@ -419,9 +312,8 @@ EarlyDefs ::= ‘{’ [EarlyDef {semi EarlyDef}] ‘}’ ‘with’ EarlyDef ::= {Annotation} {Modifier} PatVarDef ``` -A template may start with an _early field definition_ clause, -which serves to define certain field values before the supertype -constructor is called. In a template +A template may start with an _early field definition_ clause, which serves to define certain field values before the supertype constructor is called. +In a template ```scala { val ´p_1´: ´T_1´ = ´e_1´ @@ -430,33 +322,21 @@ constructor is called. In a template } with ´sc´ with ´mt_1´ with ´mt_n´ { ´\mathit{stats}´ } ``` -The initial pattern definitions of ´p_1 , \ldots , p_n´ are called -_early definitions_. They define fields -which form part of the template. Every early definition must define -at least one variable. - -An early definition is type-checked and evaluated in the scope which -is in effect just before the template being defined, augmented by any -type parameters of the enclosing class and by any early definitions -preceding the one being defined. In particular, any reference to -`this` in an early definition refers -to the identity of `this` just outside the template. Consequently, it -is impossible for an early definition to refer to the object being -constructed by the template, or to refer to one of its fields and -methods, except for any other preceding early definition in the same -section. Furthermore, references to preceding early definitions -always refer to the value that's defined there and do not take into account -overriding definitions. In other words, a block of early definitions -is evaluated exactly as if it were a local block containing a number of value -definitions. - -Early definitions are evaluated -before the superclass constructor of the template is called, -in the order they are defined. +The initial pattern definitions of ´p_1 , \ldots , p_n´ are called _early definitions_. +They define fields which form part of the template. +Every early definition must define at least one variable. + +An early definition is type-checked and evaluated in the scope which is in effect just before the template being defined, augmented by any type parameters of the enclosing class and by any early definitions preceding the one being defined. +In particular, any reference to `this` in an early definition refers to the identity of `this` just outside the template. +Consequently, it is impossible for an early definition to refer to the object being constructed by the template, or to refer to one of its fields and methods, except for any other preceding early definition in the same section. +Furthermore, references to preceding early definitions always refer to the value that's defined there and do not take into account overriding definitions. +In other words, a block of early definitions is evaluated exactly as if it were a local block containing a number of value definitions. + +Early definitions are evaluated before the superclass constructor of the template is called, in the order they are defined. ###### Example -Early definitions are particularly useful for -traits, which do not have normal constructor parameters. Example: +Early definitions are particularly useful for traits, which do not have normal constructor parameters. +Example: ```scala trait Greeting { @@ -470,14 +350,11 @@ class C extends { } ``` -In the code above, the field `name` is initialized before the -constructor of `Greeting` is called. Therefore, field `msg` in -class `Greeting` is properly initialized to `"How are you, Bob"`. +In the code above, the field `name` is initialized before the constructor of `Greeting` is called. +Therefore, field `msg` in class `Greeting` is properly initialized to `"How are you, Bob"`. -If `name` had been initialized instead in `C`'s normal class -body, it would be initialized after the constructor of -`Greeting`. In that case, `msg` would be initialized to -`"How are you, "`. +If `name` had been initialized instead in `C`'s normal class body, it would be initialized after the constructor of `Greeting`. +In that case, `msg` would be initialized to `"How are you, "`. ## Modifiers @@ -494,45 +371,30 @@ AccessModifier ::= (‘private’ | ‘protected’) [AccessQualifier] AccessQualifier ::= ‘[’ (id | ‘this’) ‘]’ ``` -Member definitions may be preceded by modifiers which affect the -accessibility and usage of the identifiers bound by them. If several -modifiers are given, their order does not matter, but the same -modifier may not occur more than once. Modifiers preceding a repeated -definition apply to all constituent definitions. The rules governing -the validity and meaning of a modifier are as follows. +Member definitions may be preceded by modifiers which affect the accessibility and usage of the identifiers bound by them. +If several modifiers are given, their order does not matter, but the same modifier may not occur more than once. +Modifiers preceding a repeated definition apply to all constituent definitions. +The rules governing the validity and meaning of a modifier are as follows. ### `private` -The `private` modifier can be used with any definition or declaration in a -template. Private members of a template can be accessed only from within the -directly enclosing template and its companion module or -[companion class](#object-definitions). - -The `private` modifier is also valid for -[top-level](09-top-level-definitions.html#packagings) templates. - -A `private` modifier can be _qualified_ with an identifier ´C´ (e.g. -`private[´C´]`) that must denote a class or package enclosing the definition. -Members labeled with such a modifier are accessible respectively only from code -inside the package ´C´ or only from code inside the class ´C´ and its -[companion module](#object-definitions). - -A different form of qualification is `private[this]`. A member -´M´ marked with this modifier is called _object-protected_; it can be accessed only from within -the object in which it is defined. That is, a selection ´p.M´ is only -legal if the prefix is `this` or `´O´.this`, for some -class ´O´ enclosing the reference. In addition, the restrictions for -unqualified `private` apply. - -Members marked private without a qualifier are called _class-private_, -whereas members labeled with `private[this]` -are called _object-private_. A member _is private_ if it is -either class-private or object-private, but not if it is marked -`private[´C´]` where ´C´ is an identifier; in the latter -case the member is called _qualified private_. - -Class-private or object-private members may not be abstract, and may -not have `protected` or `override` modifiers. They are not inherited -by subclasses and they may not override definitions in parent classes. +The `private` modifier can be used with any definition or declaration in a template. +Private members of a template can be accessed only from within the directly enclosing template and its companion module or [companion class](#object-definitions). + +The `private` modifier is also valid for [top-level](09-top-level-definitions.html#packagings) templates. + +A `private` modifier can be _qualified_ with an identifier ´C´ (e.g. `private[´C´]`) that must denote a class or package enclosing the definition. +Members labeled with such a modifier are accessible respectively only from code inside the package ´C´ or only from code inside the class ´C´ and its [companion module](#object-definitions). + +A different form of qualification is `private[this]`. +A member ´M´ marked with this modifier is called _object-protected_; it can be accessed only from within the object in which it is defined. +That is, a selection ´p.M´ is only legal if the prefix is `this` or `´O´.this`, for some class ´O´ enclosing the reference. +In addition, the restrictions for unqualified `private` apply. + +Members marked private without a qualifier are called _class-private_, whereas members labeled with `private[this]` are called _object-private_. +A member _is private_ if it is either class-private or object-private, but not if it is marked `private[´C´]` where ´C´ is an identifier; in the latter case the member is called _qualified private_. + +Class-private or object-private members may not be abstract, and may not have `protected` or `override` modifiers. +They are not inherited by subclasses and they may not override definitions in parent classes. ### `protected` The `protected` modifier applies to class member definitions. @@ -541,91 +403,60 @@ Protected members of a class can be accessed from within - all templates that have the defining class as a base class, - the companion module of any of those classes. -A `protected` modifier can be qualified with an identifier ´C´ (e.g. -`protected[´C´]`) that must denote a class or package enclosing the definition. -Members labeled with such a modifier are also accessible respectively from all -code inside the package ´C´ or from all code inside the class ´C´ and its -[companion module](#object-definitions). - -A protected identifier ´x´ may be used as a member name in a selection -`´r´.´x´` only if one of the following applies: - - The access is within the template defining the member, or, if - a qualification ´C´ is given, inside the package ´C´, - or the class ´C´, or its companion module, or - - ´r´ is one of the reserved words `this` and - `super`, or - - ´r´'s type conforms to a type-instance of the - class which contains the access. - -A different form of qualification is `protected[this]`. A member -´M´ marked with this modifier is called _object-protected_; it can be accessed only from within -the object in which it is defined. That is, a selection ´p.M´ is only -legal if the prefix is `this` or `´O´.this`, for some -class ´O´ enclosing the reference. In addition, the restrictions for -unqualified `protected` apply. +A `protected` modifier can be qualified with an identifier ´C´ (e.g. `protected[´C´]`) that must denote a class or package enclosing the definition. +Members labeled with such a modifier are also accessible respectively from all code inside the package ´C´ or from all code inside the class ´C´ and its [companion module](#object-definitions). + +A protected identifier ´x´ may be used as a member name in a selection `´r´.´x´` only if one of the following applies: + - The access is within the template defining the member, or, if a qualification ´C´ is given, inside the package ´C´, or the class ´C´, or its companion module, or + - ´r´ is one of the reserved words `this` and `super`, or + - ´r´'s type conforms to a type-instance of the class which contains the access. + +A different form of qualification is `protected[this]`. +A member ´M´ marked with this modifier is called _object-protected_; it can be accessed only from within the object in which it is defined. That is, a selection ´p.M´ is only legal if the prefix is `this` or `´O´.this`, for some class ´O´ enclosing the reference. In addition, the restrictions for unqualified `protected` apply. ### `override` The `override` modifier applies to class member definitions or declarations. -It is mandatory for member definitions or declarations that override some -other concrete member definition in a parent class. If an `override` -modifier is given, there must be at least one overridden member -definition or declaration (either concrete or abstract). +It is mandatory for member definitions or declarations that override some other concrete member definition in a parent class. +If an `override` modifier is given, there must be at least one overridden member definition or declaration (either concrete or abstract). ### `abstract override` -The `override` modifier has an additional significance when -combined with the `abstract` modifier. That modifier combination -is only allowed for value members of traits. +The `override` modifier has an additional significance when combined with the `abstract` modifier. +That modifier combination is only allowed for value members of traits. -We call a member ´M´ of a template _incomplete_ if it is either -abstract (i.e. defined by a declaration), or it is labeled -`abstract` and `override` and -every member overridden by ´M´ is again incomplete. +We call a member ´M´ of a template _incomplete_ if it is either abstract (i.e. defined by a declaration), or it is labeled `abstract` and `override` and every member overridden by ´M´ is again incomplete. -Note that the `abstract override` modifier combination does not -influence the concept whether a member is concrete or abstract. A -member is _abstract_ if only a declaration is given for it; -it is _concrete_ if a full definition is given. +Note that the `abstract override` modifier combination does not influence the concept whether a member is concrete or abstract. +A member is _abstract_ if only a declaration is given for it; it is _concrete_ if a full definition is given. ### `abstract` -The `abstract` modifier is used in class definitions. It is -redundant for traits, and mandatory for all other classes which have -incomplete members. Abstract classes cannot be -[instantiated](06-expressions.html#instance-creation-expressions) with a constructor invocation -unless followed by mixins and/or a refinement which override all -incomplete members of the class. Only abstract classes and traits can have -abstract term members. - -The `abstract` modifier can also be used in conjunction with -`override` for class member definitions. In that case the -previous discussion applies. +The `abstract` modifier is used in class definitions. +It is redundant for traits, and mandatory for all other classes which have incomplete members. +Abstract classes cannot be [instantiated](06-expressions.html#instance-creation-expressions) with a constructor invocation unless followed by mixins and/or a refinement which override all incomplete members of the class. +Only abstract classes and traits can have abstract term members. + +The `abstract` modifier can also be used in conjunction with `override` for class member definitions. +In that case the previous discussion applies. ### `final` -The `final` modifier applies to class member definitions and to -class definitions. A `final` class member definition may not be -overridden in subclasses. A `final` class may not be inherited by -a template. `final` is redundant for object definitions. Members -of final classes or objects are implicitly also final, so the -`final` modifier is generally redundant for them, too. Note, however, that -[constant value definitions](04-basic-declarations-and-definitions.html#value-declarations-and-definitions) -do require an explicit `final` modifier, -even if they are defined in a final class or object. -`final` is permitted for abstract classes -but it may not be applied to traits or incomplete members, -and it may not be combined in one modifier list with `sealed`. +The `final` modifier applies to class member definitions and to class definitions. +A `final` class member definition may not be overridden in subclasses. +A `final` class may not be inherited by a template. +`final` is redundant for object definitions. +Members of final classes or objects are implicitly also final, so the `final` modifier is generally redundant for them, too. +Note, however, that [constant value definitions](04-basic-declarations-and-definitions.html#value-declarations-and-definitions) do require an explicit `final` modifier, even if they are defined in a final class or object. +`final` is permitted for abstract classes but it may not be applied to traits or incomplete members, and it may not be combined in one modifier list with `sealed`. ### `sealed` -The `sealed` modifier applies to class definitions. A -`sealed` class may not be directly inherited, except if the inheriting -template is defined in the same source file as the inherited class. +The `sealed` modifier applies to class definitions. +A `sealed` class may not be directly inherited, except if the inheriting template is defined in the same source file as the inherited class. However, subclasses of a sealed class can be inherited anywhere. ### `lazy` -The `lazy` modifier applies to value definitions. A `lazy` -value is initialized the first time it is accessed (which might never -happen at all). Attempting to access a lazy value during its -initialization might lead to looping behavior. If an exception is -thrown during initialization, the value is considered uninitialized, -and a later access will retry to evaluate its right hand side. +The `lazy` modifier applies to value definitions. +A `lazy` value is initialized the first time it is accessed (which might never +happen at all). +Attempting to access a lazy value during its initialization might lead to looping behavior. +If an exception is thrown during initialization, the value is considered uninitialized, and a later access will retry to evaluate its right hand side. ###### Example The following code illustrates the use of qualified private: @@ -641,18 +472,12 @@ class Outer { } ``` -Here, accesses to the method `f` can appear anywhere within -`Outer`, but not outside it. Accesses to method -`g` can appear anywhere within the package -`outerpkg.innerpkg`, as would be the case for -package-private methods in Java. Finally, accesses to method -`h` can appear anywhere within package `outerpkg`, -including packages contained in it. +Here, accesses to the method `f` can appear anywhere within `Outer`, but not outside it. +Accesses to method `g` can appear anywhere within the package `outerpkg.innerpkg`, as would be the case for package-private methods in Java. +Finally, accesses to method `h` can appear anywhere within package `outerpkg`, including packages contained in it. ###### Example -A useful idiom to prevent clients of a class from -constructing new instances of that class is to declare the class -`abstract` and `sealed`: +A useful idiom to prevent clients of a class from constructing new instances of that class is to declare the class `abstract` and `sealed`: ```scala object m { @@ -663,18 +488,15 @@ object m { } ``` -For instance, in the code above clients can create instances of class -`m.C` only by calling the `nextC` method of an existing `m.C` -object; it is not possible for clients to create objects of class -`m.C` directly. Indeed the following two lines are both in error: +For instance, in the code above clients can create instances of class `m.C` only by calling the `nextC` method of an existing `m.C` object; it is not possible for clients to create objects of class `m.C` directly. +Indeed the following two lines are both in error: ```scala new m.C(0) // **** error: C is abstract, so it cannot be instantiated. new m.C(0) {} // **** error: illegal inheritance from sealed class. ``` -A similar access restriction can be achieved by marking the primary -constructor `private` ([example](#example-private-constructor)). +A similar access restriction can be achieved by marking the primary constructor `private` ([example](#example-private-constructor)). ## Class Definitions @@ -700,31 +522,23 @@ class ´c´[´\mathit{tps}\,´] ´as´ ´m´(´\mathit{ps}_1´)...(´\mathit{ps} Here, - ´c´ is the name of the class to be defined. - - ´\mathit{tps}´ is a non-empty list of type parameters of the class - being defined. The scope of a type parameter is the whole class - definition including the type parameter section itself. It is - illegal to define two type parameters with the same name. The type - parameter section `[´\mathit{tps}\,´]` may be omitted. A class with a type - parameter section is called _polymorphic_, otherwise it is called - _monomorphic_. - - ´as´ is a possibly empty sequence of - [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 - `private` or `protected`, possibly with a qualification. - If such an access modifier is given it applies to the primary constructor of the class. - - ´(\mathit{ps}\_1)...(\mathit{ps}\_n)´ are formal value parameter clauses for - the _primary constructor_ of the class. The scope of a formal value parameter includes - all subsequent parameter sections and the template ´t´. However, a formal - value parameter may not form part of the types of any of the parent classes or members of the class template ´t´. - It is illegal to define two formal value parameters with the same name. + - ´\mathit{tps}´ is a non-empty list of type parameters of the class being defined. + The scope of a type parameter is the whole class definition including the type parameter section itself. + It is illegal to define two type parameters with the same name. + The type parameter section `[´\mathit{tps}\,´]` may be omitted. + A class with a type parameter section is called _polymorphic_, otherwise it is called _monomorphic_. + - ´as´ is a possibly empty sequence of [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 `private` or `protected`, possibly with a qualification. + If such an access modifier is given it applies to the primary constructor of the class. + - ´(\mathit{ps}\_1)...(\mathit{ps}\_n)´ are formal value parameter clauses for the _primary constructor_ of the class. + The scope of a formal value parameter includes all subsequent parameter sections and the template ´t´. + However, a formal value parameter may not form part of the types of any of the parent classes or members of the class template ´t´. + It is illegal to define two formal value parameters with the same name. If a class has no formal parameter section that is not implicit, an empty parameter section `()` is assumed. - If a formal parameter declaration ´x: T´ is preceded by a `val` - or `var` keyword, an accessor (getter) [definition](04-basic-declarations-and-definitions.html#variable-declarations-and-definitions) - for this parameter is implicitly added to the class. + If a formal parameter declaration ´x: T´ is preceded by a `val` or `var` keyword, an accessor (getter) [definition](04-basic-declarations-and-definitions.html#variable-declarations-and-definitions) for this parameter is implicitly added to the class. The getter introduces a value member ´x´ of class ´c´ that is defined as an alias of the parameter. If the introducing keyword is `var`, a setter accessor [`´x´_=`](04-basic-declarations-and-definitions.html#variable-declarations-and-definitions) is also implicitly added to the class. @@ -740,18 +554,11 @@ Here, ´sc´ with ´mt_1´ with ... with ´mt_m´ { ´\mathit{stats}´ } // ´m \geq 0´ ``` - which defines the base classes, behavior and initial state of objects of - the class. The extends clause - `extends ´sc´ with ´mt_1´ with ... with ´mt_m´` - can be omitted, in which case - `extends scala.AnyRef` is assumed. The class body - `{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body - `{}` is assumed. + which defines the base classes, behavior and initial state of objects of the class. + The extends clause `extends ´sc´ with ´mt_1´ with ... with ´mt_m´` can be omitted, in which case `extends scala.AnyRef` is assumed. + The class body `{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body `{}` is assumed. -This class definition defines a type `´c´[´\mathit{tps}\,´]` and a constructor -which when applied to parameters conforming to types ´\mathit{ps}´ -initializes instances of type `´c´[´\mathit{tps}\,´]` by evaluating the template -´t´. +This class definition defines a type `´c´[´\mathit{tps}\,´]` and a constructor which when applied to parameters conforming to types ´\mathit{ps}´ initializes instances of type `´c´[´\mathit{tps}\,´]` by evaluating the template ´t´. ###### Example – `val` and `var` parameters The following example illustrates `val` and `var` parameters of a class `C`: @@ -787,45 +594,21 @@ ConstrBlock ::= ‘{’ SelfInvocation {semi BlockStat} ‘}’ SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs} ``` -A class may have additional constructors besides the primary -constructor. These are defined by constructor definitions of the form -`def this(´\mathit{ps}_1´)...(´\mathit{ps}_n´) = ´e´`. Such a -definition introduces an additional constructor for the enclosing -class, with parameters as given in the formal parameter lists ´\mathit{ps}_1 -, ..., \mathit{ps}_n´, and whose evaluation is defined by the constructor -expression ´e´. The scope of each formal parameter is the subsequent -parameter sections and the constructor -expression ´e´. A constructor expression is either a self constructor -invocation `this(´\mathit{args}_1´)...(´\mathit{args}_n´)` or a block -which begins with a self constructor invocation. The self constructor -invocation must construct a generic instance of the class. I.e. if the -class in question has name ´C´ and type parameters -`[´\mathit{tps}\,´]`, then a self constructor invocation must -generate an instance of `´C´[´\mathit{tps}\,´]`; it is not permitted -to instantiate formal type parameters. - -The signature and the self constructor invocation of a constructor -definition are type-checked and evaluated in the scope which is in -effect at the point of the enclosing class definition, augmented by -any type parameters of the enclosing class and by any -[early definitions](#early-definitions) of the enclosing template. -The rest of the -constructor expression is type-checked and evaluated as a function -body in the current class. - -If there are auxiliary constructors of a class ´C´, they form together -with ´C´'s primary [constructor](#class-definitions) -an overloaded constructor -definition. The usual rules for -[overloading resolution](06-expressions.html#overloading-resolution) -apply for constructor invocations of ´C´, -including for the self constructor invocations in the constructor -expressions themselves. However, unlike other methods, constructors -are never inherited. To prevent infinite cycles of constructor -invocations, there is the restriction that every self constructor -invocation must refer to a constructor definition which precedes it -(i.e. it must refer to either a preceding auxiliary constructor or the -primary constructor of the class). +A class may have additional constructors besides the primary constructor. +These are defined by constructor definitions of the form `def this(´\mathit{ps}_1´)...(´\mathit{ps}_n´) = ´e´`. +Such a definition introduces an additional constructor for the enclosing class, with parameters as given in the formal parameter lists ´\mathit{ps}_1 , ..., \mathit{ps}_n´, and whose evaluation is defined by the constructor expression ´e´. +The scope of each formal parameter is the subsequent parameter sections and the constructor expression ´e´. +A constructor expression is either a self constructor invocation `this(´\mathit{args}_1´)...(´\mathit{args}_n´)` or a block which begins with a self constructor invocation. +The self constructor invocation must construct a generic instance of the class. +I.e. if the class in question has name ´C´ and type parameters `[´\mathit{tps}\,´]`, then a self constructor invocation must generate an instance of `´C´[´\mathit{tps}\,´]`; it is not permitted to instantiate formal type parameters. + +The signature and the self constructor invocation of a constructor definition are type-checked and evaluated in the scope which is in effect at the point of the enclosing class definition, augmented by any type parameters of the enclosing class and by any [early definitions](#early-definitions) of the enclosing template. +The rest of the constructor expression is type-checked and evaluated as a function body in the current class. + +If there are auxiliary constructors of a class ´C´, they form together with ´C´'s primary [constructor](#class-definitions) an overloaded constructor definition. +The usual rules for [overloading resolution](06-expressions.html#overloading-resolution) apply for constructor invocations of ´C´, including for the self constructor invocations in the constructor expressions themselves. +However, unlike other methods, constructors are never inherited. +To prevent infinite cycles of constructor invocations, there is the restriction that every self constructor invocation must refer to a constructor definition which precedes it (i.e. it must refer to either a preceding auxiliary constructor or the primary constructor of the class). ###### Example Consider the class definition @@ -839,9 +622,8 @@ class LinkedList[A]() { } ``` -This defines a class `LinkedList` with three constructors. The -second constructor constructs a singleton list, while the -third one constructs a list with a given head and tail. +This defines a class `LinkedList` with three constructors. +The second constructor constructs a singleton list, while the third one constructs a list with a given head and tail. ### Case Classes @@ -849,21 +631,16 @@ third one constructs a list with a given head and tail. TmplDef ::= ‘case’ ‘class’ ClassDef ``` -If a class definition is prefixed with `case`, the class is said -to be a _case class_. +If a class definition is prefixed with `case`, the class is said to be a _case class_. A case class is required to have a parameter section that is not implicit. -The formal parameters in the first parameter section -are called _elements_ and are treated specially. -First, the value of such a parameter can be extracted as a -field of a constructor pattern. Second, a `val` prefix is -implicitly added to such a parameter, unless the parameter already carries -a `val` or `var` modifier. Hence, an accessor -definition for the parameter is [generated](#class-definitions). - -A case class definition of `´c´[´\mathit{tps}\,´](´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)` with type -parameters ´\mathit{tps}´ and value parameters ´\mathit{ps}´ implies -the definition of a companion object, which serves as an [extractor object](08-pattern-matching.html#extractor-patterns). It has the following shape: +The formal parameters in the first parameter section are called _elements_ and are treated specially. +First, the value of such a parameter can be extracted as a field of a constructor pattern. +Second, a `val` prefix is implicitly added to such a parameter, unless the parameter already carries a `val` or `var` modifier. +Hence, an accessor definition for the parameter is [generated](#class-definitions). + +A case class definition of `´c´[´\mathit{tps}\,´](´\mathit{ps}_1\,´)...(´\mathit{ps}_n´)` with type parameters ´\mathit{tps}´ and value parameters ´\mathit{ps}´ implies the definition of a companion object, which serves as an [extractor object](08-pattern-matching.html#extractor-patterns). +It has the following shape: ```scala object ´c´ { @@ -874,62 +651,38 @@ object ´c´ { } ``` -Here, ´\mathit{Ts}´ stands for the vector of types defined in the type -parameter section ´\mathit{tps}´, -each ´\mathit{xs}\_i´ denotes the parameter names of the parameter -section ´\mathit{ps}\_i´, and -´\mathit{xs}\_{11}, ... , \mathit{xs}\_{1k}´ denote the names of all parameters -in the first parameter section ´\mathit{xs}\_1´. +Here, ´\mathit{Ts}´ stands for the vector of types defined in the type parameter section ´\mathit{tps}´, each ´\mathit{xs}\_i´ denotes the parameter names of the parameter section ´\mathit{ps}\_i´, and ´\mathit{xs}\_{11}, ... , \mathit{xs}\_{1k}´ denote the names of all parameters in the first parameter section ´\mathit{xs}\_1´. If a type parameter section is missing in the class, it is also missing in the `apply` and `unapply` methods. -If the companion object ´c´ is already defined, -the `apply` and `unapply` methods are added to the existing object. -If the object ´c´ already has a [matching](#definition-matching) -`apply` (or `unapply`) member, no new definition is added. +If the companion object ´c´ is already defined, the `apply` and `unapply` methods are added to the existing object. +If the object ´c´ already has a [matching](#definition-matching) `apply` (or `unapply`) member, no new definition is added. The definition of `apply` is omitted if class ´c´ is `abstract`. -If the case class definition contains an empty value parameter list, the -`unapply` method returns a `Boolean` instead of an `Option` type and -is defined as follows: +If the case class definition contains an empty value parameter list, the `unapply` method returns a `Boolean` instead of an `Option` type and is defined as follows: ```scala def unapply[´\mathit{tps}\,´](´x´: ´c´[´\mathit{tps}\,´]) = x ne null ``` -The name of the `unapply` method is changed to `unapplySeq` if the first -parameter section ´\mathit{ps}_1´ of ´c´ ends in a -[repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters). +The name of the `unapply` method is changed to `unapplySeq` if the first parameter section ´\mathit{ps}_1´ of ´c´ ends in a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters). -A method named `copy` is implicitly added to every case class unless the -class already has a member (directly defined or inherited) with that name, or the -class has a repeated parameter. The method is defined as follows: +A method named `copy` is implicitly added to every case class unless the class already has a member (directly defined or inherited) with that name, or the class has a repeated parameter. +The method is defined as follows: ```scala def copy[´\mathit{tps}\,´](´\mathit{ps}'_1\,´)...(´\mathit{ps}'_n´): ´c´[´\mathit{tps}\,´] = new ´c´[´\mathit{Ts}\,´](´\mathit{xs}_1\,´)...(´\mathit{xs}_n´) ``` -Again, `´\mathit{Ts}´` stands for the vector of types defined in the type parameter section `´\mathit{tps}´` -and each `´xs_i´` denotes the parameter names of the parameter section `´ps'_i´`. The value -parameters `´ps'_{1,j}´` of first parameter list have the form `´x_{1,j}´:´T_{1,j}´=this.´x_{1,j}´`, -the other parameters `´ps'_{i,j}´` of the `copy` method are defined as `´x_{i,j}´:´T_{i,j}´`. -In all cases `´x_{i,j}´` and `´T_{i,j}´` refer to the name and type of the corresponding class parameter -`´\mathit{ps}_{i,j}´`. - -Every case class implicitly overrides some method definitions of class -[`scala.AnyRef`](12-the-scala-standard-library.html#root-classes) unless a definition of the same -method is already given in the case class itself or a concrete -definition of the same method is given in some base class of the case -class different from `AnyRef`. In particular: - -- Method `equals: (Any)Boolean` is structural equality, where two - instances are equal if they both belong to the case class in question and they - have equal (with respect to `equals`) constructor arguments (restricted to the class's _elements_, i.e., the first parameter section). -- Method `hashCode: Int` computes a hash-code. If the hashCode methods - of the data structure members map equal (with respect to equals) - values to equal hash-codes, then the case class hashCode method does - too. -- Method `toString: String` returns a string representation which - contains the name of the class and its elements. +Again, `´\mathit{Ts}´` stands for the vector of types defined in the type parameter section `´\mathit{tps}´` and each `´xs_i´` denotes the parameter names of the parameter section `´ps'_i´`. +The value parameters `´ps'_{1,j}´` of first parameter list have the form `´x_{1,j}´:´T_{1,j}´=this.´x_{1,j}´`, the other parameters `´ps'_{i,j}´` of the `copy` method are defined as `´x_{i,j}´:´T_{i,j}´`. +In all cases `´x_{i,j}´` and `´T_{i,j}´` refer to the name and type of the corresponding class parameter `´\mathit{ps}_{i,j}´`. + +Every case class implicitly overrides some method definitions of class [`scala.AnyRef`](12-the-scala-standard-library.html#root-classes) unless a definition of the same method is already given in the case class itself or a concrete definition of the same method is given in some base class of the case class different from `AnyRef`. +In particular: + +- Method `equals: (Any)Boolean` is structural equality, where two instances are equal if they both belong to the case class in question and they have equal (with respect to `equals`) constructor arguments (restricted to the class's _elements_, i.e., the first parameter section). +- Method `hashCode: Int` computes a hash-code. If the hashCode methods of the data structure members map equal (with respect to equals) values to equal hash-codes, then the case class hashCode method does too. +- Method `toString: String` returns a string representation which contains the name of the class and its elements. ###### Example Here is the definition of abstract syntax for lambda calculus: @@ -941,9 +694,7 @@ case class Apply (f: Expr, e: Expr) extends Expr case class Lambda(x: String, e: Expr) extends Expr ``` -This defines a class `Expr` with case classes -`Var`, `Apply` and `Lambda`. A call-by-value evaluator -for lambda expressions could then be written as follows. +This defines a class `Expr` with case classes `Var`, `Apply` and `Lambda`. A call-by-value evaluator for lambda expressions could then be written as follows. ```scala type Env = String => Value @@ -961,17 +712,13 @@ def eval(e: Expr, env: Env): Value = e match { } ``` -It is possible to define further case classes that extend type -`Expr` in other parts of the program, for instance +It is possible to define further case classes that extend type `Expr` in other parts of the program, for instance ```scala case class Number(x: Int) extends Expr ``` -This form of extensibility can be excluded by declaring the base class -`Expr` `sealed`; in this case, all classes that -directly extend `Expr` must be in the same source file as -`Expr`. +This form of extensibility can be excluded by declaring the base class `Expr` `sealed`; in this case, all classes that directly extend `Expr` must be in the same source file as `Expr`. ## Traits @@ -981,28 +728,21 @@ TraitDef ::= id [TypeParamClause] TraitTemplateOpt TraitTemplateOpt ::= ‘extends’ TraitTemplate | [[‘extends’] TemplateBody] ``` -A _trait_ is a class that is meant to be added to some other class -as a mixin. Unlike normal classes, traits cannot have -constructor parameters. Furthermore, no constructor arguments are -passed to the superclass of the trait. This is not necessary as traits are -initialized after the superclass is initialized. +A _trait_ is a class that is meant to be added to some other class as a mixin. +Unlike normal classes, traits cannot have constructor parameters. +Furthermore, no constructor arguments are passed to the superclass of the trait. +This is not necessary as traits are initialized after the superclass is initialized. Assume a trait ´D´ defines some aspect of an instance ´x´ of type ´C´ (i.e. ´D´ is a base class of ´C´). -Then the _actual supertype_ of ´D´ in ´x´ is the compound type consisting of all the -base classes in ´\mathcal{L}(C)´ that succeed ´D´. The actual supertype gives -the context for resolving a [`super` reference](06-expressions.html#this-and-super) in a trait. -Note that the actual supertype depends on the type to which the trait is added in a mixin composition; -it is not statically known at the time the trait is defined. +Then the _actual supertype_ of ´D´ in ´x´ is the compound type consisting of all the base classes in ´\mathcal{L}(C)´ that succeed ´D´. +The actual supertype gives the context for resolving a [`super` reference](06-expressions.html#this-and-super) in a trait. +Note that the actual supertype depends on the type to which the trait is added in a mixin composition; 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). +If ´D´ is not a trait, then its actual supertype is simply its least proper supertype (which is statically known). ###### 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 -comparison operators `<=`, `>`, and -`>=`. +The following trait defines the property of being comparable to objects of some type. +It contains an abstract method `<` and default implementations of the other comparison operators `<=`, `>`, and `>=`. ```scala trait Comparable[T <: Comparable[T]] { self: T => @@ -1014,13 +754,10 @@ trait Comparable[T <: Comparable[T]] { self: T => ``` ###### Example -Consider an abstract class `Table` that implements maps -from a type of keys `A` to a type of values `B`. The class -has a method `set` to enter a new key / value pair into the table, -and a method `get` that returns an optional value matching a -given key. Finally, there is a method `apply` which is like -`get`, except that it returns a given default value if the table -is undefined for the given key. This class is implemented as follows. +Consider an abstract class `Table` that implements maps from a type of keys `A` to a type of values `B`. +The class has a method `set` to enter a new key / value pair into the table, and a method `get` that returns an optional value matching a given key. +Finally, there is a method `apply` which is like `get`, except that it returns a given default value if the table is undefined for the given key. +This class is implemented as follows. ```scala abstract class Table[A, B](defaultValue: B) { @@ -1043,8 +780,7 @@ class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) { } ``` -Here is a trait that prevents concurrent access to the -`get` and `set` operations of its parent class: +Here is a trait that prevents concurrent access to the `get` and `set` operations of its parent class: ```scala trait SynchronizedTable[A, B] extends Table[A, B] { @@ -1055,27 +791,18 @@ trait SynchronizedTable[A, B] extends Table[A, B] { } ``` -Note that `SynchronizedTable` does not pass an argument to -its superclass, `Table`, even though `Table` is defined with a -formal parameter. Note also that the `super` calls -in `SynchronizedTable`'s `get` and `set` methods -statically refer to abstract methods in class `Table`. This is -legal, as long as the calling method is labeled -[`abstract override`](#modifiers). +Note that `SynchronizedTable` does not pass an argument to its superclass, `Table`, even though `Table` is defined with a formal parameter. +Note also that the `super` calls in `SynchronizedTable`'s `get` and `set` methods statically refer to abstract methods in class `Table`. +This is legal, as long as the calling method is labeled [`abstract override`](#modifiers). -Finally, the following mixin composition creates a synchronized list -table with strings as keys and integers as values and with a default -value `0`: +Finally, the following mixin composition creates a synchronized list table with strings as keys and integers as values and with a default value `0`: ```scala object MyTable extends ListTable[String, Int](0) with SynchronizedTable[String, Int] ``` -The object `MyTable` inherits its `get` and `set` -method from `SynchronizedTable`. The `super` calls in these -methods are re-bound to refer to the corresponding implementations in -`ListTable`, which is the actual supertype of `SynchronizedTable` -in `MyTable`. +The object `MyTable` inherits its `get` and `set` method from `SynchronizedTable`. +The `super` calls in these methods are re-bound to refer to the corresponding implementations in `ListTable`, which is the actual supertype of `SynchronizedTable` in `MyTable`. ## Object Definitions @@ -1083,50 +810,36 @@ in `MyTable`. ObjectDef ::= id ClassTemplate ``` -An _object definition_ defines a single object of a new class. Its -most general form is -`object ´m´ extends ´t´`. Here, -´m´ is the name of the object to be defined, and -´t´ is a [template](#templates) of the form +An _object definition_ defines a single object of a new class. +Its most general form is `object ´m´ extends ´t´`. +Here, ´m´ is the name of the object to be defined, and ´t´ is a [template](#templates) of the form ```scala ´sc´ with ´mt_1´ with ... with ´mt_n´ { ´\mathit{stats}´ } ``` which defines the base classes, behavior and initial state of ´m´. -The extends clause `extends ´sc´ with ´mt_1´ with ... with ´mt_n´` -can be omitted, in which case -`extends scala.AnyRef` is assumed. The class body -`{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body -`{}` is assumed. +The extends clause `extends ´sc´ with ´mt_1´ with ... with ´mt_n´` can be omitted, in which case `extends scala.AnyRef` is assumed. +The class body `{ ´\mathit{stats}´ }` may also be omitted, in which case the empty body `{}` is assumed. -The object definition defines a single object (or: _module_) -conforming to the template ´t´. It is roughly equivalent to the -following definition of a lazy value: +The object definition defines a single object (or: _module_) conforming to the template ´t´. +It is roughly equivalent to the following definition of a lazy value: ```scala lazy val ´m´ = new ´sc´ with ´mt_1´ with ... with ´mt_n´ { this: ´m.type´ => ´\mathit{stats}´ } ``` -Note that the value defined by an object definition is instantiated -lazily. The `new ´m´$cls` constructor is evaluated -not at the point of the object definition, but is instead evaluated -the first time ´m´ is dereferenced during execution of the program -(which might be never at all). An attempt to dereference ´m´ again -during evaluation of the constructor will lead to an infinite loop -or run-time error. -Other threads trying to dereference ´m´ while the -constructor is being evaluated block until evaluation is complete. - -The expansion given above is not accurate for top-level objects. It -cannot be because variable and method definition cannot appear on the -top-level outside of a [package object](09-top-level-definitions.html#package-objects). Instead, -top-level objects are translated to static fields. +Note that the value defined by an object definition is instantiated lazily. +The `new ´m´$cls` constructor is evaluated not at the point of the object definition, but is instead evaluated the first time ´m´ is dereferenced during execution of the program (which might be never at all). +An attempt to dereference ´m´ again during evaluation of the constructor will lead to an infinite loop or run-time error. +Other threads trying to dereference ´m´ while the constructor is being evaluated block until evaluation is complete. + +The expansion given above is not accurate for top-level objects. +It cannot be because variable and method definition cannot appear on the top-level outside of a [package object](09-top-level-definitions.html#package-objects). +Instead, top-level objects are translated to static fields. ###### Example -Classes in Scala do not have static members; however, an equivalent -effect can be achieved by an accompanying object definition -E.g. +Classes in Scala do not have static members; however, an equivalent effect can be achieved by an accompanying object definition E.g. ```scala abstract class Point { @@ -1139,22 +852,13 @@ object Point { } ``` -This defines a class `Point` and an object `Point` which -contains `origin` as a member. Note that the double use of the -name `Point` is legal, since the class definition defines the -name `Point` in the type name space, whereas the object -definition defines a name in the term namespace. - -This technique is applied by the Scala compiler when interpreting a -Java class with static members. Such a class ´C´ is conceptually seen -as a pair of a Scala class that contains all instance members of ´C´ -and a Scala object that contains all static members of ´C´. - -Generally, a _companion module_ of a class is an object which has -the same name as the class and is defined in the same scope and -compilation unit. Conversely, the class is called the _companion class_ -of the module. - -Very much like a concrete class definition, an object definition may -still contain declarations of abstract type members, but not of -abstract term members. +This defines a class `Point` and an object `Point` which contains `origin` as a member. +Note that the double use of the name `Point` is legal, since the class definition defines the name `Point` in the type name space, whereas the object definition defines a name in the term namespace. + +This technique is applied by the Scala compiler when interpreting a Java class with static members. +Such a class ´C´ is conceptually seen as a pair of a Scala class that contains all instance members of ´C´ and a Scala object that contains all static members of ´C´. + +Generally, a _companion module_ of a class is an object which has the same name as the class and is defined in the same scope and compilation unit. +Conversely, the class is called the _companion class_ of the module. + +Very much like a concrete class definition, an object definition may still contain declarations of abstract type members, but not of abstract term members. diff --git a/docs/_spec/06-expressions.md b/docs/_spec/06-expressions.md index 36c31af8969c..597756550e6f 100644 --- a/docs/_spec/06-expressions.md +++ b/docs/_spec/06-expressions.md @@ -47,23 +47,21 @@ Ascription ::= ‘:’ InfixType | ‘:’ ‘_’ ‘*’ ``` -Expressions are composed of operators and operands. Expression forms are -discussed subsequently in decreasing order of precedence. +Expressions are composed of operators and operands. +Expression forms are discussed subsequently in decreasing order of precedence. ## Expression Typing -The typing of expressions is often relative to some _expected type_ (which might be undefined). When we write "expression ´e´ is expected to conform to type ´T´", we mean: +The typing of expressions is often relative to some _expected type_ (which might be undefined). +When we write "expression ´e´ is expected to conform to type ´T´", we mean: 1. the expected type of ´e´ is ´T´, and 2. the type of expression ´e´ must conform to ´T´. -The following skolemization rule is applied universally for every -expression: If the type of an expression would be an existential type -´T´, then the type of the expression is assumed instead to be a -[skolemization](03-types.html#existential-types) of ´T´. +The following skolemization rule is applied universally for every expression: +If the type of an expression would be an existential type ´T´, then the type of the expression is assumed instead to be a [skolemization](03-types.html#existential-types) of ´T´. -Skolemization is reversed by type packing. Assume an expression ´e´ of -type ´T´ and let ´t_1[\mathit{tps}\_1] >: L_1 <: U_1, ..., t_n[\mathit{tps}\_n] >: L_n <: U_n´ be -all the type variables created by skolemization of some part of ´e´ which are free in ´T´. +Skolemization is reversed by type packing. +Assume an expression ´e´ of type ´T´ and let ´t_1[\mathit{tps}\_1] >: L_1 <: U_1, ..., t_n[\mathit{tps}\_n] >: L_n <: U_n´ be all the type variables created by skolemization of some part of ´e´ which are free in ´T´. Then the _packed type_ of ´e´ is ```scala @@ -76,8 +74,7 @@ Then the _packed type_ of ´e´ is SimpleExpr ::= Literal ``` -Typing of literals is described along with their [lexical syntax](01-lexical-syntax.html#literals); -their evaluation is immediate. +Typing of literals is described along with their [lexical syntax](01-lexical-syntax.html#literals); their evaluation is immediate. ## The _Null_ Value @@ -85,16 +82,13 @@ The `null` value is of type `scala.Null`, and thus conforms to every reference t It denotes a reference value which refers to a special `null` object. This object implements methods in class `scala.AnyRef` as follows: -- `eq(´x\,´)` and `==(´x\,´)` return `true` iff the - argument ´x´ is also the "null" object. -- `ne(´x\,´)` and `!=(´x\,´)` return true iff the - argument x is not also the "null" object. +- `eq(´x\,´)` and `==(´x\,´)` return `true` iff the argument ´x´ is also the "null" object. +- `ne(´x\,´)` and `!=(´x\,´)` return true iff the argument x is not also the "null" object. - `isInstanceOf[´T\,´]` always returns `false`. - `asInstanceOf[´T\,´]` returns the [default value](04-basic-declarations-and-definitions.html#value-declarations-and-definitions) of type ´T´. - `##` returns ``0``. -A reference to any other member of the "null" object causes a -`NullPointerException` to be thrown. +A reference to any other member of the "null" object causes a `NullPointerException` to be thrown. ## Designators @@ -103,50 +97,31 @@ SimpleExpr ::= Path | SimpleExpr ‘.’ id ``` -A designator refers to a named term. It can be a _simple name_ or -a _selection_. +A designator refers to a named term. It can be a _simple name_ or a _selection_. -A simple name ´x´ refers to a value as specified -[here](02-identifiers-names-and-scopes.html#identifiers,-names-and-scopes). -If ´x´ is bound by a definition or declaration in an enclosing class -or object ´C´, it is taken to be equivalent to the selection -`´C´.this.´x´` where ´C´ is taken to refer to the class containing ´x´ -even if the type name ´C´ is [shadowed](02-identifiers-names-and-scopes.html#identifiers,-names-and-scopes) at the -occurrence of ´x´. +A simple name ´x´ refers to a value as specified [here](02-identifiers-names-and-scopes.html#identifiers,-names-and-scopes). +If ´x´ is bound by a definition or declaration in an enclosing class or object ´C´, it is taken to be equivalent to the selection `´C´.this.´x´` where ´C´ is taken to refer to the class containing ´x´ even if the type name ´C´ is [shadowed](02-identifiers-names-and-scopes.html#identifiers,-names-and-scopes) at the occurrence of ´x´. -If ´r´ is a [stable identifier](03-types.html#paths) of type ´T´, the selection ´r.x´ refers -statically to a term member ´m´ of ´r´ that is identified in ´T´ by -the name ´x´. +If ´r´ is a [stable identifier](03-types.html#paths) of type ´T´, the selection ´r.x´ refers statically to a term member ´m´ of ´r´ that is identified in ´T´ by the name ´x´. -For other expressions ´e´, ´e.x´ is typed as -if it was `{ val ´y´ = ´e´; ´y´.´x´ }`, for some fresh name -´y´. +For other expressions ´e´, ´e.x´ is typed as if it was `{ val ´y´ = ´e´; ´y´.´x´ }`, for some fresh name ´y´. -The expected type of a designator's prefix is always undefined. The -type of a designator is the type ´T´ of the entity it refers to, with -the following exception: The type of a [path](03-types.html#paths) ´p´ -which occurs in a context where a [stable type](03-types.html#singleton-types) -is required is the singleton type `´p´.type`. +The expected type of a designator's prefix is always undefined. +The type of a designator is the type ´T´ of the entity it refers to, with the following exception: The type of a [path](03-types.html#paths) ´p´ which occurs in a context where a [stable type](03-types.html#singleton-types) is required is the singleton type `´p´.type`. -The contexts where a stable type is required are those that satisfy -one of the following conditions: +The contexts where a stable type is required are those that satisfy one of the following conditions: -1. The path ´p´ occurs as the prefix of a selection and it does not -designate a constant, or +1. The path ´p´ occurs as the prefix of a selection and it does not designate a constant, or 1. The expected type ´\mathit{pt}´ is a stable type, or -1. The expected type ´\mathit{pt}´ is an abstract type with a stable type as lower - bound, and the type ´T´ of the entity referred to by ´p´ does not - conform to ´\mathit{pt}´, or +1. The expected type ´\mathit{pt}´ is an abstract type with a stable type as lower bound, and the type ´T´ of the entity referred to by ´p´ does not conform to ´\mathit{pt}´, or 1. The path ´p´ designates a module. -The selection ´e.x´ is evaluated by first evaluating the qualifier -expression ´e´, which yields an object ´r´, say. The selection's -result is then the member of ´r´ that is either defined by ´m´ or defined -by a definition overriding ´m´. +The selection ´e.x´ is evaluated by first evaluating the qualifier expression ´e´, which yields an object ´r´, say. +The selection's result is then the member of ´r´ that is either defined by ´m´ or defined by a definition overriding ´m´. ## This and Super @@ -155,52 +130,34 @@ SimpleExpr ::= [id ‘.’] ‘this’ | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id ``` -The expression `this` can appear in the statement part of a -template or compound type. It stands for the object being defined by -the innermost template or compound type enclosing the reference. If -this is a compound type, the type of `this` is that compound type. -If it is a template of a -class or object definition with simple name ´C´, the type of this -is the same as the type of `´C´.this`. - -The expression `´C´.this` is legal in the statement part of an -enclosing class or object definition with simple name ´C´. It -stands for the object being defined by the innermost such definition. -If the expression's expected type is a stable type, or -`´C´.this` occurs as the prefix of a selection, its type is -`´C´.this.type`, otherwise it is the self type of class ´C´. - -A reference `super.´m´` refers statically to a method or type ´m´ -in the least proper supertype of the innermost template containing the -reference. It evaluates to the member ´m'´ in the actual supertype of -that template which is equal to ´m´ or which overrides ´m´. The -statically referenced member ´m´ must be a type or a -method. +The expression `this` can appear in the statement part of a template or compound type. +It stands for the object being defined by the innermost template or compound type enclosing the reference. +If this is a compound type, the type of `this` is that compound type. +If it is a template of a class or object definition with simple name ´C´, the type of this is the same as the type of `´C´.this`. + +The expression `´C´.this` is legal in the statement part of an enclosing class or object definition with simple name ´C´. +It stands for the object being defined by the innermost such definition. +If the expression's expected type is a stable type, or `´C´.this` occurs as the prefix of a selection, its type is `´C´.this.type`, otherwise it is the self type of class ´C´. + +A reference `super.´m´` refers statically to a method or type ´m´ in the least proper supertype of the innermost template containing the reference. +It evaluates to the member ´m'´ in the actual supertype of that template which is equal to ´m´ or which overrides ´m´. +The statically referenced member ´m´ must be a type or a method. -If it is -a method, it must be concrete, or the template -containing the reference must have a member ´m'´ which overrides ´m´ -and which is labeled `abstract override`. - -A reference `´C´.super.´m´` refers statically to a method -or type ´m´ in the least proper supertype of the innermost enclosing class or -object definition named ´C´ which encloses the reference. It evaluates -to the member ´m'´ in the actual supertype of that class or object -which is equal to ´m´ or which overrides ´m´. The -statically referenced member ´m´ must be a type or a -method. If the statically -referenced member ´m´ is a method, it must be concrete, or the innermost enclosing -class or object definition named ´C´ must have a member ´m'´ which -overrides ´m´ and which is labeled `abstract override`. - -The `super` prefix may be followed by a trait qualifier -`[´T\,´]`, as in `´C´.super[´T\,´].´x´`. This is -called a _static super reference_. In this case, the reference is -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. +If it is a method, it must be concrete, or the template containing the reference must have a member ´m'´ which overrides ´m´ and which is labeled `abstract override`. + +A reference `´C´.super.´m´` refers statically to a method or type ´m´ in the least proper supertype of the innermost enclosing class or object definition named ´C´ which encloses the reference. +It evaluates to the member ´m'´ in the actual supertype of that class or object +which is equal to ´m´ or which overrides ´m´. +The statically referenced member ´m´ must be a type or a method. +If the statically referenced member ´m´ is a method, it must be concrete, or the innermost enclosing class or object definition named ´C´ must have a member ´m'´ which overrides ´m´ and which is labeled `abstract override`. + +The `super` prefix may be followed by a trait qualifier `[´T\,´]`, as in `´C´.super[´T\,´].´x´`. +This is called a _static super reference_. +In this case, the reference is 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 Consider the following class definitions @@ -217,8 +174,7 @@ class D extends A with B { } ``` -The linearization of class `C` is `{C, B, Root}` and -the linearization of class `D` is `{D, B, A, Root}`. +The linearization of class `C` is `{C, B, Root}` and the linearization of class `D` is `{D, B, A, Root}`. Then we have: ```scala @@ -232,8 +188,7 @@ Then we have: (new D).superD == "B" ``` -Note that the `superB` method returns different results -depending on whether `B` is mixed in with class `Root` or `A`. +Note that the `superB` method returns different results depending on whether `B` is mixed in with class `Root` or `A`. ## Function Applications @@ -246,9 +201,13 @@ ArgumentExprs ::= ‘(’ [Exprs] ‘)’ Exprs ::= Expr {‘,’ Expr} ``` -An application `´f(e_1, ..., e_m)´` applies the function `´f´` to the argument expressions `´e_1, ..., e_m´`. For this expression to be well-typed, the function must be *applicable* to its arguments, which is defined next by case analysis on ´f´'s type. +An application `´f(e_1, ..., e_m)´` applies the function `´f´` to the argument expressions `´e_1, ..., e_m´`. +For this expression to be well-typed, the function must be *applicable* to its arguments, which is defined next by case analysis on ´f´'s type. -If ´f´ has a method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´`, each argument expression ´e_i´ is typed with the corresponding parameter type ´T_i´ as expected type. Let ´S_i´ be the type of argument ´e_i´ ´(i = 1, ..., m)´. The method ´f´ must be _applicable_ to its arguments ´e_1, ..., e_n´ of types ´S_1, ..., S_n´. We say that an argument expression ´e_i´ is a _named_ argument if it has the form `´x_i=e'_i´` and `´x_i´` is one of the parameter names `´p_1, ..., p_n´`. +If ´f´ has a method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´`, each argument expression ´e_i´ is typed with the corresponding parameter type ´T_i´ as expected type. +Let ´S_i´ be the type of argument ´e_i´ ´(i = 1, ..., m)´. +The method ´f´ must be _applicable_ to its arguments ´e_1, ..., e_n´ of types ´S_1, ..., S_n´. +We say that an argument expression ´e_i´ is a _named_ argument if it has the form `´x_i=e'_i´` and `´x_i´` is one of the parameter names `´p_1, ..., p_n´`. Once the types ´S_i´ have been determined, the method ´f´ of the above method type is said to be applicable if all of the following conditions hold: - for every named argument ´p_j=e_i'´ the type ´S_i´ is [compatible](03-types.html#compatibility) with the parameter type ´T_j´; @@ -258,57 +217,37 @@ Once the types ´S_i´ have been determined, the method ´f´ of the above metho If ´f´ is a polymorphic method, [local type inference](#local-type-inference) is used to instantiate ´f´'s type parameters. The polymorphic method is applicable if type inference can determine type arguments so that the instantiated method is applicable. -If ´f´ has some value type, the application is taken to be equivalent to `´f´.apply(´e_1, ..., e_m´)`, -i.e. the application of an `apply` method defined by ´f´. The value `´f´` is applicable to the given arguments if `´f´.apply` is applicable. - - -The application `´f´(´e_1, ..., e_n´)` evaluates ´f´ and then each argument -´e_1, ..., e_n´ from left to right, except for arguments that correspond to -a by-name parameter (see below). Each argument expression is converted to the -type of its corresponding formal parameter. After that, the application is -rewritten to the function's right hand side, with actual arguments substituted -for formal parameters. The result of evaluating the rewritten right-hand side -is finally converted to the function's declared result type, if one is given. - -The case of a formal parameter with a parameterless -method type `=> ´T´` is treated specially. In this case, the -corresponding actual argument expression ´e´ is not evaluated before the -application. Instead, every use of the formal parameter on the -right-hand side of the rewrite rule entails a re-evaluation of ´e´. -In other words, the evaluation order for -`=>`-parameters is _call-by-name_ whereas the evaluation -order for normal parameters is _call-by-value_. -Furthermore, it is required that ´e´'s [packed type](#expression-typing) -conforms to the parameter type ´T´. -The behavior of by-name parameters is preserved if the application is -transformed into a block due to named or default arguments. In this case, -the local value for that parameter has the form `val ´y_i´ = () => ´e´` -and the argument passed to the function is `´y_i´()`. - -The last argument in an application may be marked as a sequence -argument, e.g. `´e´: _*`. Such an argument must correspond -to a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type -`´S´*` and it must be the only argument matching this -parameter (i.e. the number of formal parameters and actual arguments -must be the same). Furthermore, the type of ´e´ must conform to -`scala.Seq[´T´]`, for some type ´T´ which conforms to -´S´. In this case, the argument list is transformed by replacing the -sequence ´e´ with its elements. When the application uses named -arguments, the vararg parameter has to be specified exactly once. - -If only a single argument is supplied, it may be supplied as a block expression -and parentheses can be omitted, in the form `´f´ { block }`. This is valid when -`f` has a single formal parameter or when all other formal parameters have -default values. - -A function application usually allocates a new frame on the program's -run-time stack. However, if a local method or a final method calls -itself as its last action, the call is executed using the stack-frame -of the caller. +If ´f´ has some value type, the application is taken to be equivalent to `´f´.apply(´e_1, ..., e_m´)`, i.e. the application of an `apply` method defined by ´f´. +The value `´f´` is applicable to the given arguments if `´f´.apply` is applicable. + + +The application `´f´(´e_1, ..., e_n´)` evaluates ´f´ and then each argument ´e_1, ..., e_n´ from left to right, except for arguments that correspond to a by-name parameter (see below). +Each argument expression is converted to the type of its corresponding formal parameter. +After that, the application is rewritten to the function's right hand side, with actual arguments substituted for formal parameters. +The result of evaluating the rewritten right-hand side is finally converted to the function's declared result type, if one is given. + +The case of a formal parameter with a parameterless method type `=> ´T´` is treated specially. +In this case, the corresponding actual argument expression ´e´ is not evaluated before the application. +Instead, every use of the formal parameter on the right-hand side of the rewrite rule entails a re-evaluation of ´e´. +In other words, the evaluation order for `=>`-parameters is _call-by-name_ whereas the evaluation order for normal parameters is _call-by-value_. +Furthermore, it is required that ´e´'s [packed type](#expression-typing) conforms to the parameter type ´T´. +The behavior of by-name parameters is preserved if the application is transformed into a block due to named or default arguments. +In this case, the local value for that parameter has the form `val ´y_i´ = () => ´e´` and the argument passed to the function is `´y_i´()`. + +The last argument in an application may be marked as a sequence argument, e.g. `´e´: _*`. +Such an argument must correspond to a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type `´S´*` and it must be the only argument matching this parameter (i.e. the number of formal parameters and actual arguments must be the same). +Furthermore, the type of ´e´ must conform to `scala.Seq[´T´]`, for some type ´T´ which conforms to ´S´. +In this case, the argument list is transformed by replacing the sequence ´e´ with its elements. +When the application uses named arguments, the vararg parameter has to be specified exactly once. + +If only a single argument is supplied, it may be supplied as a block expression and parentheses can be omitted, in the form `´f´ { block }`. +This is valid when `f` has a single formal parameter or when all other formal parameters have default values. + +A function application usually allocates a new frame on the program's run-time stack. +However, if a local method or a final method calls itself as its last action, the call is executed using the stack-frame of the caller. ###### Example -Assume the following method which computes the sum of a -variable number of arguments: +Assume the following method which computes the sum of a variable number of arguments: ```scala def sum(xs: Int*) = xs.foldLeft(0)((x, y) => x + y) @@ -321,7 +260,8 @@ sum(1, 2, 3, 4) sum(List(1, 2, 3, 4): _*) ``` -both yield `10` as result. On the other hand, +both yield `10` as result. +On the other hand, ```scala sum(List(1, 2, 3, 4)) @@ -334,25 +274,15 @@ The keyword is ignored. ### Named and Default Arguments -If an application is to use named arguments ´p = e´ or default -arguments, the following conditions must hold. +If an application is to use named arguments ´p = e´ or default arguments, the following conditions must hold. -- For every named argument ´p_i = e_i´ which appears left of a positional argument - in the argument list ´e_1 ... e_m´, the argument position ´i´ coincides with - the position of parameter ´p_i´ in the parameter list of the applied method. -- The names ´x_i´ of all named arguments are pairwise distinct and no named - argument defines a parameter which is already specified by a - positional argument. -- Every formal parameter ´p_j:T_j´ which is not specified by either a positional - or named argument has a default argument. +- For every named argument ´p_i = e_i´ which appears left of a positional argument in the argument list ´e_1 ... e_m´, the argument position ´i´ coincides with the position of parameter ´p_i´ in the parameter list of the applied method. +- The names ´x_i´ of all named arguments are pairwise distinct and no named argument defines a parameter which is already specified by a positional argument. +- Every formal parameter ´p_j:T_j´ which is not specified by either a positional or named argument has a default argument. -If the application uses named or default -arguments the following transformation is applied to convert it into -an application without named or default arguments. +If the application uses named or default arguments the following transformation is applied to convert it into an application without named or default arguments. -If the method ´f´ -has the form `´p.m´[´\mathit{targs}´]` it is transformed into the -block +If the method ´f´ has the form `´p.m´[´\mathit{targs}´]` it is transformed into the block ```scala { val q = ´p´ @@ -360,9 +290,8 @@ block } ``` -If the method ´f´ is itself an application expression the transformation -is applied recursively on ´f´. The result of transforming ´f´ is a block of -the form +If the method ´f´ is itself an application expression the transformation is applied recursively on ´f´. +The result of transforming ´f´ is a block of the form ```scala { val q = ´p´ @@ -373,20 +302,11 @@ the form } ``` -where every argument in ´(\mathit{args}\_1), ..., (\mathit{args}\_l)´ is a reference to -one of the values ´x_1, ..., x_k´. To integrate the current application -into the block, first a value definition using a fresh name ´y_i´ is created -for every argument in ´e_1, ..., e_m´, which is initialised to ´e_i´ for -positional arguments and to ´e'_i´ for named arguments of the form -`´x_i=e'_i´`. Then, for every parameter which is not specified -by the argument list, a value definition using a fresh name ´z_i´ is created, -which is initialized using the method computing the -[default argument](04-basic-declarations-and-definitions.html#function-declarations-and-definitions) of -this parameter. - -Let ´\mathit{args}´ be a permutation of the generated names ´y_i´ and ´z_i´ such such -that the position of each name matches the position of its corresponding -parameter in the method type `(´p_1:T_1, ..., p_n:T_n´)´U´`. +where every argument in ´(\mathit{args}\_1), ..., (\mathit{args}\_l)´ is a reference to one of the values ´x_1, ..., x_k´. +To integrate the current application into the block, first a value definition using a fresh name ´y_i´ is created for every argument in ´e_1, ..., e_m´, which is initialised to ´e_i´ for positional arguments and to ´e'_i´ for named arguments of the form `´x_i=e'_i´`. +Then, for every parameter which is not specified by the argument list, a value definition using a fresh name ´z_i´ is created, which is initialized using the method computing the [default argument](04-basic-declarations-and-definitions.html#function-declarations-and-definitions) of this parameter. + +Let ´\mathit{args}´ be a permutation of the generated names ´y_i´ and ´z_i´ such such that the position of each name matches the position of its corresponding parameter in the method type `(´p_1:T_1, ..., p_n:T_n´)´U´`. The final result of the transformation is a block of the form ```scala @@ -406,20 +326,15 @@ The final result of the transformation is a block of the form ### Signature Polymorphic Methods -For invocations of signature polymorphic methods of the target platform `´f´(´e_1, ..., e_m´)`, -the invoked method has a different method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´` at each call -site. The parameter types `´T_, ..., T_n´` are the types of the argument expressions -`´e_1, ..., e_m´`. If the declared return type `´R´` of the signature polymorphic method is -any type other than `scala.AnyRef`, then the return type `´U´` is `´R´`. -Otherwise, `´U´` is the expected type at the call site. If the expected type is undefined then -`´U´` is `scala.AnyRef`. The parameter names `´p_1, ..., p_n´` are fresh. +For invocations of signature polymorphic methods of the target platform `´f´(´e_1, ..., e_m´)`, the invoked method has a different method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´` at each call site. +The parameter types `´T_, ..., T_n´` are the types of the argument expressions `´e_1, ..., e_m´`. +If the declared return type `´R´` of the signature polymorphic method is any type other than `scala.AnyRef`, then the return type `´U´` is `´R´`. +Otherwise, `´U´` is the expected type at the call site. If the expected type is undefined then `´U´` is `scala.AnyRef`. +The parameter names `´p_1, ..., p_n´` are fresh. ###### Note -On the Java platform version 11 and later, signature polymorphic methods are native, -members of `java.lang.invoke.MethodHandle` or `java.lang.invoke.VarHandle`, and have a single -repeated parameter of type `java.lang.Object*`. - +On the Java platform version 11 and later, signature polymorphic methods are native, members of `java.lang.invoke.MethodHandle` or `java.lang.invoke.VarHandle`, and have a single repeated parameter of type `java.lang.Object*`. ## Method Values @@ -428,13 +343,9 @@ SimpleExpr ::= SimpleExpr1 ‘_’ ``` The expression `´e´ _` is well-formed if ´e´ is of method -type or if ´e´ is a call-by-name parameter. If ´e´ is a method with -parameters, `´e´ _` represents ´e´ converted to a function -type by [eta expansion](#eta-expansion-section). If ´e´ is a -parameterless method or call-by-name parameter of type -`=> ´T´`, `´e´ _` represents the function of type -`() => ´T´`, which evaluates ´e´ when it is applied to the empty -parameter list `()`. +type or if ´e´ is a call-by-name parameter. +If ´e´ is a method with parameters, `´e´ _` represents ´e´ converted to a function type by [eta expansion](#eta-expansion-section). +If ´e´ is a parameterless method or call-by-name parameter of type `=> ´T´`, `´e´ _` represents the function of type `() => ´T´`, which evaluates ´e´ when it is applied to the empty parameter list `()`. ###### Example The method values in the left column are each equivalent to the [eta-expanded expressions](#eta-expansion-section) on the right. @@ -447,8 +358,7 @@ The method values in the left column are each equivalent to the [eta-expanded ex |`(1 to 9).fold(z)_` | `{ val eta1 = 1 to 9; val eta2 = z; op => eta1.fold(eta2)(op) }` | |`Some(1).fold(??? : Int)_` | `{ val eta1 = Some(1); val eta2 = () => ???; op => eta1.fold(eta2())(op) }` | -Note that a space is necessary between a method name and the trailing underscore -because otherwise the underscore would be considered part of the name. +Note that a space is necessary between a method name and the trailing underscore because otherwise the underscore would be considered part of the name. ## Type Applications @@ -456,25 +366,15 @@ because otherwise the underscore would be considered part of the name. SimpleExpr ::= SimpleExpr TypeArgs ``` -A _type application_ `´e´[´T_1, ..., T_n´]` instantiates -a polymorphic value ´e´ of type -`[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´` -with argument types -`´T_1, ..., T_n´`. Every argument type ´T_i´ must obey -the corresponding bounds ´L_i´ and ´U_i´. That is, for each ´i = 1 -, ..., n´, we must have ´\sigma L_i <: T_i <: \sigma -U_i´, where ´\sigma´ is the substitution ´[a_1 := T_1, ..., a_n -:= T_n]´. The type of the application is ´\sigma S´. +A _type application_ `´e´[´T_1, ..., T_n´]` instantiates a polymorphic value ´e´ of type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´` with argument types `´T_1, ..., T_n´`. +Every argument type ´T_i´ must obey the corresponding bounds ´L_i´ and ´U_i´. +That is, for each ´i = 1, ..., n´, we must have ´\sigma L_i <: T_i <: \sigma U_i´, where ´\sigma´ is the substitution ´[a_1 := T_1, ..., a_n +:= T_n]´. +The type of the application is ´\sigma S´. -If the function part ´e´ is of some value type, the type application -is taken to be equivalent to -`´e´.apply[´T_1 , ...,´ T´_n´]`, i.e. the application of an `apply` method defined by -´e´. +If the function part ´e´ is of some value type, the type application is taken to be equivalent to `´e´.apply[´T_1 , ...,´ T´_n´]`, i.e. the application of an `apply` method defined by ´e´. -Type applications can be omitted if -[local type inference](#local-type-inference) can infer best type parameters -for a polymorphic method from the types of the actual method arguments -and the expected result type. +Type applications can be omitted if [local type inference](#local-type-inference) can infer best type parameters for a polymorphic method from the types of the actual method arguments and the expected result type. ## Tuples @@ -482,11 +382,8 @@ and the expected result type. SimpleExpr ::= ‘(’ [Exprs] ‘)’ ``` -A _tuple expression_ `(´e_1´, ..., ´e_n´)` is an alias -for the class instance creation -`scala.Tuple´n´(´e_1´, ..., ´e_n´)`, where ´n \geq 2´. -The empty tuple -`()` is the unique value of type `scala.Unit`. +A _tuple expression_ `(´e_1´, ..., ´e_n´)` is an alias for the class instance creation `scala.Tuple´n´(´e_1´, ..., ´e_n´)`, where ´n \geq 2´. +The empty tuple `()` is the unique value of type `scala.Unit`. ## Instance Creation Expressions @@ -494,44 +391,33 @@ The empty tuple SimpleExpr ::= ‘new’ (ClassTemplate | TemplateBody) ``` -A _simple instance creation expression_ is of the form -`new ´c´` -where ´c´ is a [constructor invocation](05-classes-and-objects.html#constructor-invocations). Let ´T´ be -the type of ´c´. Then ´T´ must -denote a (a type instance of) a non-abstract subclass of -`scala.AnyRef`. Furthermore, the _concrete self type_ of the -expression must conform to the [self type](05-classes-and-objects.html#templates) of the class denoted by -´T´. The concrete self type is normally -´T´, except if the expression `new ´c´` appears as the -right hand side of a value definition +A _simple instance creation expression_ is of the form `new ´c´` where ´c´ is a [constructor invocation](05-classes-and-objects.html#constructor-invocations). +Let ´T´ be the type of ´c´. +Then ´T´ must denote a (a type instance of) a non-abstract subclass of `scala.AnyRef`. +Furthermore, the _concrete self type_ of the expression must conform to the [self type](05-classes-and-objects.html#templates) of the class denoted by ´T´. +The concrete self type is normally ´T´, except if the expression `new ´c´` appears as the right hand side of a value definition ```scala val ´x´: ´S´ = new ´c´ ``` (where the type annotation `: ´S´` may be missing). -In the latter case, the concrete self type of the expression is the -compound type `´T´ with ´x´.type`. +In the latter case, the concrete self type of the expression is the compound type `´T´ with ´x´.type`. -The expression is evaluated by creating a fresh -object of type ´T´ which is initialized by evaluating ´c´. The -type of the expression is ´T´. +The expression is evaluated by creating a fresh object of type ´T´ which is initialized by evaluating ´c´. +The type of the expression is ´T´. -A _general instance creation expression_ is of the form -`new ´t´` for some [class template](05-classes-and-objects.html#templates) ´t´. +A _general instance creation expression_ is of the form `new ´t´` for some [class template](05-classes-and-objects.html#templates) ´t´. Such an expression is equivalent to the block ```scala { class ´a´ extends ´t´; new ´a´ } ``` -where ´a´ is a fresh name of an _anonymous class_ which is -inaccessible to user programs. +where ´a´ is a fresh name of an _anonymous class_ which is inaccessible to user programs. -There is also a shorthand form for creating values of structural -types: If `{´D´}` is a class body, then -`new {´D´}` is equivalent to the general instance creation expression -`new AnyRef{´D´}`. +There is also a shorthand form for creating values of structural types: +If `{´D´}` is a class body, then `new {´D´}` is equivalent to the general instance creation expression `new AnyRef{´D´}`. ###### Example Consider the following structural instance creation expression: @@ -562,45 +448,27 @@ BlockExpr ::= ‘{’ CaseClauses ‘}’ Block ::= BlockStat {semi BlockStat} [ResultExpr] ``` -A _block expression_ `{´s_1´; ...; ´s_n´; ´e\,´}` is -constructed from a sequence of block statements ´s_1, ..., s_n´ -and a final expression ´e´. The statement sequence may not contain -two definitions or declarations that bind the same name in the same -namespace. The final expression can be omitted, in which -case the unit value `()` is assumed. +A _block expression_ `{´s_1´; ...; ´s_n´; ´e\,´}` is constructed from a sequence of block statements ´s_1, ..., s_n´ and a final expression ´e´. +The statement sequence may not contain two definitions or declarations that bind the same name in the same namespace. +The final expression can be omitted, in which case the unit value `()` is assumed. -The expected type of the final expression ´e´ is the expected -type of the block. The expected type of all preceding statements is -undefined. +The expected type of the final expression ´e´ is the expected type of the block. +The expected type of all preceding statements is undefined. -The type of a block `´s_1´; ...; ´s_n´; ´e´` is -`´T´ forSome {´\,Q\,´}`, where ´T´ is the type of ´e´ and ´Q´ -contains [existential clauses](03-types.html#existential-types) -for every value or type name which is free in ´T´ -and which is defined locally in one of the statements ´s_1, ..., s_n´. +The type of a block `´s_1´; ...; ´s_n´; ´e´` is `´T´ forSome {´\,Q\,´}`, where ´T´ is the type of ´e´ and ´Q´ contains [existential clauses](03-types.html#existential-types) for every value or type name which is free in ´T´ and which is defined locally in one of the statements ´s_1, ..., s_n´. We say the existential clause _binds_ the occurrence of the value or type name. Specifically, -- A locally defined type definition `type´\;t = T´` - is bound by the existential clause `type´\;t >: T <: T´`. - It is an error if ´t´ carries type parameters. -- A locally defined value definition `val´\;x: T = e´` is - bound by the existential clause `val´\;x: T´`. -- A locally defined class definition `class´\;c´ extends´\;t´` - is bound by the existential clause `type´\;c <: T´` where - ´T´ is the least class type or refinement type which is a proper - supertype of the type ´c´. It is an error if ´c´ carries type parameters. -- A locally defined object definition `object´\;x\;´extends´\;t´` - is bound by the existential clause `val´\;x: T´` where - ´T´ is the least class type or refinement type which is a proper supertype of the type - `´x´.type`. - -Evaluation of the block entails evaluation of its -statement sequence, followed by an evaluation of the final expression -´e´, which defines the result of the block. - -A block expression `{´c_1´; ...; ´c_n´}` where ´s_1, ..., s_n´ are -case clauses forms a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions). +- A locally defined type definition `type´\;t = T´` is bound by the existential clause `type´\;t >: T <: T´`. +It is an error if ´t´ carries type parameters. +- A locally defined value definition `val´\;x: T = e´` is bound by the existential clause `val´\;x: T´`. +- A locally defined class definition `class´\;c´ extends´\;t´` is bound by the existential clause `type´\;c <: T´` where ´T´ is the least class type or refinement type which is a proper supertype of the type ´c´. +It is an error if ´c´ carries type parameters. +- A locally defined object definition `object´\;x\;´extends´\;t´` is bound by the existential clause `val´\;x: T´` where ´T´ is the least class type or refinement type which is a proper supertype of the type `´x´.type`. + +Evaluation of the block entails evaluation of its statement sequence, followed by an evaluation of the final expression ´e´, which defines the result of the block. + +A block expression `{´c_1´; ...; ´c_n´}` where ´s_1, ..., s_n´ are case clauses forms a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions). ###### Example Assuming a class `Ref[T](x: T)`, the block @@ -616,9 +484,7 @@ The block { class C extends B {´\ldots´} ; new C } ``` -simply has type `B`, because with the rules [here](03-types.html#simplification-rules) -the existentially quantified type -`_1 forSome { type _1 <: B }` can be simplified to `B`. +simply has type `B`, because with the rules [here](03-types.html#simplification-rules) the existentially quantified type `_1 forSome { type _1 <: B }` can be simplified to `B`. ## Prefix, Infix, and Postfix Operations @@ -633,35 +499,26 @@ Expressions can be constructed from operands and operators. ### Prefix Operations -A prefix operation ´\mathit{op};e´ consists of a prefix operator ´\mathit{op}´, which -must be one of the identifiers ‘`+`’, ‘`-`’, ‘`!`’ or ‘`~`’, -which must not be enclosed in backquotes. -The expression ´\mathit{op};e´ is -equivalent to the postfix method application -`e.unary_´\mathit{op}´`. +A prefix operation ´\mathit{op};e´ consists of a prefix operator ´\mathit{op}´, which must be one of the identifiers ‘`+`’, ‘`-`’, ‘`!`’ or ‘`~`’, which must not be enclosed in backquotes. +The expression ´\mathit{op};e´ is equivalent to the postfix method application `e.unary_´\mathit{op}´`. -Prefix operators are different from normal method applications in -that their operand expression need not be atomic. For instance, the -input sequence `-sin(x)` is read as `-(sin(x))`, whereas the -method application `negate sin(x)` would be parsed as the -application of the infix operator `sin` to the operands -`negate` and `(x)`. +Prefix operators are different from normal method applications in that their operand expression need not be atomic. +For instance, the input sequence `-sin(x)` is read as `-(sin(x))`, whereas the method application `negate sin(x)` would be parsed as the application of the infix operator `sin` to the operands `negate` and `(x)`. ### Postfix Operations -A postfix operator can be an arbitrary identifier. The postfix -operation ´e;\mathit{op}´ is interpreted as ´e.\mathit{op}´. +A postfix operator can be an arbitrary identifier. +The postfix operation ´e;\mathit{op}´ is interpreted as ´e.\mathit{op}´. ### Infix Operations -An infix operator can be an arbitrary identifier. Infix operators have -precedence and associativity defined as follows: +An infix operator can be an arbitrary identifier. +Infix operators have precedence and associativity defined as follows: -The _precedence_ of an infix operator is determined by the operator's first -character. Characters are listed below in increasing order of -precedence, with characters on the same line having the same precedence. +The _precedence_ of an infix operator is determined by the operator's first character. +Characters are listed below in increasing order of precedence, with characters on the same line having the same precedence. ```scala (all letters, as defined in [chapter 1](01-lexical-syntax.html), including `_` and `$`) @@ -676,65 +533,42 @@ precedence, with characters on the same line having the same precedence. (other operator characters, as defined in [chapter 1](01-lexical-syntax.html), including Unicode categories `Sm` and `So`) ``` -That is, operators starting with a letter have lowest precedence, -followed by operators starting with ‘`|`’, etc. +That is, operators starting with a letter have lowest precedence, followed by operators starting with ‘`|`’, etc. -There's one exception to this rule, which concerns -[_assignment operators_](#assignment-operators). -The precedence of an assignment operator is the same as the one -of simple assignment `(=)`. That is, it is lower than the -precedence of any other operator. +There's one exception to this rule, which concerns [_assignment operators_](#assignment-operators). +The precedence of an assignment operator is the same as the one of simple assignment `(=)`. +That is, it is lower than the precedence of any other operator. The _associativity_ of an operator is determined by the operator's -last character. Operators ending in a colon ‘`:`’ are -right-associative. All other operators are left-associative. - -Precedence and associativity of operators determine the grouping of -parts of an expression as follows. - -- If there are several infix operations in an - expression, then operators with higher precedence bind more closely - than operators with lower precedence. -- If there are consecutive infix - operations ´e_0; \mathit{op}\_1; e_1; \mathit{op}\_2 ... \mathit{op}\_n; e_n´ - with operators ´\mathit{op}\_1, ..., \mathit{op}\_n´ of the same precedence, - then all these operators must - have the same associativity. If all operators are left-associative, - the sequence is interpreted as - ´(...(e_0;\mathit{op}\_1;e_1);\mathit{op}\_2...);\mathit{op}\_n;e_n´. - Otherwise, if all operators are right-associative, the - sequence is interpreted as - ´e_0;\mathit{op}\_1;(e_1;\mathit{op}\_2;(... \mathit{op}\_n;e_n)...)´. -- Postfix operators always have lower precedence than infix - operators. E.g. ´e_1;\mathit{op}\_1;e_2;\mathit{op}\_2´ is always equivalent to - ´(e_1;\mathit{op}\_1;e_2);\mathit{op}\_2´. - -The right-hand operand of a left-associative operator may consist of -several arguments enclosed in parentheses, e.g. ´e;\mathit{op};(e_1,...,e_n)´. +last character. +Operators ending in a colon ‘`:`’ are right-associative. +All other operators are left-associative. + +Precedence and associativity of operators determine the grouping of parts of an expression as follows. + +- If there are several infix operations in an expression, then operators with higher precedence bind more closely than operators with lower precedence. +- If there are consecutive infix operations ´e_0; \mathit{op}\_1; e_1; \mathit{op}\_2 ... \mathit{op}\_n; e_n´ with operators ´\mathit{op}\_1, ..., \mathit{op}\_n´ of the same precedence, then all these operators must have the same associativity. +If all operators are left-associative, the sequence is interpreted as ´(...(e_0;\mathit{op}\_1;e_1);\mathit{op}\_2...);\mathit{op}\_n;e_n´. +Otherwise, if all operators are right-associative, the sequence is interpreted as ´e_0;\mathit{op}\_1;(e_1;\mathit{op}\_2;(... \mathit{op}\_n;e_n)...)´. +- Postfix operators always have lower precedence than infix operators. E.g. ´e_1;\mathit{op}\_1;e_2;\mathit{op}\_2´ is always equivalent to ´(e_1;\mathit{op}\_1;e_2);\mathit{op}\_2´. + +The right-hand operand of a left-associative operator may consist of several arguments enclosed in parentheses, e.g. ´e;\mathit{op};(e_1,...,e_n)´. This expression is then interpreted as ´e.\mathit{op}(e_1,...,e_n)´. -A left-associative binary -operation ´e_1;\mathit{op};e_2´ is interpreted as ´e_1.\mathit{op}(e_2)´. If ´\mathit{op}´ is -right-associative and its parameter is passed by name, the same operation is interpreted as -´e_2.\mathit{op}(e_1)´. If ´\mathit{op}´ is right-associative and its parameter is passed by value, -it is interpreted as `{ val ´x´=´e_1´; ´e_2´.´\mathit{op}´(´x\,´) }`, where ´x´ is a fresh name. +A left-associative binary operation ´e_1;\mathit{op};e_2´ is interpreted as ´e_1.\mathit{op}(e_2)´. If ´\mathit{op}´ is right-associative and its parameter is passed by name, the same operation is interpreted as ´e_2.\mathit{op}(e_1)´. +If ´\mathit{op}´ is right-associative and its parameter is passed by value, it is interpreted as `{ val ´x´=´e_1´; ´e_2´.´\mathit{op}´(´x\,´) }`, where ´x´ is a fresh name. ### Assignment Operators -An _assignment operator_ is an operator symbol (syntax category -`op` in [Identifiers](01-lexical-syntax.html#identifiers)) that ends in an equals character -“`=`”, with the following exceptions: +An _assignment operator_ is an operator symbol (syntax category `op` in [Identifiers](01-lexical-syntax.html#identifiers)) that ends in an equals character “`=`”, with the following exceptions: 1. the operator also starts with an equals character, or 1. the operator is one of `(<=)`, `(>=)`, `(!=)`. -Assignment operators are treated specially in that they -can be expanded to assignments if no other interpretation is valid. +Assignment operators are treated specially in that they can be expanded to assignments if no other interpretation is valid. -Let's consider an assignment operator such as `+=` in an infix -operation `´l´ += ´r´`, where ´l´, ´r´ are expressions. -This operation can be re-interpreted as an operation which corresponds -to the assignment +Let's consider an assignment operator such as `+=` in an infix operation `´l´ += ´r´`, where ´l´, ´r´ are expressions. +This operation can be re-interpreted as an operation which corresponds to the assignment ```scala ´l´ = ´l´ + ´r´ @@ -744,14 +578,9 @@ except that the operation's left-hand-side ´l´ is evaluated only once. The re-interpretation occurs if the following two conditions are fulfilled. -1. The left-hand-side ´l´ does not have a member named - `+=`, and also cannot be converted by an - [implicit conversion](#implicit-conversions) - to a value with a member named `+=`. +1. The left-hand-side ´l´ does not have a member named `+=`, and also cannot be converted by an [implicit conversion](#implicit-conversions) to a value with a member named `+=`. 1. The assignment `´l´ = ´l´ + ´r´` is type-correct. - In particular this implies that ´l´ refers to a variable or object - that can be assigned to, and that is convertible to a value with a member - named `+`. +In particular this implies that ´l´ refers to a variable or object that can be assigned to, and that is convertible to a value with a member named `+`. ## Typed Expressions @@ -759,9 +588,9 @@ The re-interpretation occurs if the following two conditions are fulfilled. Expr1 ::= PostfixExpr ‘:’ CompoundType ``` -The _typed expression_ ´e: T´ has type ´T´. The type of -expression ´e´ is expected to conform to ´T´. The result of -the expression is the value of ´e´ converted to type ´T´. +The _typed expression_ ´e: T´ has type ´T´. +The type of expression ´e´ is expected to conform to ´T´. +The result of the expression is the value of ´e´ converted to type ´T´. ###### Example Here are examples of well-typed and ill-typed expressions. @@ -778,9 +607,7 @@ Here are examples of well-typed and ill-typed expressions. Expr1 ::= PostfixExpr ‘:’ Annotation {Annotation} ``` -An _annotated expression_ `´e´: @´a_1´ ... @´a_n´` -attaches [annotations](11-annotations.html#user-defined-annotations) ´a_1, ..., a_n´ to the -expression ´e´. +An _annotated expression_ `´e´: @´a_1´ ... @´a_n´` attaches [annotations](11-annotations.html#user-defined-annotations) ´a_1, ..., a_n´ to the expression ´e´. ## Assignments @@ -790,25 +617,14 @@ Expr1 ::= [SimpleExpr ‘.’] id ‘=’ Expr | SimpleExpr1 ArgumentExprs ‘=’ Expr ``` -The interpretation of an assignment to a simple variable `´x´ = ´e´` -depends on the definition of ´x´. If ´x´ denotes a mutable -variable, then the assignment changes the current value of ´x´ to be -the result of evaluating the expression ´e´. The type of ´e´ is -expected to conform to the type of ´x´. If ´x´ is a parameterless -method defined in some template, and the same template contains a -setter method `´x´_=` as member, then the assignment -`´x´ = ´e´` is interpreted as the invocation -`´x´_=(´e\,´)` of that setter method. Analogously, an -assignment `´f.x´ = ´e´` to a parameterless method ´x´ -is interpreted as the invocation `´f.x´_=(´e\,´)`. -If ´x´ is an application of a unary operator, then the expression -is interpreted as though it were written as the explicit application -`´x´.unary_´\mathit{op}´`, namely, as `´x´.unary_´\mathit{op}´_=(´e\,´)`. - -An assignment `´f´(´\mathit{args}\,´) = ´e´` with a method application to the -left of the ‘`=`’ operator is interpreted as -`´f.´update(´\mathit{args}´, ´e\,´)`, i.e. -the invocation of an `update` method defined by ´f´. +The interpretation of an assignment to a simple variable `´x´ = ´e´` depends on the definition of ´x´. +If ´x´ denotes a mutable variable, then the assignment changes the current value of ´x´ to be the result of evaluating the expression ´e´. +The type of ´e´ is expected to conform to the type of ´x´. +If ´x´ is a parameterless method defined in some template, and the same template contains a setter method `´x´_=` as member, then the assignment `´x´ = ´e´` is interpreted as the invocation `´x´_=(´e\,´)` of that setter method. +Analogously, an assignment `´f.x´ = ´e´` to a parameterless method ´x´ is interpreted as the invocation `´f.x´_=(´e\,´)`. +If ´x´ is an application of a unary operator, then the expression is interpreted as though it were written as the explicit application `´x´.unary_´\mathit{op}´`, namely, as `´x´.unary_´\mathit{op}´_=(´e\,´)`. + +An assignment `´f´(´\mathit{args}\,´) = ´e´` with a method application to the left of the ‘`=`’ operator is interpreted as `´f.´update(´\mathit{args}´, ´e\,´)`, i.e. the invocation of an `update` method defined by ´f´. ###### Example Here are some assignment expressions and their equivalent expansions. @@ -846,8 +662,7 @@ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { } ``` -Desugaring the array accesses and assignments yields the following -expanded version: +Desugaring the array accesses and assignments yields the following expanded version: ```scala def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { @@ -877,25 +692,17 @@ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ Expr] ``` -The _conditional expression_ `if (´e_1´) ´e_2´ else ´e_3´` chooses -one of the values of ´e_2´ and ´e_3´, depending on the -value of ´e_1´. The condition ´e_1´ is expected to -conform to type `Boolean`. The then-part ´e_2´ and the -else-part ´e_3´ are both expected to conform to the expected -type of the conditional expression. The type of the conditional -expression is the [weak least upper bound](03-types.html#weak-conformance) -of the types of ´e_2´ and -´e_3´. A semicolon preceding the `else` symbol of a -conditional expression is ignored. +The _conditional expression_ `if (´e_1´) ´e_2´ else ´e_3´` chooses one of the values of ´e_2´ and ´e_3´, depending on the value of ´e_1´. +The condition ´e_1´ is expected to conform to type `Boolean`. +The then-part ´e_2´ and the else-part ´e_3´ are both expected to conform to the expected type of the conditional expression. +The type of the conditional expression is the [weak least upper bound](03-types.html#weak-conformance) of the types of ´e_2´ and ´e_3´. +A semicolon preceding the `else` symbol of a conditional expression is ignored. -The conditional expression is evaluated by evaluating first -´e_1´. If this evaluates to `true`, the result of -evaluating ´e_2´ is returned, otherwise the result of -evaluating ´e_3´ is returned. +The conditional expression is evaluated by evaluating first ´e_1´. +If this evaluates to `true`, the result of evaluating ´e_2´ is returned, otherwise the result of evaluating ´e_3´ is returned. -A short form of the conditional expression eliminates the -else-part. The conditional expression `if (´e_1´) ´e_2´` is -evaluated as if it was `if (´e_1´) ´e_2´ else ()`. +A short form of the conditional expression eliminates the else-part. +The conditional expression `if (´e_1´) ´e_2´` is evaluated as if it was `if (´e_1´) ´e_2´ else ()`. ## While Loop Expressions @@ -903,9 +710,7 @@ evaluated as if it was `if (´e_1´) ´e_2´ else ()`. Expr1 ::= ‘while’ ‘(’ Expr ‘)’ {nl} Expr ``` -The _while loop expression_ `while (´e_1´) ´e_2´` is typed and -evaluated as if it was an application of `whileLoop (´e_1´) (´e_2´)` where -the hypothetical method `whileLoop` is defined as follows. +The _while loop expression_ `while (´e_1´) ´e_2´` is typed and evaluated as if it was an application of `whileLoop (´e_1´) (´e_2´)` where the hypothetical method `whileLoop` is defined as follows. ```scala def whileLoop(cond: => Boolean)(body: => Unit): Unit = @@ -918,8 +723,7 @@ def whileLoop(cond: => Boolean)(body: => Unit): Unit = Expr1 ::= ‘do’ Expr [semi] ‘while’ ‘(’ Expr ‘)’ ``` -The _do loop expression_ `do ´e_1´ while (´e_2´)` is typed and -evaluated as if it was the expression `(´e_1´ ; while (´e_2´) ´e_1´)`. +The _do loop expression_ `do ´e_1´ while (´e_2´)` is typed and evaluated as if it was the expression `(´e_1´ ; while (´e_2´) ´e_1´)`. A semicolon preceding the `while` symbol of a do loop expression is ignored. ## For Comprehensions and For Loops @@ -932,57 +736,36 @@ Generator ::= [‘case’] Pattern1 ‘<-’ Expr {[semi] Guard | semi Pat Guard ::= ‘if’ PostfixExpr ``` -A _for loop_ `for (´\mathit{enums}\,´) ´e´` executes expression ´e´ -for each binding generated by the enumerators ´\mathit{enums}´. -A _for comprehension_ `for (´\mathit{enums}\,´) yield ´e´` evaluates -expression ´e´ for each binding generated by the enumerators ´\mathit{enums}´ -and collects the results. An enumerator sequence always starts with a -generator; this can be followed by further generators, value -definitions, or guards. - -A _generator_ `´p´ <- ´e´` produces bindings from an expression ´e´ which is -matched in some way against pattern ´p´. Optionally, `case` can appear in front -of a generator pattern, this has no meaning in Scala 2 but will be [required in -Scala 3 if `p` is not -irrefutable](https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html). - -A _value definition_ `´p´ = ´e´` -binds the value name ´p´ (or several names in a pattern ´p´) to -the result of evaluating the expression ´e´. A _guard_ -`if ´e´` contains a boolean expression which restricts -enumerated bindings. The precise meaning of generators and guards is -defined by translation to invocations of four methods: `map`, -`withFilter`, `flatMap`, and `foreach`. These methods can -be implemented in different ways for different carrier types. - -The translation scheme is as follows. In a first step, every -generator `´p´ <- ´e´`, where ´p´ is not [irrefutable](08-pattern-matching.html#patterns) -for the type of ´e´ is replaced by +A _for loop_ `for (´\mathit{enums}\,´) ´e´` executes expression ´e´ for each binding generated by the enumerators ´\mathit{enums}´. +A _for comprehension_ `for (´\mathit{enums}\,´) yield ´e´` evaluates expression ´e´ for each binding generated by the enumerators ´\mathit{enums}´ and collects the results. +An enumerator sequence always starts with a generator; this can be followed by further generators, value definitions, or guards. + +A _generator_ `´p´ <- ´e´` produces bindings from an expression ´e´ which is matched in some way against pattern ´p´. +Optionally, `case` can appear in front of a generator pattern, this has no meaning in Scala 2 but will be [required in Scala 3 if `p` is not irrefutable](https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html). + +A _value definition_ `´p´ = ´e´` binds the value name ´p´ (or several names in a pattern ´p´) to the result of evaluating the expression ´e´. +A _guard_ `if ´e´` contains a boolean expression which restricts enumerated bindings. +The precise meaning of generators and guards is defined by translation to invocations of four methods: `map`, `withFilter`, `flatMap`, and `foreach`. +These methods can be implemented in different ways for different carrier types. + +The translation scheme is as follows. +In a first step, every generator `´p´ <- ´e´`, where ´p´ is not [irrefutable](08-pattern-matching.html#patterns) for the type of ´e´ is replaced by ```scala ´p´ <- ´e´.withFilter { case ´p´ => true; case _ => false } ``` -Then, the following rules are applied repeatedly until all -comprehensions have been eliminated. +Then, the following rules are applied repeatedly until all comprehensions have been eliminated. - - A for comprehension - `for (´p´ <- ´e\,´) yield ´e'´` - is translated to - `´e´.map { case ´p´ => ´e'´ }`. - - A for loop - `for (´p´ <- ´e\,´) ´e'´` - is translated to - `´e´.foreach { case ´p´ => ´e'´ }`. + - A for comprehension `for (´p´ <- ´e\,´) yield ´e'´` is translated to `´e´.map { case ´p´ => ´e'´ }`. + - A for loop `for (´p´ <- ´e\,´) ´e'´` is translated to `´e´.foreach { case ´p´ => ´e'´ }`. - A for comprehension ```scala for (´p´ <- ´e´; ´p'´ <- ´e'; ...´) yield ´e''´ ``` - where `...` is a (possibly empty) - sequence of generators, definitions, or guards, - is translated to + where `...` is a (possibly empty) sequence of generators, definitions, or guards, is translated to ```scala ´e´.flatMap { case ´p´ => for (´p'´ <- ´e'; ...´) yield ´e''´ } @@ -994,30 +777,22 @@ comprehensions have been eliminated. for (´p´ <- ´e´; ´p'´ <- ´e'; ...´) ´e''´ ``` - where `...` is a (possibly empty) - sequence of generators, definitions, or guards, - is translated to + where `...` is a (possibly empty) sequence of generators, definitions, or guards, is translated to ```scala ´e´.foreach { case ´p´ => for (´p'´ <- ´e'; ...´) ´e''´ } ``` - - A generator `´p´ <- ´e´` followed by a guard - `if ´g´` is translated to a single generator - `´p´ <- ´e´.withFilter((´x_1, ..., x_n´) => ´g\,´)` where - ´x_1, ..., x_n´ are the free variables of ´p´. + - A generator `´p´ <- ´e´` followed by a guard `if ´g´` is translated to a single generator `´p´ <- ´e´.withFilter((´x_1, ..., x_n´) => ´g\,´)` where ´x_1, ..., x_n´ are the free variables of ´p´. - - A generator `´p´ <- ´e´` followed by a value definition - `´p'´ = ´e'´` is translated to the following generator of pairs of values, where - ´x´ and ´x'´ are fresh names: + - A generator `´p´ <- ´e´` followed by a value definition `´p'´ = ´e'´` is translated to the following generator of pairs of values, where ´x´ and ´x'´ are fresh names: ```scala (´p´, ´p'´) <- for (´x @ p´ <- ´e´) yield { val ´x' @ p'´ = ´e'´; (´x´, ´x'´) } ``` ###### Example -The following code produces all pairs of numbers between ´1´ and ´n-1´ -whose sums are prime. +The following code produces all pairs of numbers between ´1´ and ´n-1´ whose sums are prime. ```scala for { i <- 1 until n @@ -1037,8 +812,7 @@ The for comprehension is translated to: ``` ###### Example -For comprehensions can be used to express vector -and matrix algorithms concisely. +For comprehensions can be used to express vector and matrix algorithms concisely. For instance, here is a method to compute the transpose of a given matrix: @@ -1072,9 +846,7 @@ def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]]) = { } ``` -The code above makes use of the fact that `map`, `flatMap`, -`withFilter`, and `foreach` are defined for instances of class -`scala.Array`. +The code above makes use of the fact that `map`, `flatMap`, `withFilter`, and `foreach` are defined for instances of class `scala.Array`. ## Return Expressions @@ -1082,32 +854,22 @@ The code above makes use of the fact that `map`, `flatMap`, Expr1 ::= ‘return’ [Expr] ``` -A _return expression_ `return ´e´` must occur inside the body of some -enclosing user defined method. The innermost enclosing method in a -source program, ´m´, must have an explicitly declared result type, and -the type of ´e´ must conform to it. +A _return expression_ `return ´e´` must occur inside the body of some enclosing user defined method. +The innermost enclosing method in a source program, ´m´, must have an explicitly declared result type, and the type of ´e´ must conform to it. -The return expression evaluates the expression ´e´ and returns its -value as the result of ´m´. The evaluation of any statements or -expressions following the return expression is omitted. The type of -a return expression is `scala.Nothing`. +The return expression evaluates the expression ´e´ and returns its value as the result of ´m´. +The evaluation of any statements or expressions following the return expression is omitted. +The type of a return expression is `scala.Nothing`. -The expression ´e´ may be omitted. The return expression -`return` is type-checked and evaluated as if it were `return ()`. +The expression ´e´ may be omitted. +The return expression `return` is type-checked and evaluated as if it were `return ()`. -Returning from the method from within a nested function may be -implemented by throwing and catching a -`scala.runtime.NonLocalReturnControl`. Any exception catches -between the point of return and the enclosing methods might see -and catch that exception. A key comparison makes sure that this -exception is only caught by the method instance which is terminated -by the return. +Returning from the method from within a nested function may be implemented by throwing and catching a `scala.runtime.NonLocalReturnControl`. +Any exception catches between the point of return and the enclosing methods might see and catch that exception. +A key comparison makes sure that this exception is only caught by the method instance which is terminated by the return. -If the return expression is itself part of an anonymous function, it -is possible that the enclosing method ´m´ has already returned -before the return expression is executed. In that case, the thrown -`scala.runtime.NonLocalReturnControl` will not be caught, and will -propagate up the call stack. +If the return expression is itself part of an anonymous function, it is possible that the enclosing method ´m´ has already returned before the return expression is executed. +In that case, the thrown `scala.runtime.NonLocalReturnControl` will not be caught, and will propagate up the call stack. ## Throw Expressions @@ -1115,16 +877,12 @@ propagate up the call stack. Expr1 ::= ‘throw’ Expr ``` -A _throw expression_ `throw ´e´` evaluates the expression -´e´. The type of this expression must conform to -`Throwable`. If ´e´ evaluates to an exception -reference, evaluation is aborted with the thrown exception. If ´e´ -evaluates to `null`, evaluation is instead aborted with a -`NullPointerException`. If there is an active -[`try` expression](#try-expressions) which handles the thrown -exception, evaluation resumes with the handler; otherwise the thread -executing the `throw` is aborted. The type of a throw expression -is `scala.Nothing`. +A _throw expression_ `throw ´e´` evaluates the expression ´e´. +The type of this expression must conform to `Throwable`. +If ´e´ evaluates to an exception reference, evaluation is aborted with the thrown exception. +If ´e´ evaluates to `null`, evaluation is instead aborted with a `NullPointerException`. +If there is an active [`try` expression](#try-expressions) which handles the thrown exception, evaluation resumes with the handler; otherwise the thread executing the `throw` is aborted. +The type of a throw expression is `scala.Nothing`. ## Try Expressions @@ -1132,51 +890,36 @@ is `scala.Nothing`. Expr1 ::= ‘try’ Expr [‘catch’ Expr] [‘finally’ Expr] ``` -A _try expression_ is of the form `try { ´b´ } catch ´h´` -where the handler ´h´ is usually a -[pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions) +A _try expression_ is of the form `try { ´b´ } catch ´h´` where the handler ´h´ is usually a [pattern matching anonymous function](08-pattern-matching.html#pattern-matching-anonymous-functions) ```scala { case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` -This expression is evaluated by evaluating the block -´b´. If evaluation of ´b´ does not cause an exception to be -thrown, the result of ´b´ is returned. Otherwise the -handler ´h´ is applied to the thrown exception. -If the handler contains a case matching the thrown exception, -the first such case is invoked. If the handler contains -no case matching the thrown exception, the exception is -re-thrown. More generally, if the handler is a `PartialFunction`, -it is applied only if it is defined at the given exception. - -Let ´\mathit{pt}´ be the expected type of the try expression. The block -´b´ is expected to conform to ´\mathit{pt}´. The handler ´h´ -is expected conform to type `scala.Function[scala.Throwable, ´\mathit{pt}\,´]`. -The type of the try expression is the [weak least upper bound](03-types.html#weak-conformance) -of the type of ´b´ and the result type of ´h´. - -A try expression `try { ´b´ } finally ´e´` evaluates the block -´b´. If evaluation of ´b´ does not cause an exception to be -thrown, the expression ´e´ is evaluated. If an exception is thrown -during evaluation of ´e´, the evaluation of the try expression is -aborted with the thrown exception. If no exception is thrown during -evaluation of ´e´, the result of ´b´ is returned as the -result of the try expression. - -If an exception is thrown during evaluation of ´b´, the finally block -´e´ is also evaluated. If another exception ´e´ is thrown -during evaluation of ´e´, evaluation of the try expression is -aborted with the thrown exception. If no exception is thrown during -evaluation of ´e´, the original exception thrown in ´b´ is -re-thrown once evaluation of ´e´ has completed. The block -´b´ is expected to conform to the expected type of the try -expression. The finally expression ´e´ is expected to conform to -type `Unit`. - -A try expression `try { ´b´ } catch ´e_1´ finally ´e_2´` -is a shorthand -for `try { try { ´b´ } catch ´e_1´ } finally ´e_2´`. +This expression is evaluated by evaluating the block ´b´. +If evaluation of ´b´ does not cause an exception to be thrown, the result of ´b´ is returned. +Otherwise the handler ´h´ is applied to the thrown exception. +If the handler contains a case matching the thrown exception, the first such case is invoked. +If the handler contains no case matching the thrown exception, the exception is re-thrown. +More generally, if the handler is a `PartialFunction`, it is applied only if it is defined at the given exception. + +Let ´\mathit{pt}´ be the expected type of the try expression. +The block ´b´ is expected to conform to ´\mathit{pt}´. +The handler ´h´ is expected conform to type `scala.Function[scala.Throwable, ´\mathit{pt}\,´]`. +The type of the try expression is the [weak least upper bound](03-types.html#weak-conformance) of the type of ´b´ and the result type of ´h´. + +A try expression `try { ´b´ } finally ´e´` evaluates the block ´b´. +If evaluation of ´b´ does not cause an exception to be thrown, the expression ´e´ is evaluated. +If an exception is thrown during evaluation of ´e´, the evaluation of the try expression is aborted with the thrown exception. +If no exception is thrown during evaluation of ´e´, the result of ´b´ is returned as the result of the try expression. + +If an exception is thrown during evaluation of ´b´, the finally block ´e´ is also evaluated. +If another exception ´e´ is thrown during evaluation of ´e´, evaluation of the try expression is aborted with the thrown exception. +If no exception is thrown during evaluation of ´e´, the original exception thrown in ´b´ is re-thrown once evaluation of ´e´ has completed. +The block ´b´ is expected to conform to the expected type of the try expression. +The finally expression ´e´ is expected to conform to type `Unit`. + +A try expression `try { ´b´ } catch ´e_1´ finally ´e_2´` is a shorthand for `try { try { ´b´ } catch ´e_1´ } finally ´e_2´`. ## Anonymous Functions @@ -1187,18 +930,27 @@ Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’ Binding ::= (id | ‘_’) [‘:’ Type] ``` -The anonymous function of arity ´n´, `(´x_1´: ´T_1, ..., x_n´: ´T_n´) => e` maps parameters ´x_i´ of types ´T_i´ to a result given by expression ´e´. The scope of each formal parameter ´x_i´ is ´e´. Formal parameters must have pairwise distinct names. +The anonymous function of arity ´n´, `(´x_1´: ´T_1, ..., x_n´: ´T_n´) => e` maps parameters ´x_i´ of types ´T_i´ to a result given by expression ´e´. +The scope of each formal parameter ´x_i´ is ´e´. +Formal parameters must have pairwise distinct names. -In the case of a single untyped formal parameter, `(´x\,´) => ´e´` can be abbreviated to `´x´ => ´e´`. If an anonymous function `(´x´: ´T\,´) => ´e´` with a single typed parameter appears as the result expression of a block, it can be abbreviated to `´x´: ´T´ => e`. +In the case of a single untyped formal parameter, `(´x\,´) => ´e´` can be abbreviated to `´x´ => ´e´`. +If an anonymous function `(´x´: ´T\,´) => ´e´` with a single typed parameter appears as the result expression of a block, it can be abbreviated to `´x´: ´T´ => e`. -A formal parameter may also be a wildcard represented by an underscore `_`. In that case, a fresh name for the parameter is chosen arbitrarily. +A formal parameter may also be a wildcard represented by an underscore `_`. +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-implicits.html#implicit-parameters-and-views); however the parameter section itself does not count as an [implicit parameter section](07-implicits.html#implicit-parameters). Hence, arguments to anonymous functions always have to be given explicitly. +A named parameter of an anonymous function may be optionally preceded by an `implicit` modifier. +In that case the parameter is labeled [`implicit`](07-implicits.html#implicit-parameters-and-views); however the parameter section itself does not count as an [implicit parameter section](07-implicits.html#implicit-parameters). +Hence, arguments to anonymous functions always have to be given explicitly. ### Translation -If the expected type of the anonymous function is of the shape `scala.Function´n´[´S_1´, ..., ´S_n´, ´R\,´]`, or can be [SAM-converted](#sam-conversion) to such a function type, the type `´T_i´` of a parameter `´x_i´` can be omitted, as far as `´S_i´` is defined in the expected type, and `´T_i´ = ´S_i´` is assumed. Furthermore, the expected type when type checking ´e´ is ´R´. +If the expected type of the anonymous function is of the shape `scala.Function´n´[´S_1´, ..., ´S_n´, ´R\,´]`, or can be [SAM-converted](#sam-conversion) to such a function type, the type `´T_i´` of a parameter `´x_i´` can be omitted, as far as `´S_i´` is defined in the expected type, and `´T_i´ = ´S_i´` is assumed. +Furthermore, the expected type when type checking ´e´ is ´R´. -If there is no expected type for the function literal, all formal parameter types `´T_i´` must be specified explicitly, and the expected type of ´e´ is undefined. The type of the anonymous function is `scala.Function´n´[´T_1´, ..., ´T_n´, ´R\,´]`, where ´R´ is the [packed type](#expression-typing) of ´e´. ´R´ must be equivalent to a type which does not refer to any of the formal parameters ´x_i´. +If there is no expected type for the function literal, all formal parameter types `´T_i´` must be specified explicitly, and the expected type of ´e´ is undefined. +The type of the anonymous function is `scala.Function´n´[´T_1´, ..., ´T_n´, ´R\,´]`, where ´R´ is the [packed type](#expression-typing) of ´e´. +´R´ must be equivalent to a type which does not refer to any of the formal parameters ´x_i´. The eventual run-time value of an anonymous function is determined by the expected type: - a subclass of one of the builtin function types, `scala.Function´n´[´S_1, ..., S_n´, ´R\,´]` (with ´S_i´ and ´R´ fully defined), @@ -1218,15 +970,9 @@ The same evaluation holds for a SAM type, except that the instantiated type is g The underlying platform may provide more efficient ways of constructing these instances, such as Java 8's `invokedynamic` bytecode and `LambdaMetaFactory` class. -When a `PartialFunction` is required, an additional member `isDefinedAt` -is synthesized, which simply returns `true`. -However, if the function literal has the shape `x => x match { $...$ }`, -then `isDefinedAt` is derived from the pattern match in the following way: -each case from the match expression evaluates to `true`, -and if there is no default case, -a default case is added that evaluates to `false`. -For more details on how that is implemented see -["Pattern Matching Anonymous Functions"](08-pattern-matching.html#pattern-matching-anonymous-functions). +When a `PartialFunction` is required, an additional member `isDefinedAt` is synthesized, which simply returns `true`. +However, if the function literal has the shape `x => x match { $...$ }`, then `isDefinedAt` is derived from the pattern match in the following way: each case from the match expression evaluates to `true`, and if there is no default case, a default case is added that evaluates to `false`. +For more details on how that is implemented see ["Pattern Matching Anonymous Functions"](08-pattern-matching.html#pattern-matching-anonymous-functions). ###### Example Examples of anonymous functions: @@ -1253,29 +999,18 @@ _ => 5 // The function that ignores its argument SimpleExpr1 ::= ‘_’ ``` -An expression (of syntactic category `Expr`) -may contain embedded underscore symbols `_` at places where identifiers -are legal. Such an expression represents an anonymous function where subsequent -occurrences of underscores denote successive parameters. +An expression (of syntactic category `Expr`) may contain embedded underscore symbols `_` at places where identifiers are legal. +Such an expression represents an anonymous function where subsequent occurrences of underscores denote successive parameters. -Define an _underscore section_ to be an expression of the form -`_:´T´` where ´T´ is a type, or else of the form `_`, -provided the underscore does not appear as the expression part of a -type ascription `_:´T´`. +Define an _underscore section_ to be an expression of the form `_:´T´` where ´T´ is a type, or else of the form `_`, provided the underscore does not appear as the expression part of a type ascription `_:´T´`. -An expression ´e´ of syntactic category `Expr` _binds_ an underscore section -´u´, if the following two conditions hold: (1) ´e´ properly contains ´u´, and -(2) there is no other expression of syntactic category `Expr` -which is properly contained in ´e´ and which itself properly contains ´u´. +An expression ´e´ of syntactic category `Expr` _binds_ an underscore section ´u´, if the following two conditions hold: (1) ´e´ properly contains ´u´, and (2) there is no other expression of syntactic category `Expr` which is properly contained in ´e´ and which itself properly contains ´u´. -If an expression ´e´ binds underscore sections ´u_1, ..., u_n´, in this order, it is equivalent to -the anonymous function `(´u'_1´, ... ´u'_n´) => ´e'´` -where each ´u_i'´ results from ´u_i´ by replacing the underscore with a fresh identifier and -´e'´ results from ´e´ by replacing each underscore section ´u_i´ by ´u_i'´. +If an expression ´e´ binds underscore sections ´u_1, ..., u_n´, in this order, it is equivalent to the anonymous function `(´u'_1´, ... ´u'_n´) => ´e'´` where each ´u_i'´ results from ´u_i´ by replacing the underscore with a fresh identifier and ´e'´ results from ´e´ by replacing each underscore section ´u_i´ by ´u_i'´. ###### Example -The anonymous functions in the left column use placeholder -syntax. Each of these is equivalent to the anonymous function on its right. +The anonymous functions in the left column use placeholder syntax. +Each of these is equivalent to the anonymous function on its right. | | | |---------------------------|----------------------------| @@ -1289,15 +1024,13 @@ syntax. Each of these is equivalent to the anonymous function on its right. ## Constant Expressions Constant expressions are expressions that the Scala compiler can evaluate to a constant. -The definition of "constant expression" depends on the platform, but they -include at least the expressions of the following forms: +The definition of "constant expression" depends on the platform, but they include at least the expressions of the following forms: - A literal of a value class, such as an integer - A string literal - A class constructed with [`Predef.classOf`](12-the-scala-standard-library.html#the-predef-object) - An element of an enumeration from the underlying platform -- A literal array, of the form `Array´(c_1, ..., c_n)´`, - where all of the ´c_i´'s are themselves constant expressions +- A literal array, of the form `Array´(c_1, ..., c_n)´`, where all of the ´c_i´'s are themselves constant expressions - An identifier defined by a [constant value definition](04-basic-declarations-and-definitions.html#value-declarations-and-definitions). ## Statements @@ -1315,40 +1048,31 @@ TemplateStat ::= Import | ``` -Statements occur as parts of blocks and templates. A _statement_ can be -an import, a definition or an expression, or it can be empty. -Statements used in the template of a class definition can also be -declarations. An expression that is used as a statement can have an -arbitrary value type. An expression statement ´e´ is evaluated by -evaluating ´e´ and discarding the result of the evaluation. +Statements occur as parts of blocks and templates. +A _statement_ can be an import, a definition or an expression, or it can be empty. +Statements used in the template of a class definition can also be declarations. +An expression that is used as a statement can have an arbitrary value type. +An expression statement ´e´ is evaluated by evaluating ´e´ and discarding the result of the evaluation. -Block statements may be definitions which bind local names in the -block. The only modifier allowed in all block-local definitions is -`implicit`. When prefixing a class or object definition, -modifiers `abstract`, `final`, and `sealed` are also -permitted. +Block statements may be definitions which bind local names in the block. +The only modifier allowed in all block-local definitions is `implicit`. +When prefixing a class or object definition, modifiers `abstract`, `final`, and `sealed` are also permitted. -Evaluation of a statement sequence entails evaluation of the -statements in the order they are written. +Evaluation of a statement sequence entails evaluation of the statements in the order they are written. ## Implicit Conversions -Implicit conversions can be applied to expressions whose type does not -match their expected type, to qualifiers in selections, and to unapplied methods. The -available implicit conversions are given in the next two sub-sections. +Implicit conversions can be applied to expressions whose type does not match their expected type, to qualifiers in selections, and to unapplied methods. +The available implicit conversions are given in the next two sub-sections. ### Value Conversions -The following seven implicit conversions can be applied to an -expression ´e´ which has some value type ´T´ and which is type-checked with -some expected type ´\mathit{pt}´. +The following seven implicit conversions can be applied to an expression ´e´ which has some value type ´T´ and which is type-checked with some expected type ´\mathit{pt}´. ###### Static Overloading Resolution -If an expression denotes several possible members of a class, -[overloading resolution](#overloading-resolution) -is applied to pick a unique member. +If an expression denotes several possible members of a class, [overloading resolution](#overloading-resolution) is applied to pick a unique member. ###### Type Instantiation An expression ´e´ of polymorphic type @@ -1357,47 +1081,31 @@ An expression ´e´ of polymorphic type [´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´ ``` -which does not appear as the function part of -a type application is converted to a type instance of ´T´ -by determining with [local type inference](#local-type-inference) -instance types `´T_1, ..., T_n´` -for the type variables `´a_1, ..., a_n´` and -implicitly embedding ´e´ in the [type application](#type-applications) -`´e´[´T_1, ..., T_n´]`. +which does not appear as the function part of a type application is converted to a type instance of ´T´ by determining with [local type inference](#local-type-inference) instance types `´T_1, ..., T_n´` for the type variables `´a_1, ..., a_n´` and implicitly embedding ´e´ in the [type application](#type-applications) `´e´[´T_1, ..., T_n´]`. ###### Numeric Widening -If ´e´ has a primitive number type which [weakly conforms](03-types.html#weak-conformance) -to the expected type, it is widened to -the expected type using one of the numeric conversion methods -`toShort`, `toChar`, `toInt`, `toLong`, -`toFloat`, `toDouble` defined [in the standard library](12-the-scala-standard-library.html#numeric-value-types). +If ´e´ has a primitive number type which [weakly conforms](03-types.html#weak-conformance) to the expected type, it is widened to the expected type using one of the numeric conversion methods `toShort`, `toChar`, `toInt`, `toLong`, `toFloat`, `toDouble` defined [in the standard library](12-the-scala-standard-library.html#numeric-value-types). -Since conversions from `Int` to `Float` and from `Long` to `Float` or `Double` -may incur a loss of precision, those implicit conversions are deprecated. -The conversion is permitted for literals if the original value can be recovered, -that is, if conversion back to the original type produces the original value. +Since conversions from `Int` to `Float` and from `Long` to `Float` or `Double` may incur a loss of precision, those implicit conversions are deprecated. +The conversion is permitted for literals if the original value can be recovered, that is, if conversion back to the original type produces the original value. ###### Numeric Literal Narrowing -If the expected type is `Byte`, `Short` or `Char`, and -the expression ´e´ is an integer literal fitting in the range of that -type, it is converted to the same literal in that type. +If the expected type is `Byte`, `Short` or `Char`, and the expression ´e´ is an integer literal fitting in the range of that type, it is converted to the same literal in that type. ###### Value Discarding -If ´e´ has some value type and the expected type is `Unit`, -´e´ is converted to the expected type by embedding it in the -term `{ ´e´; () }`. +If ´e´ has some value type and the expected type is `Unit`, ´e´ is converted to the expected type by embedding it in the term `{ ´e´; () }`. ###### SAM conversion An expression `(p1, ..., pN) => body` of function type `(T1, ..., TN) => T` is sam-convertible to the expected type `S` if the following holds: - the class `C` of `S` declares an abstract method `m` with signature `(p1: A1, ..., pN: AN): R`; - besides `m`, `C` must not declare or inherit any other deferred value members; - the method `m` must have a single argument list; - - there must be a type `U` that is a subtype of `S`, so that the expression - `new U { final def m(p1: A1, ..., pN: AN): R = body }` is well-typed (conforming to the expected type `S`); + - there must be a type `U` that is a subtype of `S`, so that the expression `new U { final def m(p1: A1, ..., pN: AN): R = body }` is well-typed (conforming to the expected type `S`); - for the purpose of scoping, `m` should be considered a static member (`U`'s members are not in scope in `body`); - `(A1, ..., AN) => R` is a subtype of `(T1, ..., TN) => T` (satisfying this condition drives type inference of unknown type parameters in `S`); -Note that a function literal that targets a SAM is not necessarily compiled to the above instance creation expression. This is platform-dependent. +Note that a function literal that targets a SAM is not necessarily compiled to the above instance creation expression. +This is platform-dependent. It follows that: - if class `C` defines a constructor, it must be accessible and must define exactly one, empty, argument list; @@ -1412,106 +1120,71 @@ Finally, we impose some implementation restrictions (these may be lifted in futu - `C` must not be `@specialized`. ###### 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-implicits.html#views). +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-implicits.html#views). ###### Selection on `Dynamic` -If none of the previous conversions applies, and ´e´ is a prefix -of a selection ´e.x´, and ´e´'s type conforms to class `scala.Dynamic`, -then the selection is rewritten according to the rules for -[dynamic member selection](#dynamic-member-selection). +If none of the previous conversions applies, and ´e´ is a prefix of a selection ´e.x´, and ´e´'s type conforms to class `scala.Dynamic`, then the selection is rewritten according to the rules for [dynamic member selection](#dynamic-member-selection). ### Method Conversions -The following four implicit conversions can be applied to methods -which are not applied to some argument list. +The following four implicit conversions can be applied to methods which are not applied to some argument list. ###### Evaluation -A parameterless method ´m´ of type `=> ´T´` is always converted to -type ´T´ by evaluating the expression to which ´m´ is bound. +A parameterless method ´m´ of type `=> ´T´` is always converted to 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-implicits.html#implicit-parameters). +If the method takes only implicit parameters, implicit arguments are passed following the rules [here](07-implicits.html#implicit-parameters). ###### Eta Expansion -Otherwise, if the method is not a constructor, -and the expected type ´\mathit{pt}´ is a function type, or, -for methods of non-zero arity, a type [sam-convertible](#sam-conversion) to a function type, -´(\mathit{Ts}') \Rightarrow T'´, [eta-expansion](#eta-expansion-section) -is performed on the expression ´e´. +Otherwise, if the method is not a constructor, and the expected type ´\mathit{pt}´ is a function type, or, for methods of non-zero arity, a type [sam-convertible](#sam-conversion) to a function type, ´(\mathit{Ts}') \Rightarrow T'´, [eta-expansion](#eta-expansion-section) is performed on the expression ´e´. (The exception for zero-arity methods is to avoid surprises due to unexpected sam conversion.) ###### Empty Application -Otherwise, if ´e´ has method type ´()T´, it is implicitly applied to the empty -argument list, yielding ´e()´. +Otherwise, if ´e´ has method type ´()T´, it is implicitly applied to the empty argument list, yielding ´e()´. ### Overloading Resolution -If an identifier or selection ´e´ references several members of a -class, the context of the reference is used to identify a unique -member. The way this is done depends on whether or not ´e´ is used as -a function. Let ´\mathscr{A}´ be the set of members referenced by ´e´. +If an identifier or selection ´e´ references several members of a class, the context of the reference is used to identify a unique member. +The way this is done depends on whether or not ´e´ is used as a function. +Let ´\mathscr{A}´ be the set of members referenced by ´e´. -Assume first that ´e´ appears as a function in an application, as in -`´e´(´e_1´, ..., ´e_m´)`. +Assume first that ´e´ appears as a function in an application, as in `´e´(´e_1´, ..., ´e_m´)`. -One first determines the set of functions that is potentially [applicable](#function-applications) -based on the _shape_ of the arguments. +One first determines the set of functions that is potentially [applicable](#function-applications) based on the _shape_ of the arguments. -The *shape* of an argument expression ´e´, written ´\mathit{shape}(e)´, is -a type that is defined as follows: - - For a function expression `(´p_1´: ´T_1, ..., p_n´: ´T_n´) => ´b´: (Any, ..., Any) => ´\mathit{shape}(b)´`, - where `Any` occurs ´n´ times in the argument type. +The *shape* of an argument expression ´e´, written ´\mathit{shape}(e)´, is a type that is defined as follows: + - For a function expression `(´p_1´: ´T_1, ..., p_n´: ´T_n´) => ´b´: (Any, ..., Any) => ´\mathit{shape}(b)´`, where `Any` occurs ´n´ times in the argument type. - For a pattern-matching anonymous function definition `{ case ... }`: `PartialFunction[Any, Nothing]`. - For a named argument `´n´ = ´e´`: ´\mathit{shape}(e)´. - For all other expressions: `Nothing`. -Let ´\mathscr{B}´ be the set of alternatives in ´\mathscr{A}´ that are [_applicable_](#function-applications) -to expressions ´(e_1, ..., e_n)´ of types ´(\mathit{shape}(e_1), ..., \mathit{shape}(e_n))´. +Let ´\mathscr{B}´ be the set of alternatives in ´\mathscr{A}´ that are [_applicable_](#function-applications) to expressions ´(e_1, ..., e_n)´ of types ´(\mathit{shape}(e_1), ..., \mathit{shape}(e_n))´. If there is precisely one alternative in ´\mathscr{B}´, that alternative is chosen. Otherwise, let ´S_1, ..., S_m´ be the list of types obtained by typing each argument as follows. -Normally, an argument is typed without an expected type, except when -all alternatives explicitly specify the same parameter type for this argument (a missing parameter type, -due to e.g. arity differences, is taken as `NoType`, thus resorting to no expected type), -or when trying to propagate more type information to aid inference of higher-order function parameter types, as explained next. - -The intuition for higher-order function parameter type inference is that all arguments must be of a function-like type -(`PartialFunction`, `FunctionN` or some equivalent [SAM type](#sam-conversion)), -which in turn must define the same set of higher-order argument types, so that they can safely be used as -the expected type of a given argument of the overloaded method, without unduly ruling out any alternatives. -The intent is not to steer overloading resolution, but to preserve enough type information to steer type -inference of the arguments (a function literal or eta-expanded method) to this overloaded method. - -Note that the expected type drives eta-expansion (not performed unless a function-like type is expected), -as well as inference of omitted parameter types of function literals. - -More precisely, an argument `´e_i´` is typed with an expected type that is derived from the `´i´`th argument -type found in each alternative (call these `´T_{ij}´` for alternative `´j´` and argument position `´i´`) when -all `´T_{ij}´` are function types `´(A_{1j},..., A_{nj}) => ?´` (or the equivalent `PartialFunction`, or SAM) -of some arity `´n´`, and their argument types `´A_{kj}´` are identical across all overloads `´j´` for a -given `´k´`. Then, the expected type for `´e_i´` is derived as follows: +Normally, an argument is typed without an expected type, except when all alternatives explicitly specify the same parameter type for this argument (a missing parameter type, due to e.g. arity differences, is taken as `NoType`, thus resorting to no expected type), or when trying to propagate more type information to aid inference of higher-order function parameter types, as explained next. + +The intuition for higher-order function parameter type inference is that all arguments must be of a function-like type (`PartialFunction`, `FunctionN` or some equivalent [SAM type](#sam-conversion)), which in turn must define the same set of higher-order argument types, so that they can safely be used as the expected type of a given argument of the overloaded method, without unduly ruling out any alternatives. +The intent is not to steer overloading resolution, but to preserve enough type information to steer type inference of the arguments (a function literal or eta-expanded method) to this overloaded method. + +Note that the expected type drives eta-expansion (not performed unless a function-like type is expected), as well as inference of omitted parameter types of function literals. + +More precisely, an argument `´e_i´` is typed with an expected type that is derived from the `´i´`th argument type found in each alternative (call these `´T_{ij}´` for alternative `´j´` and argument position `´i´`) when all `´T_{ij}´` are function types `´(A_{1j},..., A_{nj}) => ?´` (or the equivalent `PartialFunction`, or SAM) of some arity `´n´`, and their argument types `´A_{kj}´` are identical across all overloads `´j´` for a given `´k´`. +Then, the expected type for `´e_i´` is derived as follows: - we use `´PartialFunction[A_{1j},..., A_{nj}, ?]´` if for some overload `´j´`, `´T_{ij}´`'s type symbol is `PartialFunction`; - else, if for some `´j´`, `´T_{ij}´` is `FunctionN`, the expected type is `´FunctionN[A_{1j},..., A_{nj}, ?]´`; - - else, if for all `´j´`, `´T_{ij}´` is a SAM type of the same class, defining argument types `´A_{1j},..., A_{nj}´` - (and a potentially varying result type), the expected type encodes these argument types and the SAM class. + - else, if for all `´j´`, `´T_{ij}´` is a SAM type of the same class, defining argument types `´A_{1j},..., A_{nj}´` (and a potentially varying result type), the expected type encodes these argument types and the SAM class. -For every member ´m´ in ´\mathscr{B}´ one determines whether it is applicable -to expressions (´e_1, ..., e_m´) of types ´S_1, ..., S_m´. +For every member ´m´ in ´\mathscr{B}´ one determines whether it is applicable to expressions (´e_1, ..., e_m´) of types ´S_1, ..., S_m´. -It is an error if none of the members in ´\mathscr{B}´ is applicable. If there is one -single applicable alternative, that alternative is chosen. Otherwise, let ´\mathscr{CC}´ -be the set of applicable alternatives which don't employ any default argument -in the application to ´e_1, ..., e_m´. +It is an error if none of the members in ´\mathscr{B}´ is applicable. +If there is one single applicable alternative, that alternative is chosen. +Otherwise, let ´\mathscr{CC}´ be the set of applicable alternatives which don't employ any default argument in the application to ´e_1, ..., e_m´. It is again an error if ´\mathscr{CC}´ is empty. -Otherwise, one chooses the _most specific_ alternative among the alternatives -in ´\mathscr{CC}´, according to the following definition of being "as specific as", and -"more specific than": +Otherwise, one chooses the _most specific_ alternative among the alternatives in ´\mathscr{CC}´, according to the following definition of being "as specific as", and "more specific than": -- A parameterized method ´m´ of type `(´p_1:T_1, ..., p_n:T_n´)´U´` is - _as specific as_ some other member ´m'´ of type ´S´ if ´m'´ is [applicable](#function-applications) - to arguments `(´p_1, ..., p_n´)` of types ´T_1, ..., T_n´. -- A polymorphic method of type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´` is - as specific as some other member of type ´S´ if ´T´ is as specific as ´S´ - under the assumption that for ´i = 1, ..., n´ each ´a_i´ is an abstract type name - bounded from below by ´L_i´ and from above by ´U_i´. +- A parameterized method ´m´ of type `(´p_1:T_1, ..., p_n:T_n´)´U´` is _as specific as_ some other member ´m'´ of type ´S´ if ´m'´ is [applicable](#function-applications) to arguments `(´p_1, ..., p_n´)` of types ´T_1, ..., T_n´. +- A polymorphic method of type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´` is as specific as some other member of type ´S´ if ´T´ is as specific as ´S´ under the assumption that for ´i = 1, ..., n´ each ´a_i´ is an abstract type name bounded from below by ´L_i´ and from above by ´U_i´. - A member of any other type is always as specific as a parameterized method or a polymorphic method. -- Given two members of types ´T´ and ´U´ which are neither parameterized nor polymorphic method types, - the member of type ´T´ is as specific as the member of type ´U´ if - the existential dual of ´T´ conforms to the existential dual of ´U´. - Here, the existential dual of a polymorphic type - `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´` is - `´T´ forSome { type ´a_1´ >: ´L_1´ <: ´U_1´, ..., type ´a_n´ >: ´L_n´ <: ´U_n´}`. - The existential dual of every other type is the type itself. +- Given two members of types ´T´ and ´U´ which are neither parameterized nor polymorphic method types, the member of type ´T´ is as specific as the member of type ´U´ if the existential dual of ´T´ conforms to the existential dual of ´U´. +Here, the existential dual of a polymorphic type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´` is `´T´ forSome { type ´a_1´ >: ´L_1´ <: ´U_1´, ..., type ´a_n´ >: ´L_n´ <: ´U_n´}`. +The existential dual of every other type is the type itself. The _relative weight_ of an alternative ´A´ over an alternative ´B´ is a number from 0 to 2, defined as the sum of @@ -1546,34 +1210,26 @@ number from 0 to 2, defined as the sum of - 1 if ´A´ is as specific as ´B´, 0 otherwise, and - 1 if ´A´ is defined in a class or object which is derived from the class or object defining ´B´, 0 otherwise. -A class or object ´C´ is _derived_ from a class or object ´D´ if one of -the following holds: +A class or object ´C´ is _derived_ from a class or object ´D´ if one of the following holds: - ´C´ is a subclass of ´D´, or - ´C´ is a companion object of a class derived from ´D´, or - ´D´ is a companion object of a class from which ´C´ is derived. -An alternative ´A´ is _more specific_ than an alternative ´B´ if -the relative weight of ´A´ over ´B´ is greater than the relative -weight of ´B´ over ´A´. +An alternative ´A´ is _more specific_ than an alternative ´B´ if the relative weight of ´A´ over ´B´ is greater than the relative weight of ´B´ over ´A´. -It is an error if there is no alternative in ´\mathscr{CC}´ which is more -specific than all other alternatives in ´\mathscr{CC}´. +It is an error if there is no alternative in ´\mathscr{CC}´ which is more specific than all other alternatives in ´\mathscr{CC}´. -Assume next that ´e´ appears as a function in a type application, as -in `´e´[´\mathit{targs}\,´]`. Then all alternatives in -´\mathscr{A}´ which take the same number of type parameters as there are type -arguments in ´\mathit{targs}´ are chosen. It is an error if no such alternative exists. -If there are several such alternatives, overloading resolution is -applied again to the whole expression `´e´[´\mathit{targs}\,´]`. +Assume next that ´e´ appears as a function in a type application, as in `´e´[´\mathit{targs}\,´]`. +Then all alternatives in ´\mathscr{A}´ which take the same number of type parameters as there are type arguments in ´\mathit{targs}´ are chosen. +It is an error if no such alternative exists. +If there are several such alternatives, overloading resolution is applied again to the whole expression `´e´[´\mathit{targs}\,´]`. Assume finally that ´e´ does not appear as a function in either an application or a type application. -If an expected type is given, let ´\mathscr{B}´ be the set of those alternatives -in ´\mathscr{A}´ which are [compatible](03-types.html#compatibility) to it. +If an expected type is given, let ´\mathscr{B}´ be the set of those alternatives in ´\mathscr{A}´ which are [compatible](03-types.html#compatibility) to it. Otherwise, let ´\mathscr{B}´ be the same as ´\mathscr{A}´. In this last case we choose the most specific alternative among all alternatives in ´\mathscr{B}´. -It is an error if there is no alternative in ´\mathscr{B}´ which is -more specific than all other alternatives in ´\mathscr{B}´. +It is an error if there is no alternative in ´\mathscr{B}´ which is more specific than all other alternatives in ´\mathscr{B}´. ###### Example Consider the following definitions: @@ -1586,109 +1242,69 @@ val a: A val b: B ``` -Then the application `f(b, b)` refers to the first -definition of ´f´ whereas the application `f(a, a)` -refers to the second. Assume now we add a third overloaded definition +Then the application `f(b, b)` refers to the first definition of ´f´ whereas the application `f(a, a)` refers to the second. +Assume now we add a third overloaded definition ```scala def f(x: B, y: A) = ... ``` -Then the application `f(a, a)` is rejected for being ambiguous, since -no most specific applicable signature exists. +Then the application `f(a, a)` is rejected for being ambiguous, since no most specific applicable signature exists. ### Local Type Inference -Local type inference infers type arguments to be passed to expressions -of polymorphic type. Say ´e´ is of type [´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´ -and no explicit type parameters are given. +Local type inference infers type arguments to be passed to expressions of polymorphic type. +Say ´e´ is of type [´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´ and no explicit type parameters are given. -Local type inference converts this expression to a type -application `´e´[´T_1, ..., T_n´]`. The choice of the -type arguments ´T_1, ..., T_n´ depends on the context in which -the expression appears and on the expected type ´\mathit{pt}´. +Local type inference converts this expression to a type application `´e´[´T_1, ..., T_n´]`. +The choice of the type arguments ´T_1, ..., T_n´ depends on the context in which the expression appears and on the expected type ´\mathit{pt}´. There are three cases. ###### Case 1: Selections -If the expression appears as the prefix of a selection with a name -´x´, then type inference is _deferred_ to the whole expression -´e.x´. That is, if ´e.x´ has type ´S´, it is now treated as having -type [´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´, -and local type inference is applied in turn to infer type arguments -for ´a_1, ..., a_n´, using the context in which ´e.x´ appears. +If the expression appears as the prefix of a selection with a name ´x´, then type inference is _deferred_ to the whole expression ´e.x´. +That is, if ´e.x´ has type ´S´, it is now treated as having type [´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´, and local type inference is applied in turn to infer type arguments for ´a_1, ..., a_n´, using the context in which ´e.x´ appears. ###### Case 2: Values -If the expression ´e´ appears as a value without being applied to -value arguments, the type arguments are inferred by solving a -constraint system which relates the expression's type ´T´ with the -expected type ´\mathit{pt}´. Without loss of generality we can assume that -´T´ is a value type; if it is a method type we apply -[eta-expansion](#eta-expansion-section) to convert it to a function type. Solving -means finding a substitution ´\sigma´ of types ´T_i´ for the type -parameters ´a_i´ such that - -- None of the inferred types ´T_i´ is a [singleton type](03-types.html#singleton-types) - unless it is a singleton type corresponding to an object or a constant value - definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. -- All type parameter bounds are respected, i.e. - ´\sigma L_i <: \sigma a_i´ and ´\sigma a_i <: \sigma U_i´ for ´i = 1, ..., n´. -- The expression's type conforms to the expected type, i.e. - ´\sigma T <: \sigma \mathit{pt}´. +If the expression ´e´ appears as a value without being applied to value arguments, the type arguments are inferred by solving a constraint system which relates the expression's type ´T´ with the expected type ´\mathit{pt}´. +Without loss of generality we can assume that ´T´ is a value type; if it is a method type we apply [eta-expansion](#eta-expansion-section) to convert it to a function type. +Solving means finding a substitution ´\sigma´ of types ´T_i´ for the type parameters ´a_i´ such that + +- None of the inferred types ´T_i´ is a [singleton type](03-types.html#singleton-types) unless it is a singleton type corresponding to an object or a constant value definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. +- All type parameter bounds are respected, i.e. ´\sigma L_i <: \sigma a_i´ and ´\sigma a_i <: \sigma U_i´ for ´i = 1, ..., n´. +- The expression's type conforms to the expected type, i.e. ´\sigma T <: \sigma \mathit{pt}´. It is a compile time error if no such substitution exists. -If several substitutions exist, local-type inference will choose for -each type variable ´a_i´ a minimal or maximal type ´T_i´ of the -solution space. A _maximal_ type ´T_i´ will be chosen if the type -parameter ´a_i´ appears [contravariantly](04-basic-declarations-and-definitions.html#variance-annotations) in the -type ´T´ of the expression. A _minimal_ type ´T_i´ will be chosen -in all other situations, i.e. if the variable appears covariantly, -non-variantly or not at all in the type ´T´. We call such a substitution -an _optimal solution_ of the given constraint system for the type ´T´. +If several substitutions exist, local-type inference will choose for each type variable ´a_i´ a minimal or maximal type ´T_i´ of the solution space. +A _maximal_ type ´T_i´ will be chosen if the type parameter ´a_i´ appears [contravariantly](04-basic-declarations-and-definitions.html#variance-annotations) in the type ´T´ of the expression. +A _minimal_ type ´T_i´ will be chosen in all other situations, i.e. if the variable appears covariantly, non-variantly or not at all in the type ´T´. +We call such a substitution an _optimal solution_ of the given constraint system for the type ´T´. ###### Case 3: Methods -The last case applies if the expression -´e´ appears in an application ´e(d_1, ..., d_m)´. In that case -´T´ is a method type ´(p_1:R_1, ..., p_m:R_m)T'´. Without loss of -generality we can assume that the result type ´T'´ is a value type; if -it is a method type we apply [eta-expansion](#eta-expansion-section) to -convert it to a function type. One computes first the types ´S_j´ of -the argument expressions ´d_j´, using two alternative schemes. Each -argument expression ´d_j´ is typed first with the expected type ´R_j´, -in which the type parameters ´a_1, ..., a_n´ are taken as type -constants. If this fails, the argument ´d_j´ is typed instead with an -expected type ´R_j'´ which results from ´R_j´ by replacing every type -parameter in ´a_1, ..., a_n´ with _undefined_. - -In a second step, type arguments are inferred by solving a constraint -system which relates the method's type with the expected type -´\mathit{pt}´ and the argument types ´S_1, ..., S_m´. Solving the -constraint system means -finding a substitution ´\sigma´ of types ´T_i´ for the type parameters -´a_i´ such that - -- None of the inferred types ´T_i´ is a [singleton type](03-types.html#singleton-types) - unless it is a singleton type corresponding to an object or a constant value - definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. -- All type parameter bounds are respected, i.e. ´\sigma L_i <: \sigma a_i´ and - ´\sigma a_i <: \sigma U_i´ for ´i = 1, ..., n´. +The last case applies if the expression ´e´ appears in an application ´e(d_1, ..., d_m)´. +In that case ´T´ is a method type ´(p_1:R_1, ..., p_m:R_m)T'´. +Without loss of generality we can assume that the result type ´T'´ is a value type; if it is a method type we apply [eta-expansion](#eta-expansion-section) to +convert it to a function type. +One computes first the types ´S_j´ of the argument expressions ´d_j´, using two alternative schemes. +Each argument expression ´d_j´ is typed first with the expected type ´R_j´, in which the type parameters ´a_1, ..., a_n´ are taken as type constants. +If this fails, the argument ´d_j´ is typed instead with an expected type ´R_j'´ which results from ´R_j´ by replacing every type parameter in ´a_1, ..., a_n´ with _undefined_. + +In a second step, type arguments are inferred by solving a constraint system which relates the method's type with the expected type ´\mathit{pt}´ and the argument types ´S_1, ..., S_m´. +Solving the constraint system means finding a substitution ´\sigma´ of types ´T_i´ for the type parameters ´a_i´ such that + +- None of the inferred types ´T_i´ is a [singleton type](03-types.html#singleton-types) unless it is a singleton type corresponding to an object or a constant value definition or the corresponding bound ´U_i´ is a subtype of `scala.Singleton`. +- All type parameter bounds are respected, i.e. ´\sigma L_i <: \sigma a_i´ and ´\sigma a_i <: \sigma U_i´ for ´i = 1, ..., n´. - The method's result type ´T'´ conforms to the expected type, i.e. ´\sigma T' <: \sigma \mathit{pt}´. -- Each argument type [weakly conforms](03-types.html#weak-conformance) - to the corresponding formal parameter - type, i.e. ´\sigma S_j <:_w \sigma R_j´ for ´j = 1, ..., m´. +- Each argument type [weakly conforms](03-types.html#weak-conformance) to the corresponding formal parameter type, i.e. ´\sigma S_j <:_w \sigma R_j´ for ´j = 1, ..., m´. -It is a compile time error if no such substitution exists. If several -solutions exist, an optimal one for the type ´T'´ is chosen. +It is a compile time error if no such substitution exists. +If several solutions exist, an optimal one for the type ´T'´ is chosen. -All or parts of an expected type ´\mathit{pt}´ may be undefined. The rules for -[conformance](03-types.html#conformance) are extended to this case by adding -the rule that for any type ´T´ the following two statements are always -true: ´\mathit{undefined} <: T´ and ´T <: \mathit{undefined}´ +All or parts of an expected type ´\mathit{pt}´ may be undefined. +The rules for [conformance](03-types.html#conformance) are extended to this case by adding the rule that for any type ´T´ the following two statements are always true: ´\mathit{undefined} <: T´ and ´T <: \mathit{undefined}´ -It is possible that no minimal or maximal solution for a type variable -exists, in which case a compile-time error results. Because ´<:´ is a -pre-order, it is also possible that a solution set has several optimal -solutions for a type. In that case, a Scala compiler is free to pick -any one of them. +It is possible that no minimal or maximal solution for a type variable exists, in which case a compile-time error results. +Because ´<:´ is a pre-order, it is also possible that a solution set has several optimal solutions for a type. +In that case, a Scala compiler is free to pick any one of them. ###### Example Consider the two methods: @@ -1704,33 +1320,26 @@ and the definition val xs = cons(1, nil) ``` -The application of `cons` is typed with an undefined expected -type. This application is completed by local type inference to -`cons[Int](1, nil)`. -Here, one uses the following -reasoning to infer the type argument `Int` for the type -parameter `a`: +The application of `cons` is typed with an undefined expected type. +This application is completed by local type inference to `cons[Int](1, nil)`. +Here, one uses the following reasoning to infer the type argument `Int` for the type parameter `a`: -First, the argument expressions are typed. The first argument `1` -has type `Int` whereas the second argument `nil` is -itself polymorphic. One tries to type-check `nil` with an -expected type `List[a]`. This leads to the constraint system +First, the argument expressions are typed. The first argument `1` has type `Int` whereas the second argument `nil` is itself polymorphic. +One tries to type-check `nil` with an expected type `List[a]`. +This leads to the constraint system ```scala List[b?] <: List[a] ``` -where we have labeled `b?` with a question mark to indicate -that it is a variable in the constraint system. -Because class `List` is covariant, the optimal -solution of this constraint is +where we have labeled `b?` with a question mark to indicate that it is a variable in the constraint system. +Because class `List` is covariant, the optimal solution of this constraint is ```scala b = scala.Nothing ``` -In a second step, one solves the following constraint system for -the type parameter `a` of `cons`: +In a second step, one solves the following constraint system for the type parameter `a` of `cons`: ```scala Int <: a? @@ -1757,16 +1366,14 @@ val ys = cons("abc", xs) where `xs` is defined of type `List[Int]` as before. In this case local type inference proceeds as follows. -First, the argument expressions are typed. The first argument -`"abc"` has type `String`. The second argument `xs` is -first tried to be typed with expected type `List[a]`. This fails, -as `List[Int]` is not a subtype of `List[a]`. Therefore, -the second strategy is tried; `xs` is now typed with expected type -`List[´\mathit{undefined}´]`. This succeeds and yields the argument type -`List[Int]`. +First, the argument expressions are typed. +The first argument `"abc"` has type `String`. +The second argument `xs` is first tried to be typed with expected type `List[a]`. +This fails,as `List[Int]` is not a subtype of `List[a]`. +Therefore, the second strategy is tried; `xs` is now typed with expected type `List[´\mathit{undefined}´]`. +This succeeds and yields the argument type `List[Int]`. -In a second step, one solves the following constraint system for -the type parameter `a` of `cons`: +In a second step, one solves the following constraint system for the type parameter `a` of `cons`: ```scala String <: a? @@ -1784,16 +1391,14 @@ so `scala.Any` is the type inferred for `a`. ### Eta Expansion -_Eta-expansion_ converts an expression of method type to an -equivalent expression of function type. It proceeds in two steps. +_Eta-expansion_ converts an expression of method type to an equivalent expression of function type. +It proceeds in two steps. -First, one identifies the maximal sub-expressions of ´e´; let's -say these are ´e_1, ..., e_m´. For each of these, one creates a -fresh name ´x_i´. Let ´e'´ be the expression resulting from -replacing every maximal subexpression ´e_i´ in ´e´ by the -corresponding fresh name ´x_i´. Second, one creates a fresh name ´y_i´ -for every argument type ´T_i´ of the method (´i = 1 , ..., -n´). The result of eta-conversion is then: +First, one identifies the maximal sub-expressions of ´e´; let's say these are ´e_1, ..., e_m´. +For each of these, one creates a fresh name ´x_i´. +Let ´e'´ be the expression resulting from replacing every maximal subexpression ´e_i´ in ´e´ by the corresponding fresh name ´x_i´. +Second, one creates a fresh name ´y_i´ for every argument type ´T_i´ of the method (´i = 1 , ..., n´). +The result of eta-conversion is then: ```scala { val ´x_1´ = ´e_1´; @@ -1803,13 +1408,12 @@ n´). The result of eta-conversion is then: } ``` -The behavior of [call-by-name parameters](#function-applications) -is preserved under eta-expansion: the corresponding actual argument expression, -a sub-expression of parameterless method type, is not evaluated in the expanded block. +The behavior of [call-by-name parameters](#function-applications) is preserved under eta-expansion: the corresponding actual argument expression, a sub-expression of parameterless method type, is not evaluated in the expanded block. ### Dynamic Member Selection -The standard Scala library defines a marker trait `scala.Dynamic`. Subclasses of this trait are able to intercept selections and applications on their instances by defining methods of the names `applyDynamic`, `applyDynamicNamed`, `selectDynamic`, and `updateDynamic`. +The standard Scala library defines a marker trait `scala.Dynamic`. +Subclasses of this trait are able to intercept selections and applications on their instances by defining methods of the names `applyDynamic`, `applyDynamicNamed`, `selectDynamic`, and `updateDynamic`. The following rewrites are performed, assuming ´e´'s type conforms to `scala.Dynamic`, and the original expression does not type check under the normal rules, as specified fully in the relevant subsection of [implicit conversion](#dynamic-member-selection): diff --git a/docs/_spec/07-implicits.md b/docs/_spec/07-implicits.md index 47dc4ca0b0d4..a0db9dd9b418 100644 --- a/docs/_spec/07-implicits.md +++ b/docs/_spec/07-implicits.md @@ -13,17 +13,13 @@ 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). +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. +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] { @@ -44,61 +40,41 @@ object Monoids { ## Implicit Parameters -An _implicit parameter list_ -`(implicit ´p_1´,...,´p_n´)` of a method marks the parameters ´p_1, ..., 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. To be accessible without a prefix, an identifier -must be a local name, a member of an enclosing template or a name introduced by 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´. +An _implicit parameter list_ `(implicit ´p_1´,...,´p_n´)` of a method marks the parameters ´p_1, ..., 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. +To be accessible without a prefix, an identifier must be a local name, a member of an enclosing template or a name introduced by 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 ... with ´T_n´`, - the union of the parts of ´T_1, ..., T_n´, as well as ´T´ itself; -- if ´T´ is a parameterized type `´S´[´T_1, ..., T_n´]`, - the union of the parts of ´S´ and ´T_1, ..., 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 compound type `´T_1´ with ... with ´T_n´`, the union of the parts of ´T_1, ..., T_n´, as well as ´T´ itself; +- if ´T´ is a parameterized type `´S´[´T_1, ..., T_n´]`, the union of the parts of ´S´ and ´T_1, ..., 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, ..., T_n´ and result type ´U´, - the union of the parts of ´T_1, ..., T_n´ and ´U´; +- if ´T´ denotes an implicit conversion to a type with a method with argument types ´T_1, ..., T_n´ and result type ´U´, the union of the parts of ´T_1, ..., T_n´ and ´U´; - the parts of quantified (existential or universal) 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. +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. +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 = @@ -106,23 +82,15 @@ def sum[A](xs: List[A])(implicit m: Monoid[A]): A = else m.add(xs.head, sum(xs.tail)) ``` -The monoid in question is marked as an implicit parameter, and can therefore -be inferred based on the type of the list. -Consider for instance the call `sum(List(1, 2, 3))` -in a context where `stringMonoid` and `intMonoid` -are visible. We know that the formal type parameter `a` of -`sum` needs to be instantiated to `Int`. The only -eligible object which matches the implicit formal parameter type -`Monoid[Int]` is `intMonoid` so this object will -be passed as implicit parameter. +The monoid in question is marked as an implicit parameter, and can therefore be inferred based on the type of the list. +Consider for instance the call `sum(List(1, 2, 3))` in a context where `stringMonoid` and `intMonoid` are visible. +We know that the formal type parameter `a` of `sum` needs to be instantiated to `Int`. +The only eligible object which matches the implicit formal parameter type `Monoid[Int]` is `intMonoid` so this object will be passed as implicit parameter. -This discussion also shows that implicit parameters are inferred after -any type arguments are [inferred](06-expressions.html#local-type-inference). +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. +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]) @@ -136,16 +104,14 @@ Assume in addition a method implicit def int2ordered(x: Int): Ordered[Int] ``` -that injects integers into the `Ordered` class. We can now -define a `sort` method over ordered lists: +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: +We can apply `sort` to a list of lists of integers `yss: List[List[Int]]` as follows: ```scala sort(yss) @@ -157,28 +123,22 @@ The call above will be completed by passing two nested implicit arguments: sort(yss)((xs: List[Int]) => list2ordered[Int](xs)(int2ordered)) ``` -The possibility of passing implicit arguments to implicit arguments -raises the possibility of an infinite recursion. For instance, one -might try to define the following method, which injects _every_ type into the -`Ordered` class: +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: +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 => ... ))) ``` -Such infinite expansions should be detected and reported as errors, however to support the deliberate -implicit construction of recursive values we allow implicit arguments to be marked as by-name. At call -sites recursive uses of implicit values are permitted if they occur in an implicit by-name argument. +Such infinite expansions should be detected and reported as errors, however to support the deliberate implicit construction of recursive values we allow implicit arguments to be marked as by-name. +At call sites recursive uses of implicit values are permitted if they occur in an implicit by-name argument. Consider the following example, @@ -196,8 +156,8 @@ val foo = implicitly[Foo] assert(foo eq foo.next) ``` -As with the `magic` case above this diverges due to the recursive implicit argument `rec` of method -`foo`. If we mark the implicit argument as by-name, +As with the `magic` case above this diverges due to the recursive implicit argument `rec` of method `foo`. +If we mark the implicit argument as by-name, ```scala trait Foo { @@ -215,8 +175,7 @@ assert(foo eq foo.next) the example compiles with the assertion successful. -When compiled, recursive by-name implicit arguments of this sort are extracted out as val members of a -local synthetic object at call sites as follows, +When compiled, recursive by-name implicit arguments of this sort are extracted out as val members of a local synthetic object at call sites as follows, ```scala val foo: Foo = scala.Predef.implicitly[Foo]( @@ -232,46 +191,33 @@ val foo: Foo = scala.Predef.implicitly[Foo]( assert(foo eq foo.next) ``` -Note that the recursive use of `rec$1` occurs within the by-name argument of `foo` and is consequently -deferred. The desugaring matches what a programmer would do to construct such a recursive value -explicitly. - -To prevent infinite expansions, such as the `magic` example above, 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, ´T´ is added to the stack paired with the implicit -definition which produces it, and whether it was required to satisfy a by-name implicit argument or -not. The type is removed from the stack once the search for the implicit argument either definitely -fails or succeeds. Everytime a type is about to be added to the stack, it is checked against -existing entries which were produced by the same implicit definition and then, - -+ if it is equivalent to some type which is already on the stack and there is a by-name argument between - that entry and the top of the stack. In this case the search for that type succeeds immediately and - the implicit argument is compiled as a recursive reference to the found argument. That argument is - added as an entry in the synthesized implicit dictionary if it has not already been added. -+ otherwise if the _core_ of the type _dominates_ the core of a type already on the stack, then the - implicit expansion is said to _diverge_ and the search for that type fails immediately. +Note that the recursive use of `rec$1` occurs within the by-name argument of `foo` and is consequently deferred. +The desugaring matches what a programmer would do to construct such a recursive value explicitly. + +To prevent infinite expansions, such as the `magic` example above, 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, ´T´ is added to the stack paired with the implicit definition which produces it, and whether it was required to satisfy a by-name implicit argument or not. +The type is removed from the stack once the search for the implicit argument either definitely fails or succeeds. +Everytime a type is about to be added to the stack, it is checked against existing entries which were produced by the same implicit definition and then, + ++ if it is equivalent to some type which is already on the stack and there is a by-name argument between that entry and the top of the stack. +In this case the search for that type succeeds immediately and the implicit argument is compiled as a recursive reference to the found argument. +That argument is added as an entry in the synthesized implicit dictionary if it has not already been added. ++ otherwise if the _core_ of the type _dominates_ the core of a type already on the stack, then the implicit expansion is said to _diverge_ and the search for that type fails immediately. + otherwise it is added to the stack paired with the implicit definition which produces it. - Implicit resolution continues with the implicit arguments of that definition (if any). +Implicit resolution continues with the implicit arguments of that definition (if any). -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. +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. -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´ and the _covering sets_ of ´T´ and ´U´ are equal. +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´ and the _covering sets_ of ´T´ and ´U´ are equal. -The set of _top-level type constructors_ ´\mathit{ttcs}(T)´ of a type ´T´ depends on the form of -the type: +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 ... with ´T_n)´` ´~=~ \mathit{ttcs}(T_1) \cup ... \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: +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})´ @@ -295,9 +241,7 @@ the corresponding covering sets are: - ´\mathit{cs}(C)´: List, Tuple2, Int, String ###### 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 +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]]], @@ -305,20 +249,19 @@ List[Int] => Ordered[List[Int]], Int => Ordered[Int] ``` -All types share the common type constructor `scala.Function1`, -but the complexity of each new type is lower than the complexity of the previous types. +All types share the common type constructor `scala.Function1`, but the complexity of 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: +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 +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], @@ -326,47 +269,31 @@ Throwable => Ordered[Throwable], ... ``` -Since the second type in the sequence is equal to the first, the compiler -will issue an error signalling a divergent implicit expansion. +Since the second type in the sequence is equal to the first, the compiler will issue an error signalling a divergent implicit expansion. ## Views -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. +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 its 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). +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 its 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 @@ -376,9 +303,7 @@ Class `scala.Ordered[A]` contains a method def <= [B >: A](that: B)(implicit b2ordered: B => Ordered[B]): Boolean ``` -Assume two lists `xs` and `ys` of type `List[Int]` -and assume that the `list2ordered` and `int2ordered` -methods defined [here](#implicit-parameters) are in scope. +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 @@ -393,10 +318,7 @@ is legal, and is expanded to: (xs => list2ordered(xs)(int2ordered)) ``` -The first application of `list2ordered` converts the list -`xs` to an instance of class `Ordered`, whereas the second -occurrence is part of an implicit parameter passed to the `<=` -method. +The first application of `list2ordered` converts the list `xs` to an instance of class `Ordered`, whereas the second occurrence is part of an implicit parameter passed to the `<=` method. ## Context Bounds and View Bounds @@ -405,20 +327,15 @@ method. {‘<%’ 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 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 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: +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´ = ... @@ -431,14 +348,11 @@ def ´f´[´A´](´\mathit{ps}´)(implicit ´v_1´: ´A´ => ´T_1´, ..., ´v_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_. +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. +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. Evidence parameters are prepended to the existing implicit parameter section, if one exists. @@ -452,8 +366,7 @@ def foo[A: M](implicit b: B): C ``` ###### Example -The `<=` method from the [`Ordered` example](#example-ordered) can be declared -more concisely as follows: +The `<=` method from the [`Ordered` example](#example-ordered) can be declared more concisely as follows: ```scala def <= [B >: A <% Ordered[B]](that: B): Boolean @@ -461,11 +374,9 @@ 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. +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] @@ -474,52 +385,23 @@ 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. +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. +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. +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, ..., 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], ..., M'[U_n]´. -1. If ´T´ is some other class type with type arguments ´U_1, ..., 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], ..., 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 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, ..., 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], ..., M'[U_n]´. +1. If ´T´ is some other class type with type arguments ´U_1, ..., 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], ..., 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 ... 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], ..., 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, ..., 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. +(That is, refinements are never reflected in manifests). +1. If ´T´ is an intersection type `´T_1´ with ... 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], ..., 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, ..., 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/docs/_spec/08-pattern-matching.md b/docs/_spec/08-pattern-matching.md index f7203e831438..45d777f584a0 100644 --- a/docs/_spec/08-pattern-matching.md +++ b/docs/_spec/08-pattern-matching.md @@ -28,30 +28,20 @@ chapter: 8 Patterns ::= Pattern {‘,’ Patterns} ``` -A pattern is built from constants, constructors, variables and type -tests. Pattern matching tests whether a given value (or sequence of values) -has the shape defined by a pattern, and, if it does, binds the -variables in the pattern to the corresponding components of the value -(or sequence of values). The same variable name may not be bound more -than once in a pattern. +A pattern is built from constants, constructors, variables and type tests. +Pattern matching tests whether a given value (or sequence of values) has the shape defined by a pattern, and, if it does, binds the variables in the pattern to the corresponding components of the value (or sequence of values). +The same variable name may not be bound more than once in a pattern. ###### Example Some examples of patterns are: - 1. The pattern `ex: IOException` matches all instances of class - `IOException`, binding variable `ex` to the instance. - 1. The pattern `Some(x)` matches values of the form `Some(´v´)`, - binding `x` to the argument value ´v´ of the `Some` constructor. - 1. The pattern `(x, _)` matches pairs of values, binding `x` to - the first component of the pair. The second component is matched - with a wildcard pattern. - 1. The pattern `x :: y :: xs` matches lists of length ´\geq 2´, - binding `x` to the list's first element, `y` to the list's - second element, and `xs` to the remainder. + 1. The pattern `ex: IOException` matches all instances of class `IOException`, binding variable `ex` to the instance. + 1. The pattern `Some(x)` matches values of the form `Some(´v´)`, binding `x` to the argument value ´v´ of the `Some` constructor. + 1. The pattern `(x, _)` matches pairs of values, binding `x` to the first component of the pair. The second component is matched with a wildcard pattern. + 1. The pattern `x :: y :: xs` matches lists of length ´\geq 2´, binding `x` to the list's first element, `y` to the list's second element, and `xs` to the remainder. 1. The pattern `1 | 2 | 3` matches the integers between 1 and 3. -Pattern matching is always done in a context which supplies an -expected type of the pattern. We distinguish the following kinds of -patterns. +Pattern matching is always done in a context which supplies an expected type of the pattern. +We distinguish the following kinds of patterns. ### Variable Patterns @@ -60,11 +50,10 @@ patterns. | varid ``` -A _variable pattern_ ´x´ is a simple identifier which starts with a -lower case letter. It matches any value, and binds the variable name -to that value. The type of ´x´ is the expected type of the pattern as -given from outside. A special case is the wild-card pattern `_` -which is treated as if it was a fresh variable on each occurrence. +A _variable pattern_ ´x´ is a simple identifier which starts with a lower case letter. +It matches any value, and binds the variable name to that value. +The type of ´x´ is the expected type of the pattern as given from outside. +A special case is the wild-card pattern `_` which is treated as if it was a fresh variable on each occurrence. ### Typed Patterns @@ -73,12 +62,9 @@ which is treated as if it was a fresh variable on each occurrence. | ‘_’ ‘:’ TypePat ``` -A _typed pattern_ ´x: T´ consists of a pattern variable ´x´ and a -type pattern ´T´. The type of ´x´ is the type pattern ´T´, where -each type variable and wildcard is replaced by a fresh, unknown type. -This pattern matches any value matched by the [type pattern](#type-patterns) -´T´; it binds the variable name to -that value. +A _typed pattern_ ´x: T´ consists of a pattern variable ´x´ and a type pattern ´T´. +The type of ´x´ is the type pattern ´T´, where each type variable and wildcard is replaced by a fresh, unknown type. +This pattern matches any value matched by the [type pattern](#type-patterns) ´T´; it binds the variable name to that value. ### Pattern Binders @@ -86,11 +72,9 @@ that value. Pattern2 ::= varid ‘@’ Pattern3 ``` -A _pattern binder_ `´x´@´p´` consists of a pattern variable ´x´ and a -pattern ´p´. The type of the variable ´x´ is the static type ´T´ implied -by the pattern ´p´. -This pattern matches any value ´v´ matched by the pattern ´p´, -and it binds the variable name to that value. +A _pattern binder_ `´x´@´p´` consists of a pattern variable ´x´ and a pattern ´p´. +The type of the variable ´x´ is the static type ´T´ implied by the pattern ´p´. +This pattern matches any value ´v´ matched by the pattern ´p´, and it binds the variable name to that value. A pattern ´p´ _implies_ a type ´T´ if the pattern matches only values of the type ´T´. @@ -100,9 +84,8 @@ A pattern ´p´ _implies_ a type ´T´ if the pattern matches only values of the SimplePattern ::= Literal ``` -A _literal pattern_ ´L´ matches any value that is equal (in terms of -`==`) to the literal ´L´. The type of ´L´ must conform to the -expected type of the pattern. +A _literal pattern_ ´L´ matches any value that is equal (in terms of `==`) to the literal ´L´. +The type of ´L´ must conform to the expected type of the pattern. ### Interpolated string patterns @@ -110,9 +93,8 @@ expected type of the pattern. Literal ::= interpolatedString ``` -The expansion of interpolated string literals in patterns is the same as -in expressions. If it occurs in a pattern, a interpolated string literal -of either of the forms +The expansion of interpolated string literals in patterns is the same as in expressions. +If it occurs in a pattern, a interpolated string literal of either of the forms ``` id"text0{ pat1 }text1 ... { patn }textn" id"""text0{ pat1 }text1 ... { patn }textn""" @@ -121,13 +103,10 @@ is equivalent to: ``` StringContext("""text0""", ..., """textn""").id(pat1, ..., patn) ``` -You could define your own `StringContext` to shadow the default one that's -in the `scala` package. +You could define your own `StringContext` to shadow the default one that's in the `scala` package. -This expansion is well-typed if the member `id` evaluates to an extractor -object. If the extractor object has `apply` as well as `unapply` or -`unapplySeq` methods, processed strings can be used as either expressions -or patterns. +This expansion is well-typed if the member `id` evaluates to an extractor object. +If the extractor object has `apply` as well as `unapply` or `unapplySeq` methods, processed strings can be used as either expressions or patterns. Taking XML as an example ```scala @@ -159,14 +138,11 @@ where linktext is a variable bound by the pattern. ``` A _stable identifier pattern_ is a [stable identifier](03-types.html#paths) ´r´. -The type of ´r´ must conform to the expected -type of the pattern. The pattern matches any value ´v´ such that -`´r´ == ´v´` (see [here](12-the-scala-standard-library.html#root-classes)). +The type of ´r´ must conform to the expected type of the pattern. +The pattern matches any value ´v´ such that `´r´ == ´v´` (see [here](12-the-scala-standard-library.html#root-classes)). -To resolve the syntactic overlap with a variable pattern, a -stable identifier pattern may not be a simple name starting with a lower-case -letter. However, it is possible to enclose such a variable name in -backquotes; then it is treated as a stable identifier pattern. +To resolve the syntactic overlap with a variable pattern, a stable identifier pattern may not be a simple name starting with a lower-case letter. +However, it is possible to enclose such a variable name in backquotes; then it is treated as a stable identifier pattern. ###### Example Consider the following class definition: @@ -185,8 +161,7 @@ class C { c => } ``` -Here, the first three patterns are stable identifier patterns, while the last -one is a variable pattern. +Here, the first three patterns are stable identifier patterns, while the last one is a variable pattern. ### Constructor Patterns @@ -194,25 +169,15 @@ one is a variable pattern. SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ ``` -A _constructor pattern_ is of the form ´c(p_1, ..., p_n)´ where ´n -\geq 0´. It consists of a stable identifier ´c´, followed by element -patterns ´p_1, ..., p_n´. The constructor ´c´ is a simple or -qualified name which denotes a [case class](05-classes-and-objects.html#case-classes). -If the case class is monomorphic, then it -must conform to the expected type of the pattern, and the formal -parameter types of ´x´'s [primary constructor](05-classes-and-objects.html#class-definitions) -are taken as the expected types of the element patterns ´p_1, ..., -p_n´. If the case class is polymorphic, then its type parameters are -instantiated so that the instantiation of ´c´ conforms to the expected -type of the pattern. The instantiated formal parameter types of ´c´'s -primary constructor are then taken as the expected types of the -component patterns ´p_1, ..., p_n´. The pattern matches all -objects created from constructor invocations ´c(v_1, ..., v_n)´ -where each element pattern ´p_i´ matches the corresponding value -´v_i´. - -A special case arises when ´c´'s formal parameter types end in a -repeated parameter. This is further discussed [here](#pattern-sequences). +A _constructor pattern_ is of the form ´c(p_1, ..., p_n)´ where ´n \geq 0´. It consists of a stable identifier ´c´, followed by element patterns ´p_1, ..., p_n´. +The constructor ´c´ is a simple or qualified name which denotes a [case class](05-classes-and-objects.html#case-classes). +If the case class is monomorphic, then it must conform to the expected type of the pattern, and the formal parameter types of ´x´'s [primary constructor](05-classes-and-objects.html#class-definitions) are taken as the expected types of the element patterns ´p_1, ..., p_n´. +If the case class is polymorphic, then its type parameters are instantiated so that the instantiation of ´c´ conforms to the expected type of the pattern. +The instantiated formal parameter types of ´c´'s primary constructor are then taken as the expected types of the component patterns ´p_1, ..., p_n´. +The pattern matches all objects created from constructor invocations ´c(v_1, ..., v_n)´ where each element pattern ´p_i´ matches the corresponding value ´v_i´. + +A special case arises when ´c´'s formal parameter types end in a repeated parameter. +This is further discussed [here](#pattern-sequences). ### Tuple Patterns @@ -220,10 +185,7 @@ repeated parameter. This is further discussed [here](#pattern-sequences). SimplePattern ::= ‘(’ [Patterns] ‘)’ ``` -A _tuple pattern_ `(´p_1´, ..., ´p_n´)` is an alias -for the constructor pattern `scala.Tuple´n´(´p_1´, ..., ´p_n´)`, -where ´n \geq 2´. The empty tuple -`()` is the unique value of type `scala.Unit`. +A _tuple pattern_ `(´p_1´, ..., ´p_n´)` is an alias for the constructor pattern `scala.Tuple´n´(´p_1´, ..., ´p_n´)`, where ´n \geq 2´. The empty tuple `()` is the unique value of type `scala.Unit`. ### Extractor Patterns @@ -231,44 +193,26 @@ where ´n \geq 2´. The empty tuple SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ ``` -An _extractor pattern_ ´x(p_1, ..., p_n)´ where ´n \geq 0´ is of -the same syntactic form as a constructor pattern. However, instead of -a case class, the stable identifier ´x´ denotes an object which has a -member method named `unapply` or `unapplySeq` that matches -the pattern. - -An extractor pattern cannot match the value `null`. The implementation -ensures that the `unapply`/`unapplySeq` method is not applied to `null`. - -A type is said to be an _extractor type_ for some type `T` if it has a -method `get` with return type `T`, and a method `isEmpty` with a return type -that conforms to `Boolean`. `Option[T]` is an extractor type for type `T`. - -An `unapply` method in an object ´x´ _matches_ the pattern -´x(p_1, ..., p_n)´ if it has a single parameter (and, optionally, an -implicit parameter list) and one of the following applies: - -* ´n=0´ and `unapply`'s result type conforms to `Boolean`. In this case - the extractor pattern matches all values ´v´ for which - `´x´.unapply(´v´)` yields `true`. -* ´n=1´ and `unapply`'s result type is an extractor type for some - type ´T´. In this case, the (only) argument pattern ´p_1´ is typed in - turn with expected type ´T´. The extractor pattern matches then all - values ´v´ for which `´x´.unapply(´v´)` yields a value ´u´ for which `´u´.isEmpty` yields - `false`, `´u´.get` yields a value ´v_1´, and ´p_1´ matches ´v_1´. -* ´n>1´ and `unapply`'s result type is - an extractor type for some type ´T´ with members ´\_1, ..., \_n´ returning - types ´T_1, ..., T_n´. In this case, the argument patterns ´p_1 - , ..., p_n´ are typed in turn with expected types ´T_1 , ..., - T_n´. The extractor pattern matches then all values ´v´ for which - `´x´.unapply(´v´)` yields a value ´u´ for which - `´u´.isEmpty` yields `false`, `´u´.get` yields some value ´t´, and each pattern - ´p_i´ matches the corresponding value ´t._1´ from - ´t._1, ..., t._n´. - -An `unapplySeq` method in an object ´x´ matches the pattern -´x(q_1, ..., q_m, p_1, ..., p_n)´ if it takes exactly one argument -and its result type is of the form `Option[(´T_1, ..., T_m´, Seq[S])]` (if `m = 0`, the type `Option[Seq[S]]` is also accepted). +An _extractor pattern_ ´x(p_1, ..., p_n)´ where ´n \geq 0´ is of the same syntactic form as a constructor pattern. +However, instead of a case class, the stable identifier ´x´ denotes an object which has a member method named `unapply` or `unapplySeq` that matches the pattern. + +An extractor pattern cannot match the value `null`. The implementation ensures that the `unapply`/`unapplySeq` method is not applied to `null`. + +A type is said to be an _extractor type_ for some type `T` if it has a method `get` with return type `T`, and a method `isEmpty` with a return type that conforms to `Boolean`. +`Option[T]` is an extractor type for type `T`. + +An `unapply` method in an object ´x´ _matches_ the pattern ´x(p_1, ..., p_n)´ if it has a single parameter (and, optionally, an implicit parameter list) and one of the following applies: + +* ´n=0´ and `unapply`'s result type conforms to `Boolean`. +In this case the extractor pattern matches all values ´v´ for which `´x´.unapply(´v´)` yields `true`. +* ´n=1´ and `unapply`'s result type is an extractor type for some type ´T´. +In this case, the (only) argument pattern ´p_1´ is typed in turn with expected type ´T´. +The extractor pattern matches then all values ´v´ for which `´x´.unapply(´v´)` yields a value ´u´ for which `´u´.isEmpty` yields `false`, `´u´.get` yields a value ´v_1´, and ´p_1´ matches ´v_1´. +* ´n>1´ and `unapply`'s result type is an extractor type for some type ´T´ with members ´\_1, ..., \_n´ returning types ´T_1, ..., T_n´. +In this case, the argument patterns ´p_1, ..., p_n´ are typed in turn with expected types ´T_1 , ..., T_n´. +The extractor pattern matches then all values ´v´ for which `´x´.unapply(´v´)` yields a value ´u´ for which `´u´.isEmpty` yields `false`, `´u´.get` yields some value ´t´, and each pattern ´p_i´ matches the corresponding value ´t._1´ from ´t._1, ..., t._n´. + +An `unapplySeq` method in an object ´x´ matches the pattern ´x(q_1, ..., q_m, p_1, ..., p_n)´ if it takes exactly one argument and its result type is of the form `Option[(´T_1, ..., T_m´, Seq[S])]` (if `m = 0`, the type `Option[Seq[S]]` is also accepted). This case is further discussed [below](#pattern-sequences). ###### Example 1 @@ -282,8 +226,7 @@ object Pair { } ``` -This means that the name `Pair` can be used in place of `Tuple2` for tuple -formation as well as for deconstruction of tuples in patterns. +This means that the name `Pair` can be used in place of `Tuple2` for tuple formation as well as for deconstruction of tuples in patterns. Hence, the following is possible: ```scala @@ -306,12 +249,9 @@ class NameBased[A, B](a: A, b: B) { } ``` -Then `NameBased` is an extractor type for `NameBased` itself, since it has a -member `isEmpty` returning a value of type Boolean, and it has a member `get` -returning a value of type `NameBased`. +Then `NameBased` is an extractor type for `NameBased` itself, since it has a member `isEmpty` returning a value of type Boolean, and it has a member `get` returning a value of type `NameBased`. -Since it also has members `_1` and `_2`, it can be used in an extractor pattern -with n = 2 as follows: +Since it also has members `_1` and `_2`, it can be used in an extractor pattern with n = 2 as follows: ```scala object Extractor { @@ -332,18 +272,12 @@ SimplePattern ::= StableId ‘(’ [Patterns ‘,’] [varid ‘@’] ‘_’ A _pattern sequence_ ´p_1, ..., p_n´ appears in two contexts. First, in a constructor pattern ´c(q_1, ..., q_m, p_1, ..., p_n)´, where ´c´ is a case class which has ´m+1´ primary constructor parameters, ending in a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type `S*`. -Second, in an extractor pattern ´x(q_1, ..., q_m, p_1, ..., p_n)´ if the extractor object ´x´ does not have an `unapply` method, -but it does define an `unapplySeq` method with a result type that is an extractor type for type `(T_1, ... , T_m, Seq[S])` (if `m = 0`, an extractor type for the type `Seq[S]` is also accepted). The expected type for the patterns ´p_i´ is ´S´. +Second, in an extractor pattern ´x(q_1, ..., q_m, p_1, ..., p_n)´ if the extractor object ´x´ does not have an `unapply` method, but it does define an `unapplySeq` method with a result type that is an extractor type for type `(T_1, ... , T_m, Seq[S])` (if `m = 0`, an extractor type for the type `Seq[S]` is also accepted). The expected type for the patterns ´p_i´ is ´S´. The last pattern in a pattern sequence may be a _sequence wildcard_ `_*`. -Each element pattern ´p_i´ is type-checked with -´S´ as expected type, unless it is a sequence wildcard. If a final -sequence wildcard is present, the pattern matches all values ´v´ that -are sequences which start with elements matching patterns -´p_1, ..., p_{n-1}´. If no final sequence wildcard is given, the -pattern matches all values ´v´ that are sequences of -length ´n´ which consist of elements matching patterns ´p_1 , ..., -p_n´. +Each element pattern ´p_i´ is type-checked with ´S´ as expected type, unless it is a sequence wildcard. +If a final sequence wildcard is present, the pattern matches all values ´v´ that are sequences which start with elements matching patterns ´p_1, ..., p_{n-1}´. +If no final sequence wildcard is given, the pattern matches all values ´v´ that are sequences of length ´n´ which consist of elements matching patterns ´p_1, ..., p_n´. ### Infix Operation Patterns @@ -352,13 +286,10 @@ p_n´. ``` An _infix operation pattern_ ´p;\mathit{op};q´ is a shorthand for the -constructor or extractor pattern ´\mathit{op}(p, q)´. The precedence and -associativity of operators in patterns is the same as in -[expressions](06-expressions.html#prefix,-infix,-and-postfix-operations). +constructor or extractor pattern ´\mathit{op}(p, q)´. +The precedence and associativity of operators in patterns is the same as in [expressions](06-expressions.html#prefix,-infix,-and-postfix-operations). -An infix operation pattern ´p;\mathit{op};(q_1, ..., q_n)´ is a -shorthand for the constructor or extractor pattern ´\mathit{op}(p, q_1 -, ..., q_n)´. +An infix operation pattern ´p;\mathit{op};(q_1, ..., q_n)´ is a shorthand for the constructor or extractor pattern ´\mathit{op}(p, q_1, ..., q_n)´. ### Pattern Alternatives @@ -366,11 +297,10 @@ shorthand for the constructor or extractor pattern ´\mathit{op}(p, q_1 Pattern ::= Pattern1 { ‘|’ Pattern1 } ``` -A _pattern alternative_ `´p_1´ | ... | ´p_n´` -consists of a number of alternative patterns ´p_i´. All alternative -patterns are type checked with the expected type of the pattern. They -may not bind variables other than wildcards. The alternative pattern -matches a value ´v´ if at least one its alternatives matches ´v´. +A _pattern alternative_ `´p_1´ | ... | ´p_n´` consists of a number of alternative patterns ´p_i´. +All alternative patterns are type checked with the expected type of the pattern. +They may not bind variables other than wildcards. +The alternative pattern matches a value ´v´ if at least one its alternatives matches ´v´. ### XML Patterns @@ -380,17 +310,10 @@ XML patterns are treated [here](10-xml-expressions-and-patterns.html#xml-pattern Regular expression patterns have been discontinued in Scala from version 2.0. -Later version of Scala provide a much simplified version of regular -expression patterns that cover most scenarios of non-text sequence -processing. A _sequence pattern_ is a pattern that stands in a -position where either (1) a pattern of a type `T` which is -conforming to -`Seq[A]` for some `A` is expected, or (2) a case -class constructor that has an iterated formal parameter -`A*`. A wildcard star pattern `_*` in the -rightmost position stands for arbitrary long sequences. It can be -bound to variables using `@`, as usual, in which case the variable will have the -type `Seq[A]`. +Later version of Scala provide a much simplified version of regular expression patterns that cover most scenarios of non-text sequence processing. +A _sequence pattern_ is a pattern that stands in a position where either (1) a pattern of a type `T` which is conforming to `Seq[A]` for some `A` is expected, or (2) a case class constructor that has an iterated formal parameter `A*`. +A wildcard star pattern `_*` in the rightmost position stands for arbitrary long sequences. +It can be bound to variables using `@`, as usual, in which case the variable will have the type `Seq[A]`. ### Irrefutable Patterns @@ -398,16 +321,10 @@ A pattern ´p´ is _irrefutable_ for a type ´T´, if one of the following appli 1. ´p´ is a variable pattern, 1. ´p´ is a typed pattern ´x: T'´, and ´T <: T'´, -1. ´p´ is a constructor pattern ´c(p_1, ..., p_n)´, the type ´T´ - is an instance of class ´c´, the [primary constructor](05-classes-and-objects.html#class-definitions) - of type ´T´ has argument types ´T_1, ..., T_n´, and each ´p_i´ is - irrefutable for ´T_i´. -1. ´p´ is an extractor pattern for which the extractor type is `Some[´T´]` for - some type ´T´ -1. ´p´ is an extractor pattern for which the extractor types `isEmpty` method - is the singleton type `false` -1. ´p´ is an extractor pattern for which the return type is the singleton type - `true` +1. ´p´ is a constructor pattern ´c(p_1, ..., p_n)´, the type ´T´ is an instance of class ´c´, the [primary constructor](05-classes-and-objects.html#class-definitions) of type ´T´ has argument types ´T_1, ..., T_n´, and each ´p_i´ is irrefutable for ´T_i´. +1. ´p´ is an extractor pattern for which the extractor type is `Some[´T´]` for some type ´T´ +1. ´p´ is an extractor pattern for which the extractor types `isEmpty` method is the singleton type `false` +1. ´p´ is an extractor pattern for which the return type is the singleton type `true` ## Type Patterns @@ -418,70 +335,50 @@ A pattern ´p´ is _irrefutable_ for a type ´T´, if one of the following appli Type patterns consist of types, type variables, and wildcards. A type pattern ´T´ is of one of the following forms: -* A reference to a class ´C´, ´p.C´, or `´T´#´C´`. This - type pattern matches any non-null instance of the given class. - Note that the prefix of the class, if it exists, is relevant for determining - class instances. For instance, the pattern ´p.C´ matches only - instances of classes ´C´ which were created with the path ´p´ as - prefix. This also applies to prefixes which are not given syntactically. - For example, if ´C´ refers to a class defined in the nearest enclosing - class and is thus equivalent to ´this.C´, it is considered to have a prefix. - - The bottom types `scala.Nothing` and `scala.Null` cannot - be used as type patterns, because they would match nothing in any case. - -* A singleton type `´p´.type`. This type pattern matches only the value - denoted by the path ´p´ (the `eq` method is used to compare the matched value - to ´p´). - -* A literal type `´lit´`. This type pattern matches only the value - denoted by the literal ´lit´ (the `==` method is used to compare the matched - value to ´lit´). - -* A compound type pattern `´T_1´ with ... with ´T_n´` where each ´T_i´ is a - type pattern. This type pattern matches all values that are matched by each of - the type patterns ´T_i´. - -* A parameterized type pattern ´T[a_1, ..., a_n]´, where the ´a_i´ - are type variable patterns or wildcards `_`. - This type pattern matches all values which match ´T´ for - some arbitrary instantiation of the type variables and wildcards. The - bounds or alias type of these type variable are determined as - described [here](#type-parameter-inference-in-patterns). - -* A parameterized type pattern `scala.Array´[T_1]´`, where - ´T_1´ is a type pattern. This type pattern matches any non-null instance - of type `scala.Array´[U_1]´`, where ´U_1´ is a type matched by ´T_1´. - -Types which are not of one of the forms described above are also -accepted as type patterns. However, such type patterns will be translated to their -[erasure](03-types.html#type-erasure). The Scala -compiler will issue an "unchecked" warning for these patterns to -flag the possible loss of type-safety. - -A _type variable pattern_ is a simple identifier which starts with -a lower case letter. +* A reference to a class ´C´, ´p.C´, or `´T´#´C´`. +This type pattern matches any non-null instance of the given class. +Note that the prefix of the class, if it exists, is relevant for determining class instances. +For instance, the pattern ´p.C´ matches only instances of classes ´C´ which were created with the path ´p´ as prefix. +This also applies to prefixes which are not given syntactically. +For example, if ´C´ refers to a class defined in the nearest enclosing class and is thus equivalent to ´this.C´, it is considered to have a prefix. + +The bottom types `scala.Nothing` and `scala.Null` cannot be used as type patterns, because they would match nothing in any case. + +* A singleton type `´p´.type`. This type pattern matches only the value denoted by the path ´p´ (the `eq` method is used to compare the matched value to ´p´). + +* A literal type `´lit´`. This type pattern matches only the value denoted by the literal ´lit´ (the `==` method is used to compare the matched value to ´lit´). + +* A compound type pattern `´T_1´ with ... with ´T_n´` where each ´T_i´ is a type pattern. +This type pattern matches all values that are matched by each of the type patterns ´T_i´. + +* A parameterized type pattern ´T[a_1, ..., a_n]´, where the ´a_i´ are type variable patterns or wildcards `_`. +This type pattern matches all values which match ´T´ for some arbitrary instantiation of the type variables and wildcards. +The bounds or alias type of these type variable are determined as described [here](#type-parameter-inference-in-patterns). + +* A parameterized type pattern `scala.Array´[T_1]´`, where ´T_1´ is a type pattern. +This type pattern matches any non-null instance of type `scala.Array´[U_1]´`, where ´U_1´ is a type matched by ´T_1´. + +Types which are not of one of the forms described above are also accepted as type patterns. +However, such type patterns will be translated to their [erasure](03-types.html#type-erasure). +The Scala compiler will issue an "unchecked" warning for these patterns to flag the possible loss of type-safety. + +A _type variable pattern_ is a simple identifier which starts with a lower case letter. ## Type Parameter Inference in Patterns -Type parameter inference is the process of finding bounds for the -bound type variables in a typed pattern or constructor -pattern. Inference takes into account the expected type of the -pattern. +Type parameter inference is the process of finding bounds for the 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 -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, ..., a_n´ be -the type variables in ´T´. These type variables are considered bound -in the pattern. Let the expected type of the pattern be ´\mathit{pt}´. +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, ..., a_n´ be the type variables in ´T´. +These type variables are considered bound in the pattern. +Let the expected type of the pattern be ´\mathit{pt}´. -Type parameter inference constructs first a set of subtype constraints over -the type variables ´a_i´. The initial constraints set ´\mathcal{C}\_0´ reflects -just the bounds of these type variables. That is, assuming ´T´ has -bound type variables ´a_1, ..., a_n´ which correspond to class -type parameters ´a_1', ..., a_n'´ with lower bounds ´L_1, ..., L_n´ -and upper bounds ´U_1, ..., U_n´, ´\mathcal{C}_0´ contains the constraints +Type parameter inference constructs first a set of subtype constraints over the type variables ´a_i´. +The initial constraints set ´\mathcal{C}\_0´ reflects just the bounds of these type variables. +That is, assuming ´T´ has bound type variables ´a_1, ..., a_n´ which correspond to class type parameters ´a_1', ..., a_n'´ with lower bounds ´L_1, ..., L_n´ and upper bounds ´U_1, ..., U_n´, ´\mathcal{C}_0´ contains the constraints $$ \begin{cases} @@ -492,54 +389,35 @@ $$ where ´\sigma´ is the substitution ´[a_1' := a_1, ..., a_n' :=a_n]´. -The set ´\mathcal{C}_0´ is then augmented by further subtype constraints. There are two -cases. +The set ´\mathcal{C}_0´ is then augmented by further subtype constraints. +There are two cases. ###### Case 1 -If there exists a substitution ´\sigma´ over the type variables ´a_i, ..., a_n´ such that ´\sigma T´ conforms to ´\mathit{pt}´, one determines the weakest subtype constraints -´\mathcal{C}\_1´ over the type variables ´a_1, ..., a_n´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}_1´ implies that ´T´ conforms to ´\mathit{pt}´. +If there exists a substitution ´\sigma´ over the type variables ´a_i, ..., a_n´ such that ´\sigma T´ conforms to ´\mathit{pt}´, one determines the weakest subtype constraints ´\mathcal{C}\_1´ over the type variables ´a_1, ..., a_n´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}_1´ implies that ´T´ conforms to ´\mathit{pt}´. ###### Case 2 -Otherwise, if ´T´ can not be made to conform to ´\mathit{pt}´ by -instantiating its type variables, one determines all type variables in -´\mathit{pt}´ which are defined as type parameters of a method enclosing -the pattern. Let the set of such type parameters be ´b_1 , ..., -b_m´. Let ´\mathcal{C}\_0'´ be the subtype constraints reflecting the bounds of the -type variables ´b_i´. If ´T´ denotes an instance type of a final -class, let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type -variables ´a_1, ..., a_n´ and ´b_1, ..., b_m´ such that -´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that ´T´ conforms to -´\mathit{pt}´. If ´T´ does not denote an instance type of a final class, -let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type variables -´a_1, ..., a_n´ and ´b_1, ..., b_m´ such that ´\mathcal{C}\_0 \wedge -\mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that it is possible to construct a type -´T'´ which conforms to both ´T´ and ´\mathit{pt}´. It is a static error if -there is no satisfiable set of constraints ´\mathcal{C}\_2´ with this property. - -The final step consists in choosing type bounds for the type -variables which imply the established constraint system. The process -is different for the two cases above. +Otherwise, if ´T´ can not be made to conform to ´\mathit{pt}´ by instantiating its type variables, one determines all type variables in ´\mathit{pt}´ which are defined as type parameters of a method enclosing the pattern. +Let the set of such type parameters be ´b_1 , ..., b_m´. +Let ´\mathcal{C}\_0'´ be the subtype constraints reflecting the bounds of the type variables ´b_i´. +If ´T´ denotes an instance type of a final class, let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type variables ´a_1, ..., a_n´ and ´b_1, ..., b_m´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that ´T´ conforms to ´\mathit{pt}´. +If ´T´ does not denote an instance type of a final class, let ´\mathcal{C}\_2´ be the weakest set of subtype constraints over the type variables ´a_1, ..., a_n´ and ´b_1, ..., b_m´ such that ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}\_2´ implies that it is possible to construct a type ´T'´ which conforms to both ´T´ and ´\mathit{pt}´. +It is a static error if there is no satisfiable set of constraints ´\mathcal{C}\_2´ with this property. + +The final step consists in choosing type bounds for the type variables which imply the established constraint system. +The process is different for the two cases above. ###### Case 1 We take ´a_i >: L_i <: U_i´ where each ´L_i´ is minimal and each ´U_i´ is maximal wrt ´<:´ such that ´a_i >: L_i <: U_i´ for ´i = 1, ..., n´ implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_1´. ###### Case 2 -We take ´a_i >: L_i <: U_i´ and ´b\_i >: L_i' <: U_i' ´ where each ´L_i´ -and ´L_j'´ is minimal and each ´U_i´ and ´U_j'´ is maximal such that -´a_i >: L_i <: U_i´ for ´i = 1, ..., n´ and -´b_j >: L_j' <: U_j'´ for ´j = 1, ..., m´ -implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}_2´. +We take ´a_i >: L_i <: U_i´ and ´b\_i >: L_i' <: U_i' ´ where each ´L_i´ and ´L_j'´ is minimal and each ´U_i´ and ´U_j'´ is maximal such that ´a_i >: L_i <: U_i´ for ´i = 1, ..., n´ and ´b_j >: L_j' <: U_j'´ for ´j = 1, ..., m´ implies ´\mathcal{C}\_0 \wedge \mathcal{C}\_0' \wedge \mathcal{C}_2´. -In both cases, local type inference is permitted to limit the -complexity of inferred bounds. Minimality and maximality of types have -to be understood relative to the set of types of acceptable -complexity. +In both cases, local type inference is permitted to limit the 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 -Assume a constructor pattern ´C(p_1, ..., p_n)´ where class ´C´ -has type parameters ´a_1, ..., a_n´. These type parameters -are inferred in the same way as for the typed pattern -`(_: ´C[a_1, ..., a_n]´)`. +Assume a constructor pattern ´C(p_1, ..., p_n)´ where class ´C´ has type parameters ´a_1, ..., a_n´. +These type parameters are inferred in the same way as for the typed pattern `(_: ´C[a_1, ..., a_n]´)`. ###### Example Consider the program fragment: @@ -551,12 +429,11 @@ x match { } ``` -Here, the type pattern `List[a]` is matched against the -expected type `Any`. The pattern binds the type variable -`a`. Since `List[a]` conforms to `Any` -for every type argument, there are no constraints on `a`. -Hence, `a` is introduced as an abstract type with no -bounds. The scope of `a` is right-hand side of its case clause. +Here, the type pattern `List[a]` is matched against the expected type `Any`. +The pattern binds the type variable `a`. +Since `List[a]` conforms to `Any` for every type argument, there are no constraints on `a`. +Hence, `a` is introduced as an abstract type with no bounds. +The scope of `a` is right-hand side of its case clause. On the other hand, if `x` is declared as @@ -564,11 +441,8 @@ On the other hand, if `x` is declared as val x: List[List[String]], ``` -this generates the constraint -`List[a] <: List[List[String]]`, which simplifies to -`a <: List[String]`, because `List` is covariant. Hence, -`a` is introduced with upper bound -`List[String]`. +this generates the constraint `List[a] <: List[List[String]]`, which simplifies to `a <: List[String]`, because `List` is covariant. +Hence, `a` is introduced with upper bound `List[String]`. ###### Example Consider the program fragment: @@ -580,16 +454,10 @@ x match { } ``` -Scala does not maintain information about type arguments at run-time, -so there is no way to check that `x` is a list of strings. -Instead, the Scala compiler will [erase](03-types.html#type-erasure) the -pattern to `List[_]`; that is, it will only test whether the -top-level runtime-class of the value `x` conforms to -`List`, and the pattern match will succeed if it does. This -might lead to a class cast exception later on, in the case where the -list `x` contains elements other than strings. The Scala -compiler will flag this potential loss of type-safety with an -"unchecked" warning message. +Scala does not maintain information about type arguments at run-time, so there is no way to check that `x` is a list of strings. +Instead, the Scala compiler will [erase](03-types.html#type-erasure) the pattern to `List[_]`; that is, it will only test whether the top-level runtime-class of the value `x` conforms to `List`, and the pattern match will succeed if it does. +This might lead to a class cast exception later on, in the case where the list `x` contains elements other than strings. +The Scala compiler will flag this potential loss of type-safety with an "unchecked" warning message. ###### Example Consider the program fragment @@ -602,17 +470,11 @@ def f[B](t: Term[B]): B = t match { } ``` -The expected type of the pattern `y: Number` is -`Term[B]`. The type `Number` does not conform to -`Term[B]`; hence Case 2 of the rules above -applies. This means that `B` is treated as another type -variable for which subtype constraints are inferred. In our case the -applicable constraint is `Number <: Term[B]`, which -entails `B = Int`. Hence, `B` is treated in -the case clause as an abstract type with lower and upper bound -`Int`. Therefore, the right hand side of the case clause, -`y.n`, of type `Int`, is found to conform to the -function's declared result type, `Number`. +The expected type of the pattern `y: Number` is `Term[B]`. +The type `Number` does not conform to `Term[B]`; hence Case 2 of the rules above applies. +This means that `B` is treated as another type variable for which subtype constraints are inferred. +In our case the applicable constraint is `Number <: Term[B]`, which entails `B = Int`. Hence, `B` is treated in the case clause as an abstract type with lower and upper bound `Int`. +Therefore, the right hand side of the case clause, `y.n`, of type `Int`, is found to conform to the function's declared result type, `Number`. ## Pattern Matching Expressions @@ -628,70 +490,46 @@ A _pattern matching expression_ e match { case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` -consists of a selector expression ´e´ and a number ´n > 0´ of -cases. Each case consists of a (possibly guarded) pattern ´p_i´ and a -block ´b_i´. Each ´p_i´ might be complemented by a guard -`if ´e´` where ´e´ is a boolean expression. -The scope of the pattern -variables in ´p_i´ comprises the pattern's guard and the corresponding block ´b_i´. - -Let ´T´ be the type of the selector expression ´e´ and let ´a_1 -, ..., a_m´ be the type parameters of all methods enclosing -the pattern matching expression. For every ´a_i´, let ´L_i´ be its -lower bound and ´U_i´ be its higher bound. Every pattern ´p \in \{p_1,, ..., p_n\}´ -can be typed in two ways. First, it is attempted -to type ´p´ with ´T´ as its expected type. If this fails, ´p´ is -instead typed with a modified expected type ´T'´ which results from -´T´ by replacing every occurrence of a type parameter ´a_i´ by -*undefined*. If this second step fails also, a compile-time -error results. If the second step succeeds, let ´T_p´ be the type of -pattern ´p´ seen as an expression. One then determines minimal bounds -´L_11, ..., L_m'´ and maximal bounds ´U_1', ..., U_m'´ such -that for all ´i´, ´L_i <: L_i'´ and ´U_i' <: U_i´ and the following -constraint system is satisfied: +consists of a selector expression ´e´ and a number ´n > 0´ of cases. +Each case consists of a (possibly guarded) pattern ´p_i´ and a block ´b_i´. +Each ´p_i´ might be complemented by a guard `if ´e´` where ´e´ is a boolean expression. +The scope of the pattern variables in ´p_i´ comprises the pattern's guard and the corresponding block ´b_i´. + +Let ´T´ be the type of the selector expression ´e´ and let ´a_1, ..., a_m´ be the type parameters of all methods enclosing the pattern matching expression. +For every ´a_i´, let ´L_i´ be its lower bound and ´U_i´ be its higher bound. +Every pattern ´p \in \{p_1,, ..., p_n\}´ can be typed in two ways. +First, it is attempted to type ´p´ with ´T´ as its expected type. +If this fails, ´p´ is instead typed with a modified expected type ´T'´ which results from ´T´ by replacing every occurrence of a type parameter ´a_i´ by +*undefined*. +If this second step fails also, a compile-time error results. +If the second step succeeds, let ´T_p´ be the type of pattern ´p´ seen as an expression. +One then determines minimal bounds ´L_11, ..., L_m'´ and maximal bounds ´U_1', ..., U_m'´ such that for all ´i´, ´L_i <: L_i'´ and ´U_i' <: U_i´ and the following constraint system is satisfied: $$ L_1 <: a_1 <: U_1\;\wedge\;...\;\wedge\;L_m <: a_m <: U_m \ \Rightarrow\ T_p <: T $$ -If no such bounds can be found, a compile time error results. If such -bounds are found, the pattern matching clause starting with ´p´ is -then typed under the assumption that each ´a_i´ has lower bound ´L_i'´ -instead of ´L_i´ and has upper bound ´U_i'´ instead of ´U_i´. - -The expected type of every block ´b_i´ is the expected type of the -whole pattern matching expression. The type of the pattern matching -expression is then the [weak least upper bound](03-types.html#weak-conformance) -of the types of all blocks -´b_i´. - -When applying a pattern matching expression to a selector value, -patterns are tried in sequence until one is found which matches the -[selector value](#patterns). Say this case is `case ´p_i \Rightarrow b_i´`. -The result of the whole expression is the result of evaluating ´b_i´, -where all pattern variables of ´p_i´ are bound to -the corresponding parts of the selector value. If no matching pattern -is found, a `scala.MatchError` exception is thrown. - -The pattern in a case may also be followed by a guard suffix -`if e` with a boolean expression ´e´. The guard expression is -evaluated if the preceding pattern in the case matches. If the guard -expression evaluates to `true`, the pattern match succeeds as -normal. If the guard expression evaluates to `false`, the pattern -in the case is considered not to match and the search for a matching -pattern continues. - -In the interest of efficiency the evaluation of a pattern matching -expression may try patterns in some other order than textual -sequence. This might affect evaluation through -side effects in guards. However, it is guaranteed that a guard -expression is evaluated only if the pattern it guards matches. - -If the selector of a pattern match is an instance of a -[`sealed` class](05-classes-and-objects.html#modifiers), -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. +If no such bounds can be found, a compile time error results. +If such bounds are found, the pattern matching clause starting with ´p´ is then typed under the assumption that each ´a_i´ has lower bound ´L_i'´ instead of ´L_i´ and has upper bound ´U_i'´ instead of ´U_i´. + +The expected type of every block ´b_i´ is the expected type of the whole pattern matching expression. +The type of the pattern matching expression is then the [weak least upper bound](03-types.html#weak-conformance) of the types of all blocks ´b_i´. + +When applying a pattern matching expression to a selector value, patterns are tried in sequence until one is found which matches the [selector value](#patterns). +Say this case is `case ´p_i \Rightarrow b_i´`. +The result of the whole expression is the result of evaluating ´b_i´, where all pattern variables of ´p_i´ are bound to the corresponding parts of the selector value. +If no matching pattern is found, a `scala.MatchError` exception is thrown. + +The pattern in a case may also be followed by a guard suffix `if e` with a boolean expression ´e´. +The guard expression is evaluated if the preceding pattern in the case matches. +If the guard expression evaluates to `true`, the pattern match succeeds as normal. +If the guard expression evaluates to `false`, the pattern in the case is considered not to match and the search for a matching pattern continues. + +In the interest of efficiency the evaluation of a pattern matching expression may try patterns in some other order than textual sequence. +This might affect evaluation through side effects in guards. +However, it is guaranteed that a guard expression is evaluated only if the pattern it guards matches. + +If the selector of a pattern match is an instance of a [`sealed` class](05-classes-and-objects.html#modifiers), 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 @@ -707,9 +545,8 @@ case class If[T](c: Term[Boolean], t2: Term[T]) extends Term[T] ``` -There are terms to represent numeric literals, incrementation, a zero -test, and a conditional. Every term carries as a type parameter the -type of the expression it represents (either `Int` or `Boolean`). +There are terms to represent numeric literals, incrementation, a zero test, and a conditional. +Every term carries as a type parameter the type of the expression it represents (either `Int` or `Boolean`). A type-safe evaluator for such terms can be written as follows. @@ -722,16 +559,11 @@ def eval[T](t: Term[T]): T = t match { } ``` -Note that the evaluator makes crucial use of the fact that type -parameters of enclosing methods can acquire new bounds through pattern -matching. +Note that the evaluator makes crucial use of the fact that type parameters of enclosing methods can acquire new bounds through pattern matching. -For instance, the type of the pattern in the second case, -`Succ(u)`, is `Int`. It conforms to the selector type -`T` only if we assume an upper and lower bound of `Int` for `T`. -Under the assumption `Int <: T <: Int` we can also -verify that the type right hand side of the second case, `Int` -conforms to its expected type, `T`. +For instance, the type of the pattern in the second case, `Succ(u)`, is `Int`. +It conforms to the selector type `T` only if we assume an upper and lower bound of `Int` for `T`. +Under the assumption `Int <: T <: Int` we can also verify that the type right hand side of the second case, `Int` conforms to its expected type, `T`. ## Pattern Matching Anonymous Functions @@ -745,16 +577,11 @@ An anonymous function can be defined by a sequence of cases { case ´p_1´ => ´b_1´ ... case ´p_n´ => ´b_n´ } ``` -which appear as an expression without a prior `match`. The -expected type of such an expression must in part be defined. It must -be either `scala.Function´k´[´S_1, ..., S_k´, ´R´]` for some ´k > 0´, -or `scala.PartialFunction[´S_1´, ´R´]`, where the -argument type(s) ´S_1, ..., S_k´ must be fully determined, but the result type -´R´ may be undetermined. +which appear as an expression without a prior `match`. +The expected type of such an expression must in part be defined. +It must be either `scala.Function´k´[´S_1, ..., S_k´, ´R´]` for some ´k > 0´, or `scala.PartialFunction[´S_1´, ´R´]`, where the argument type(s) ´S_1, ..., S_k´ must be fully determined, but the result type ´R´ may be undetermined. -If the expected type is [SAM-convertible](06-expressions.html#sam-conversion) -to `scala.Function´k´[´S_1, ..., S_k´, ´R´]`, -the expression is taken to be equivalent to the anonymous function: +If the expected type is [SAM-convertible](06-expressions.html#sam-conversion) to `scala.Function´k´[´S_1, ..., S_k´, ´R´]`, the expression is taken to be equivalent to the anonymous function: ```scala (´x_1: S_1, ..., x_k: S_k´) => (´x_1, ..., x_k´) match { @@ -763,9 +590,7 @@ the expression is taken to be equivalent to the anonymous function: ``` Here, each ´x_i´ is a fresh name. -As was shown [here](06-expressions.html#anonymous-functions), this anonymous function is in turn -equivalent to the following instance creation expression, where - ´T´ is the weak least upper bound of the types of all ´b_i´. +As was shown [here](06-expressions.html#anonymous-functions), this anonymous function is in turn equivalent to the following instance creation expression, where ´T´ is the weak least upper bound of the types of all ´b_i´. ```scala new scala.Function´k´[´S_1, ..., S_k´, ´T´] { @@ -775,8 +600,7 @@ new scala.Function´k´[´S_1, ..., S_k´, ´T´] { } ``` -If the expected type is `scala.PartialFunction[´S´, ´R´]`, -the expression is taken to be equivalent to the following instance creation expression: +If the expected type is `scala.PartialFunction[´S´, ´R´]`, the expression is taken to be equivalent to the following instance creation expression: ```scala new scala.PartialFunction[´S´, ´T´] { @@ -790,15 +614,11 @@ new scala.PartialFunction[´S´, ´T´] { } ``` -Here, ´x´ is a fresh name and ´T´ is the weak least upper bound of the -types of all ´b_i´. The final default case in the `isDefinedAt` -method is omitted if one of the patterns ´p_1, ..., p_n´ is -already a variable or wildcard pattern. +Here, ´x´ is a fresh name and ´T´ is the weak least upper bound of the types of all ´b_i´. +The final default case in the `isDefinedAt` method is omitted if one of the patterns ´p_1, ..., p_n´ is already a variable or wildcard pattern. ###### Example -Here's an example which uses -`foldLeft` to compute the scalar product of -two vectors: +Here's an example which uses `foldLeft` to compute the scalar product of two vectors: ```scala def scalarProduct(xs: Array[Double], ys: Array[Double]) = @@ -807,8 +627,7 @@ def scalarProduct(xs: Array[Double], ys: Array[Double]) = } ``` -The case clauses in this code are equivalent to the following -anonymous function: +The case clauses in this code are equivalent to the following anonymous function: ```scala (x, y) => (x, y) match { diff --git a/docs/_spec/09-top-level-definitions.md b/docs/_spec/09-top-level-definitions.md index 3588d26f6034..8406c0180533 100644 --- a/docs/_spec/09-top-level-definitions.md +++ b/docs/_spec/09-top-level-definitions.md @@ -19,9 +19,7 @@ TopStat ::= {Annotation} {Modifier} TmplDef QualId ::= id {‘.’ id} ``` -A compilation unit consists of a sequence of packagings, import -clauses, and class and object definitions, which may be preceded by a -package clause. +A compilation unit consists of a sequence of packagings, import clauses, and class and object definitions, which may be preceded by a package clause. A _compilation unit_ @@ -32,9 +30,7 @@ package ´p_n´; ´\mathit{stats}´ ``` -starting with one or more package -clauses is equivalent to a compilation unit consisting of the -packaging +starting with one or more package clauses is equivalent to a compilation unit consisting of the packaging ```scala package ´p_1´ { ... @@ -59,20 +55,16 @@ The exception to the implicit import of `scala.Predef` can be useful to hide, e. Packaging ::= ‘package’ QualId [nl] ‘{’ TopStatSeq ‘}’ ``` -A _package_ is a special object which defines a set of member classes, -objects and packages. Unlike other objects, packages are not introduced -by a definition. Instead, the set of members of a package is determined by -packagings. +A _package_ is a special object which defines a set of member classes, objects and packages. +Unlike other objects, packages are not introduced by a definition. +Instead, the set of members of a package is determined by packagings. -A packaging `package ´p´ { ´\mathit{ds}´ }` injects all -definitions in ´\mathit{ds}´ as members into the package whose qualified name -is ´p´. Members of a package are called _top-level_ definitions. -If a definition in ´\mathit{ds}´ is labeled `private`, it is -visible only for other members in the package. +A packaging `package ´p´ { ´\mathit{ds}´ }` injects all definitions in ´\mathit{ds}´ as members into the package whose qualified name is ´p´. +Members of a package are called _top-level_ definitions. +If a definition in ´\mathit{ds}´ is labeled `private`, it is visible only for other members in the package. -Inside the packaging, all members of package ´p´ are visible under their -simple names. However this rule does not extend to members of enclosing -packages of ´p´ that are designated by a prefix of the path ´p´. +Inside the packaging, all members of package ´p´ are visible under their simple names. +However this rule does not extend to members of enclosing packages of ´p´ that are designated by a prefix of the path ´p´. ```scala package org.net.prj { @@ -80,19 +72,15 @@ package org.net.prj { } ``` -all members of package `org.net.prj` are visible under their -simple names, but members of packages `org` or `org.net` require -explicit qualification or imports. +all members of package `org.net.prj` are visible under their simple names, but members of packages `org` or `org.net` require explicit qualification or imports. -Selections ´p´.´m´ from ´p´ as well as imports from ´p´ -work as for objects. However, unlike other objects, packages may not -be used as values. It is illegal to have a package with the same fully -qualified name as a module or a class. +Selections ´p´.´m´ from ´p´ as well as imports from ´p´ work as for objects. +However, unlike other objects, packages may not be used as values. +It is illegal to have a package with the same fully qualified name as a module or a class. -Top-level definitions outside a packaging are assumed to be injected -into a special empty package. That package cannot be named and -therefore cannot be imported. However, members of the empty package -are visible to each other without qualification. +Top-level definitions outside a packaging are assumed to be injected into a special empty package. +That package cannot be named and therefore cannot be imported. +However, members of the empty package are visible to each other without qualification. ## Package Objects @@ -100,17 +88,13 @@ are visible to each other without qualification. PackageObject ::= ‘package’ ‘object’ ObjectDef ``` -A _package object_ `package object ´p´ extends ´t´` adds the -members of template ´t´ to the package ´p´. There can be only one -package object per package. The standard naming convention is to place -the definition above in a file named `package.scala` that's -located in the directory corresponding to package ´p´. +A _package object_ `package object ´p´ extends ´t´` adds the members of template ´t´ to the package ´p´. +There can be only one package object per package. +The standard naming convention is to place the definition above in a file named `package.scala` that's located in the directory corresponding to package ´p´. -The package object should not define a member with the same name as -one of the top-level objects or classes defined in package ´p´. If -there is a name conflict, the behavior of the program is currently -undefined. It is expected that this restriction will be lifted in a -future version of Scala. +The package object should not define a member with the same name as one of the top-level objects or classes defined in package ´p´. +If there is a name conflict, the behavior of the program is currently undefined. +It is expected that this restriction will be lifted in a future version of Scala. ## Package References @@ -119,18 +103,12 @@ QualId ::= id {‘.’ id} ``` A reference to a package takes the form of a qualified identifier. -Like all other references, package references are relative. That is, -a package reference starting in a name ´p´ will be looked up in the -closest enclosing scope that defines a member named ´p´. +Like all other references, package references are relative. +That is, a package reference starting in a name ´p´ will be looked up in the closest enclosing scope that defines a member named ´p´. -If a package name is shadowed, it's possible to refer to its -fully-qualified name by prefixing it with -the special predefined name `_root_`, which refers to the -outermost root package that contains all top-level packages. +If a package name is shadowed, it's possible to refer to its fully-qualified name by prefixing it with the special predefined name `_root_`, which refers to the outermost root package that contains all top-level packages. -The name `_root_` has this special denotation only when -used as the first element of a qualifier; it is an ordinary -identifier otherwise. +The name `_root_` has this special denotation only when used as the first element of a qualifier; it is an ordinary identifier otherwise. ###### Example Consider the following program: @@ -154,29 +132,20 @@ package a { ``` -Here, the reference `_root_.b.B` refers to class `B` in the -toplevel package `b`. If the `_root_` prefix had been -omitted, the name `b` would instead resolve to the package -`a.b`, and, provided that package does not also -contain a class `B`, a compiler-time error would result. +Here, the reference `_root_.b.B` refers to class `B` in the toplevel package `b`. +If the `_root_` prefix had been omitted, the name `b` would instead resolve to the package `a.b`, and, provided that package does not also contain a class `B`, a compiler-time error would result. ## Programs -A _program_ is a top-level object that has a member method -_main_ of type `(Array[String])Unit`. Programs can be -executed from a command shell. The program's command arguments are -passed to the `main` method as a parameter of type -`Array[String]`. +A _program_ is a top-level object that has a member method _main_ of type `(Array[String])Unit`. Programs can be executed from a command shell. +The program's command arguments are passed to the `main` method as a parameter of type `Array[String]`. -The `main` method of a program can be directly defined in the -object, or it can be inherited. The scala library defines a special class -`scala.App` whose body acts as a `main` method. -An objects ´m´ inheriting from this class is thus a program, -which executes the initialization code of the object ´m´. +The `main` method of a program can be directly defined in the object, or it can be inherited. +The scala library defines a special class `scala.App` whose body acts as a `main` method. +An objects ´m´ inheriting from this class is thus a program, which executes the initialization code of the object ´m´. ###### Example -The following example will create a hello world program by defining -a method `main` in module `test.HelloWorld`. +The following example will create a hello world program by defining a method `main` in module `test.HelloWorld`. ```scala package test @@ -199,8 +168,7 @@ java test.HelloWorld would work as well. -`HelloWorld` can also be defined without a `main` method -by inheriting from `App` instead: +`HelloWorld` can also be defined without a `main` method by inheriting from `App` instead: ```scala package test diff --git a/docs/_spec/10-xml-expressions-and-patterns.md b/docs/_spec/10-xml-expressions-and-patterns.md index a9b7edb14fff..c929e24fe93d 100644 --- a/docs/_spec/10-xml-expressions-and-patterns.md +++ b/docs/_spec/10-xml-expressions-and-patterns.md @@ -9,28 +9,22 @@ chapter: 10 __By Burak Emir__ This chapter describes the syntactic structure of XML expressions and patterns. -It follows as closely as possible the XML 1.0 specification, -changes being mandated by the possibility of embedding Scala code fragments. +It follows as closely as possible the XML 1.0 specification, changes being mandated by the possibility of embedding Scala code fragments. ## XML expressions -XML expressions are expressions generated by the following production, where the -opening bracket `<` of the first element must be in a position to start the lexical -[XML mode](01-lexical-syntax.html#xml-mode). +XML expressions are expressions generated by the following production, where the opening bracket `<` of the first element must be in a position to start the lexical [XML mode](01-lexical-syntax.html#xml-mode). ```ebnf XmlExpr ::= XmlContent {Element} ``` -Well-formedness constraints of the XML specification apply, which -means for instance that start tags and end tags must match, and -attributes may only be defined once, except for constraints -related to entity resolution. +Well-formedness constraints of the XML specification apply, which means for instance that start tags and end tags must match, and attributes may only be defined once, except for constraints related to entity resolution. -The following productions describe Scala's extensible markup language, -designed as close as possible to the W3C extensible markup language -standard. Only the productions for attribute values and character data are changed. -Scala does not support declarations. Entity references are not resolved at runtime. +The following productions describe Scala's extensible markup language, designed as close as possible to the W3C extensible markup language standard. +Only the productions for attribute values and character data are changed. +Scala does not support declarations. +Entity references are not resolved at runtime. ```ebnf Element ::= EmptyElemTag @@ -50,21 +44,13 @@ XmlContent ::= Element | Comment ``` -If an XML expression is a single element, its value is a runtime -representation of an XML node (an instance of a subclass of -`scala.xml.Node`). If the XML expression consists of more -than one element, then its value is a runtime representation of a -sequence of XML nodes (an instance of a subclass of -`scala.Seq[scala.xml.Node]`). +If an XML expression is a single element, its value is a runtime representation of an XML node (an instance of a subclass of `scala.xml.Node`). +If the XML expression consists of more than one element, then its value is a runtime representation of a sequence of XML nodes (an instance of a subclass of `scala.Seq[scala.xml.Node]`). -If an XML expression is an entity reference, CDATA section, processing -instruction, or a comment, it is represented by an instance of the -corresponding Scala runtime class. +If an XML expression is an entity reference, CDATA section, processing instruction, or a comment, it is represented by an instance of the corresponding Scala runtime class. -By default, beginning and trailing whitespace in element content is removed, -and consecutive occurrences of whitespace are replaced by a single space -character `\u0020`. This behavior can be changed to preserve all whitespace -with a compiler option. +By default, beginning and trailing whitespace in element content is removed, and consecutive occurrences of whitespace are replaced by a single space character `\u0020`. +This behavior can be changed to preserve all whitespace with a compiler option. ```ebnf Attribute ::= Name Eq AttValue @@ -80,10 +66,9 @@ CharData ::= { CharNoRef } ´\textit{ without}´ {CharNoRef}‘{’CharB ``` -XML expressions may contain Scala expressions as attribute values or -within nodes. In the latter case, these are embedded using a single opening -brace `{` and ended by a closing brace `}`. To express a single opening braces -within XML text as generated by CharData, it must be doubled. +XML expressions may contain Scala expressions as attribute values or within nodes. +In the latter case, these are embedded using a single opening brace `{` and ended by a closing brace `}`. +To express a single opening braces within XML text as generated by CharData, it must be doubled. Thus, `{{` represents the XML text `{` and does not introduce an embedded Scala expression. @@ -104,9 +89,7 @@ XNameStart ::= ‘_’ | BaseChar | Ideographic ## XML patterns -XML patterns are patterns generated by the following production, where -the opening bracket `<` of the element patterns must be in a position -to start the lexical [XML mode](01-lexical-syntax.html#xml-mode). +XML patterns are patterns generated by the following production, where the opening bracket `<` of the element patterns must be in a position to start the lexical [XML mode](01-lexical-syntax.html#xml-mode). ```ebnf XmlPattern ::= ElementPattern @@ -114,18 +97,14 @@ XmlPattern ::= ElementPattern Well-formedness constraints of the XML specification apply. -An XML pattern has to be a single element pattern. It -matches exactly those runtime -representations of an XML tree -that have the same structure as described by the pattern. +An XML pattern has to be a single element pattern. +It matches exactly those runtime representations of an XML tree that have the same structure as described by the pattern. XML patterns may contain [Scala patterns](08-pattern-matching.html#pattern-matching-expressions). Whitespace is treated the same way as in XML expressions. -By default, beginning and trailing whitespace in element content is removed, -and consecutive occurrences of whitespace are replaced by a single space -character `\u0020`. This behavior can be changed to preserve all whitespace -with a compiler option. +By default, beginning and trailing whitespace in element content is removed, and consecutive occurrences of whitespace are replaced by a single space character `\u0020`. +This behavior can be changed to preserve all whitespace with a compiler option. ```ebnf ElemPattern ::= EmptyElemTagP diff --git a/docs/_spec/11-annotations.md b/docs/_spec/11-annotations.md index 9f806ff5a471..11325a1639f0 100644 --- a/docs/_spec/11-annotations.md +++ b/docs/_spec/11-annotations.md @@ -15,16 +15,14 @@ chapter: 11 Annotations associate meta-information with definitions. A simple annotation has the form `@´c´` or `@´c(a_1, ..., a_n)´`. -Here, ´c´ is a constructor of a class ´C´, which must conform -to the class `scala.Annotation`. +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. +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: @@ -39,138 +37,90 @@ String @local // Type annotation ### Java Platform Annotations -The meaning of annotation clauses is implementation-dependent. On the -Java platform, the following annotations have a standard meaning. +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. +* `@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. +* `@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 the following field - definition in Java: +* `@SerialVersionUID()` Attaches a serial version identifier (a `long` constant) to a class. +This is equivalent to the following field definition in Java: - ```java - private final static SerialVersionUID = - ``` +```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 the 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. +* `@throws()` A Java compiler checks that a program contains handlers for checked exceptions by analyzing which checked exceptions can result from the 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.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`. +* `@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. +* `@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: , since: )`
      - Marks a formal parameter name as deprecated. Invocations of this entity - using named parameter syntax referring to the deprecated parameter name cause a deprecation warning. +* `@deprecatedName(name: , since: )`
      +Marks a formal parameter name as deprecated. +Invocations of this entity using named parameter syntax referring 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 that would otherwise be emitted. For instance, no warnings - would be produced for the method definition below. - - ```scala - def f(x: Option[Int]) = (x: @unchecked) match { - case Some(y) => y - } - ``` - - 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: - - ```scala - 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` - - ```scala - 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](https://docs.scala-lang.org/sips/scala-specialization.html) for more details of the implementation. +* `@unchecked` When applied to the selector of a `match` expression, this attribute suppresses any warnings about non-exhaustive pattern matches that would otherwise be emitted. +For instance, no warnings would be produced for the method definition below. +```scala +def f(x: Option[Int]) = (x: @unchecked) match { + case Some(y) => y +} +``` +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: +```scala +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` +```scala +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](https://docs.scala-lang.org/sips/scala-specialization.html) for more details of the implementation. ## User-defined Annotations -Other annotations may be interpreted by platform- or application-dependent -tools. The class `scala.annotation.Annotation` is the base class for -user-defined annotations. It has two sub-traits: -- `scala.annotation.StaticAnnotation`: Instances of a subclass of this trait - will be stored in the generated class files, and therefore accessible to - runtime reflection and later compilation runs. -- `scala.annotation.ConstantAnnotation`: Instances of a subclass of this trait - may only have arguments which are - [constant expressions](06-expressions.html#constant-expressions), and are - also stored in the generated class files. -- If an annotation class inherits from neither `scala.ConstantAnnotation` nor - `scala.StaticAnnotation`, its instances are visible only locally during the - compilation run that analyzes them. +Other annotations may be interpreted by platform- or application-dependent tools. +The class `scala.annotation.Annotation` is the base class for user-defined annotations. It has two sub-traits: +- `scala.annotation.StaticAnnotation`: Instances of a subclass of this trait will be stored in the generated class files, and therefore accessible to runtime reflection and later compilation runs. +- `scala.annotation.ConstantAnnotation`: Instances of a subclass of this trait may only have arguments which are [constant expressions](06-expressions.html#constant-expressions), and are also stored in the generated class files. +- If an annotation class inherits from neither `scala.ConstantAnnotation` nor `scala.StaticAnnotation`, its instances are visible only locally during the compilation run that analyzes them. ## Host-platform Annotations -The host platform may define its own annotation format. These annotations do not -extend any of the classes in the `scala.annotation` package, but can generally -be used in the same way as Scala annotations. The host platform may impose -additional restrictions on the expressions which are valid as annotation -arguments. +The host platform may define its own annotation format. +These annotations do not extend any of the classes in the `scala.annotation` package, but can generally be used in the same way as Scala annotations. +The host platform may impose additional restrictions on the expressions which are valid as annotation arguments. diff --git a/docs/_spec/12-the-scala-standard-library.md b/docs/_spec/12-the-scala-standard-library.md index 9bbc12e463dd..086d396ba4dd 100644 --- a/docs/_spec/12-the-scala-standard-library.md +++ b/docs/_spec/12-the-scala-standard-library.md @@ -6,39 +6,28 @@ chapter: 12 # The Scala Standard Library -The Scala standard library consists of the package `scala` with a -number of classes and modules. Some of these classes are described in -the following. +The Scala standard library consists of the package `scala` with a number of classes and modules. +Some of these classes are described in the following. ![Class hierarchy of Scala](public/images/classhierarchy.png) ## Root Classes The root of this hierarchy is formed by class `Any`. -Every class in a Scala execution environment inherits directly or -indirectly from this class. Class `Any` has two direct -subclasses: `AnyRef` and `AnyVal`. +Every class in a Scala execution environment inherits directly or indirectly from this class. +Class `Any` has two direct subclasses: `AnyRef` and `AnyVal`. -The subclass `AnyRef` represents all values which are represented -as objects in the underlying host system. Classes written in other languages -inherit from `scala.AnyRef`. +The subclass `AnyRef` represents all values which are represented as objects in the underlying host system. +Classes written in other languages inherit from `scala.AnyRef`. -The predefined subclasses of class `AnyVal` describe -values which are not implemented as objects in the underlying host -system. +The predefined subclasses of class `AnyVal` describe values which are not implemented as objects in the underlying host system. -User-defined Scala classes which do not explicitly inherit from -`AnyVal` inherit directly or indirectly from `AnyRef`. They cannot -inherit from both `AnyRef` and `AnyVal`. +User-defined Scala classes which do not explicitly inherit from `AnyVal` inherit directly or indirectly from `AnyRef`. +They cannot inherit from both `AnyRef` and `AnyVal`. -Classes `AnyRef` and `AnyVal` are required to provide only -the members declared in class `Any`, but implementations may add -host-specific methods to these classes (for instance, an -implementation may identify class `AnyRef` with its own root -class for objects). +Classes `AnyRef` and `AnyVal` are required to provide only the members declared in class `Any`, but implementations may add host-specific methods to these classes (for instance, an implementation may identify class `AnyRef` with its own root class for objects). -The signatures of these root classes are described by the following -definitions. +The signatures of these root classes are described by the following definitions. ```scala package scala @@ -88,8 +77,7 @@ class AnyRef extends Any { } ``` -The type test `´x´.isInstanceOf[´T´]` is equivalent to a typed -pattern match +The type test `´x´.isInstanceOf[´T´]` is equivalent to a typed pattern match ```scala ´x´ match { @@ -98,33 +86,25 @@ pattern match } ``` -where the type ´T'´ is the same as ´T´ except if ´T´ is -of the form ´D´ or ´D[\mathit{tps}]´ where ´D´ is a type member of some outer class ´C´. +where the type ´T'´ is the same as ´T´ except if ´T´ is of the form ´D´ or ´D[\mathit{tps}]´ where ´D´ is a type member of some outer class ´C´. In this case ´T'´ is `´C´#´D´` (or `´C´#´D[tps]´`, respectively), whereas ´T´ itself would expand to `´C´.this.´D[tps]´`. In other words, an `isInstanceOf` test does not check that types have the same enclosing instance. -The test `´x´.asInstanceOf[´T´]` is treated specially if ´T´ is a -[numeric value type](#value-classes). In this case the cast will -be translated to an application of a [conversion method](#numeric-value-types) -`x.to´T´`. For non-numeric values ´x´ the operation will raise a -`ClassCastException`. +The test `´x´.asInstanceOf[´T´]` is treated specially if ´T´ is a [numeric value type](#value-classes). +In this case the cast will be translated to an application of a [conversion method](#numeric-value-types) `x.to´T´`. +For non-numeric values ´x´ the operation will raise a `ClassCastException`. ## Value Classes -Value classes are classes whose instances are not represented as -objects by the underlying host system. All value classes inherit from -class `AnyVal`. Scala implementations need to provide the -value classes `Unit`, `Boolean`, `Double`, `Float`, -`Long`, `Int`, `Char`, `Short`, and `Byte` -(but are free to provide others as well). +Value classes are classes whose instances are not represented as objects by the underlying host system. +All value classes inherit from class `AnyVal`. +Scala implementations need to provide the value classes `Unit`, `Boolean`, `Double`, `Float`, `Long`, `Int`, `Char`, `Short`, and `Byte` (but are free to provide others as well). The signatures of these classes are defined in the following. ### Numeric Value Types -Classes `Double`, `Float`, -`Long`, `Int`, `Char`, `Short`, and `Byte` -are together called _numeric value types_. Classes `Byte`, -`Short`, or `Char` are called _subrange types_. +Classes `Double`, `Float`, `Long`, `Int`, `Char`, `Short`, and `Byte` are together called _numeric value types_. +Classes `Byte`, `Short`, or `Char` are called _subrange types_. Subrange types, as well as `Int` and `Long` are called _integer types_, whereas `Float` and `Double` are called _floating point types_. Numeric value types are ranked in the following partial order: @@ -137,81 +117,52 @@ Byte - Short Char ``` -`Byte` and `Short` are the lowest-ranked types in this order, -whereas `Double` is the highest-ranked. Ranking does _not_ -imply a [conformance relationship](03-types.html#conformance); for -instance `Int` is not a subtype of `Long`. However, object -[`Predef`](#the-predef-object) defines [views](07-implicits.html#views) -from every numeric value type to all higher-ranked numeric value types. -Therefore, lower-ranked types are implicitly converted to higher-ranked types -when required by the [context](06-expressions.html#implicit-conversions). - -Given two numeric value types ´S´ and ´T´, the _operation type_ of -´S´ and ´T´ is defined as follows: If both ´S´ and ´T´ are subrange -types then the operation type of ´S´ and ´T´ is `Int`. Otherwise -the operation type of ´S´ and ´T´ is the larger of the two types wrt -ranking. Given two numeric values ´v´ and ´w´ the operation type of -´v´ and ´w´ is the operation type of their run-time types. +`Byte` and `Short` are the lowest-ranked types in this order, whereas `Double` is the highest-ranked. +Ranking does _not_ +imply a [conformance relationship](03-types.html#conformance); for instance `Int` is not a subtype of `Long`. +However, object [`Predef`](#the-predef-object) defines [views](07-implicits.html#views) from every numeric value type to all higher-ranked numeric value types. +Therefore, lower-ranked types are implicitly converted to higher-ranked types when required by the [context](06-expressions.html#implicit-conversions). + +Given two numeric value types ´S´ and ´T´, the _operation type_ of ´S´ and ´T´ is defined as follows: If both ´S´ and ´T´ are subrange types then the operation type of ´S´ and ´T´ is `Int`. +Otherwise the operation type of ´S´ and ´T´ is the larger of the two types wrt +ranking. +Given two numeric values ´v´ and ´w´ the operation type of ´v´ and ´w´ is the operation type of their run-time types. Any numeric value type ´T´ supports the following methods. - * Comparison methods for equals (`==`), not-equals (`!=`), - less-than (`<`), greater-than (`>`), less-than-or-equals - (`<=`), greater-than-or-equals (`>=`), which each exist in 7 - overloaded alternatives. Each alternative takes a parameter of some - numeric value type. Its result type is type `Boolean`. The - operation is evaluated by converting the receiver and its argument to - their operation type and performing the given comparison operation of - that type. - * Arithmetic methods addition (`+`), subtraction (`-`), - multiplication (`*`), division (`/`), and remainder - (`%`), which each exist in 7 overloaded alternatives. Each - alternative takes a parameter of some numeric value type ´U´. Its - result type is the operation type of ´T´ and ´U´. The operation is - evaluated by converting the receiver and its argument to their - operation type and performing the given arithmetic operation of that - type. - * Parameterless arithmetic methods identity (`+`) and negation - (`-`), with result type ´T´. The first of these returns the - receiver unchanged, whereas the second returns its negation. - * Conversion methods `toByte`, `toShort`, `toChar`, - `toInt`, `toLong`, `toFloat`, `toDouble` which - convert the receiver object to the target type, using the rules of - Java's numeric type cast operation. The conversion might truncate the - numeric value (as when going from `Long` to `Int` or from - `Int` to `Byte`) or it might lose precision (as when going - from `Double` to `Float` or when converting between - `Long` and `Float`). +* Comparison methods for equals (`==`), not-equals (`!=`), less-than (`<`), greater-than (`>`), less-than-or-equals (`<=`), greater-than-or-equals (`>=`), which each exist in 7 overloaded alternatives. +Each alternative takes a parameter of some numeric value type. +Its result type is type `Boolean`. +The operation is evaluated by converting the receiver and its argument to their operation type and performing the given comparison operation of that type. +* Arithmetic methods addition (`+`), subtraction (`-`), multiplication (`*`), division (`/`), and remainder (`%`), which each exist in 7 overloaded alternatives. +Each alternative takes a parameter of some numeric value type ´U´. +Its result type is the operation type of ´T´ and ´U´. +The operation is evaluated by converting the receiver and its argument to their operation type and performing the given arithmetic operation of that type. +* Parameterless arithmetic methods identity (`+`) and negation (`-`), with result type ´T´. +The first of these returns the receiver unchanged, whereas the second returns its negation. +* Conversion methods `toByte`, `toShort`, `toChar`, `toInt`, `toLong`, `toFloat`, `toDouble` which convert the receiver object to the target type, using the rules of Java's numeric type cast operation. +The conversion might truncate the numeric value (as when going from `Long` to `Int` or from `Int` to `Byte`) or it might lose precision (as when going from `Double` to `Float` or when converting between `Long` and `Float`). Integer numeric value types support in addition the following operations: - * Bit manipulation methods bitwise-and (`&`), bitwise-or - {`|`}, and bitwise-exclusive-or (`^`), which each exist in 5 - overloaded alternatives. Each alternative takes a parameter of some - integer numeric value type. Its result type is the operation type of - ´T´ and ´U´. The operation is evaluated by converting the receiver and - its argument to their operation type and performing the given bitwise - operation of that type. - - * A parameterless bit-negation method (`~`). Its result type is - the receiver type ´T´ or `Int`, whichever is larger. - The operation is evaluated by converting the receiver to the result - type and negating every bit in its value. - * Bit-shift methods left-shift (`<<`), arithmetic right-shift - (`>>`), and unsigned right-shift (`>>>`). Each of these - methods has two overloaded alternatives, which take a parameter ´n´ - of type `Int`, respectively `Long`. The result type of the - operation is the receiver type ´T´, or `Int`, whichever is larger. - The operation is evaluated by converting the receiver to the result - type and performing the specified shift by ´n´ bits. - -Numeric value types also implement operations `equals`, -`hashCode`, and `toString` from class `Any`. - -The `equals` method tests whether the argument is a numeric value -type. If this is true, it will perform the `==` operation which -is appropriate for that type. That is, the `equals` method of a -numeric value type can be thought of being defined as follows: +* Bit manipulation methods bitwise-and (`&`), bitwise-or {`|`}, and bitwise-exclusive-or (`^`), which each exist in 5 overloaded alternatives. +Each alternative takes a parameter of some integer numeric value type. +Its result type is the operation type of ´T´ and ´U´. +The operation is evaluated by converting the receiver and its argument to their operation type and performing the given bitwise operation of that type. + +* A parameterless bit-negation method (`~`). +Its result type is the receiver type ´T´ or `Int`, whichever is larger. +The operation is evaluated by converting the receiver to the result type and negating every bit in its value. +* Bit-shift methods left-shift (`<<`), arithmetic right-shift (`>>`), and unsigned right-shift (`>>>`). +Each of these methods has two overloaded alternatives, which take a parameter ´n´ of type `Int`, respectively `Long`. +The result type of the operation is the receiver type ´T´, or `Int`, whichever is larger. +The operation is evaluated by converting the receiver to the result type and performing the specified shift by ´n´ bits. + +Numeric value types also implement operations `equals`, `hashCode`, and `toString` from class `Any`. + +The `equals` method tests whether the argument is a numeric value type. +If this is true, it will perform the `==` operation which is appropriate for that type. +That is, the `equals` method of a numeric value type can be thought of being defined as follows: ```scala def equals(other: Any): Boolean = other match { @@ -226,12 +177,10 @@ def equals(other: Any): Boolean = other match { } ``` -The `hashCode` method returns an integer hashcode that maps equal -numeric values to equal results. It is guaranteed to be the identity -for type `Int` and for all subrange types. +The `hashCode` method returns an integer hashcode that maps equal numeric values to equal results. +It is guaranteed to be the identity for type `Int` and for all subrange types. -The `toString` method displays its receiver as an integer or -floating point number. +The `toString` method displays its receiver as an integer or floating point number. ###### Example @@ -285,9 +234,8 @@ abstract sealed class Int extends AnyVal { ### Class `Boolean` -Class `Boolean` has only two values: `true` and -`false`. It implements operations as given in the following -class definition. +Class `Boolean` has only two values: `true` and `false`. +It implements operations as given in the following class definition. ```scala package scala @@ -309,47 +257,36 @@ abstract sealed class Boolean extends AnyVal { } ``` -The class also implements operations `equals`, `hashCode`, -and `toString` from class `Any`. +The class also implements operations `equals`, `hashCode`, and `toString` from class `Any`. -The `equals` method returns `true` if the argument is the -same boolean value as the receiver, `false` otherwise. The -`hashCode` method returns a fixed, implementation-specific hash-code when invoked on `true`, -and a different, fixed, implementation-specific hash-code when invoked on `false`. The `toString` method -returns the receiver converted to a string, i.e. either `"true"` or `"false"`. +The `equals` method returns `true` if the argument is the same boolean value as the receiver, `false` otherwise. +The `hashCode` method returns a fixed, implementation-specific hash-code when invoked on `true`, and a different, fixed, implementation-specific hash-code when invoked on `false`. +The `toString` method returns the receiver converted to a string, i.e. either `"true"` or `"false"`. ### Class `Unit` -Class `Unit` has only one value: `()`. It implements only -the three methods `equals`, `hashCode`, and `toString` -from class `Any`. +Class `Unit` has only one value: `()`. +It implements only the three methods `equals`, `hashCode`, and `toString` from class `Any`. -The `equals` method returns `true` if the argument is the -unit value `()`, `false` otherwise. The -`hashCode` method returns a fixed, implementation-specific hash-code, +The `equals` method returns `true` if the argument is the unit value `()`, `false` otherwise. +The `hashCode` method returns a fixed, implementation-specific hash-code. 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 -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. +This section presents some standard Scala reference classes which are 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. ### Class `String` -Scala's `String` class is usually derived from the standard String -class of the underlying host system (and may be identified with -it). For Scala clients the class is taken to support in each case a -method +Scala's `String` class is usually derived from the standard String class of the underlying host system (and may be identified with it). +For Scala clients the class is taken to support in each case a method ```scala def + (that: Any): String ``` -which concatenates its left operand with the textual representation of its -right operand. +which concatenates its left operand with the textual representation of its right operand. ### The `Tuple` classes @@ -385,14 +322,12 @@ class PartialFunction[-A, +B] extends Function1[A, B] { } ``` -The implicitly imported [`Predef`](#the-predef-object) object defines the name -`Function` as an alias of `Function1`. +The implicitly imported [`Predef`](#the-predef-object) object defines the name `Function` as an alias of `Function1`. ### Class `Array` -All operations on arrays desugar to the corresponding operations of the -underlying platform. Therefore, the following class definition is given for -informational purposes only: +All operations on arrays desugar to the corresponding operations of the underlying platform. +Therefore, the following class definition is given for informational purposes only: ```scala final class Array[T](_length: Int) @@ -404,20 +339,14 @@ extends java.io.Serializable with java.lang.Cloneable { } ``` -If ´T´ is not a type parameter or abstract type, the type `Array[T]` -is represented as the array type `|T|[]` in the -underlying host system, where `|T|` is the erasure of `T`. -If ´T´ is a type parameter or abstract type, a different representation might be -used (it is `Object` on the Java platform). +If ´T´ is not a type parameter or abstract type, the type `Array[T]` is represented as the array type `|T|[]` in the underlying host system, where `|T|` is the erasure of `T`. +If ´T´ is a type parameter or abstract type, a different representation might be used (it is `Object` on the Java platform). #### Operations -`length` returns the length of the array, `apply` means subscripting, -and `update` means element update. +`length` returns the length of the array, `apply` means subscripting, and `update` means element update. -Because of the syntactic sugar for `apply` and `update` operations, -we have the following correspondences between Scala and Java code for -operations on an array `xs`: +Because of the syntactic sugar for `apply` and `update` operations, we have the following correspondences between Scala and Java code for operations on an array `xs`: |_Scala_ |_Java_ | |------------------|------------| @@ -425,35 +354,22 @@ operations on an array `xs`: |`xs(i)` |`xs[i]` | |`xs(i) = e` |`xs[i] = e` | -Two implicit conversions exist in `Predef` that are frequently applied to arrays: -a conversion to `scala.collection.mutable.ArrayOps` and a conversion to -`scala.collection.mutable.ArraySeq` (a subtype of `scala.collection.Seq`). +Two implicit conversions exist in `Predef` that are frequently applied to arrays: a conversion to `scala.collection.mutable.ArrayOps` and a conversion to `scala.collection.mutable.ArraySeq` (a subtype of `scala.collection.Seq`). -Both types make many of the standard operations found in the Scala -collections API available. The conversion to `ArrayOps` is temporary, as all operations -defined on `ArrayOps` return a value of type `Array`, while the conversion to `ArraySeq` -is permanent as all operations return a value of type `ArraySeq`. +Both types make many of the standard operations found in the Scala collections API available. +The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return a value of type `Array`, while the conversion to `ArraySeq` is permanent as all operations return a value of type `ArraySeq`. The conversion to `ArrayOps` takes priority over the conversion to `ArraySeq`. -Because of the tension between parametrized types in Scala and the ad-hoc -implementation of arrays in the host-languages, some subtle points -need to be taken into account when dealing with arrays. These are -explained in the following. +Because of the tension between parametrized types in Scala and the ad-hoc implementation of arrays in the host-languages, some subtle points need to be taken into account when dealing with arrays. +These are explained in the following. #### Variance -Unlike arrays in Java, arrays in Scala are _not_ -co-variant; That is, ´S <: T´ does not imply -`Array[´S´] ´<:´ Array[´T´]` in Scala. -However, it is possible to cast an array -of ´S´ to an array of ´T´ if such a cast is permitted in the host -environment. +Unlike arrays in Java, arrays in Scala are _not_ co-variant; That is, ´S <: T´ does not imply `Array[´S´] ´<:´ Array[´T´]` in Scala. +However, it is possible to cast an array of ´S´ to an array of ´T´ if such a cast is permitted in the host environment. -For instance `Array[String]` does not conform to -`Array[Object]`, even though `String` conforms to `Object`. -However, it is possible to cast an expression of type -`Array[String]` to `Array[Object]`, and this -cast will succeed without raising a `ClassCastException`. Example: +For instance `Array[String]` does not conform to `Array[Object]`, even though `String` conforms to `Object`. +However, it is possible to cast an expression of type `Array[String]` to `Array[Object]`, and this cast will succeed without raising a `ClassCastException`. Example: ```scala val xs = new Array[String](2) @@ -461,14 +377,9 @@ val xs = new Array[String](2) val ys: Array[Object] = xs.asInstanceOf[Array[Object]] // OK ``` -The instantiation of an array with a polymorphic element type ´T´ requires -information about type ´T´ at runtime. -This information is synthesized by adding a [context bound](07-implicits.html#context-bounds-and-view-bounds) -of `scala.reflect.ClassTag` to type ´T´. -An example is the -following implementation of method `mkArray`, which creates -an array of an arbitrary type ´T´, given a sequence of ´T´`s which -defines its elements: +The instantiation of an array with a polymorphic element type ´T´ requires information about type ´T´ at runtime. +This information is synthesized by adding a [context bound](07-implicits.html#context-bounds-and-view-bounds) of `scala.reflect.ClassTag` to type ´T´. +An example is the following implementation of method `mkArray`, which creates an array of an arbitrary type ´T´, given a sequence of ´T´`s which defines its elements: ```scala import reflect.ClassTag @@ -483,19 +394,14 @@ def mkArray[T : ClassTag](elems: Seq[T]): Array[T] = { } ``` -If type ´T´ is a type for which the host platform offers a specialized array -representation, this representation is used. +If type ´T´ is a type for which the host platform offers a specialized array representation, this representation is used. ###### Example -On the Java Virtual Machine, an invocation of `mkArray(List(1,2,3))` -will return a primitive array of `int`s, written as `int[]` in Java. +On the Java Virtual Machine, an invocation of `mkArray(List(1,2,3))` will return a primitive array of `int`s, written as `int[]` in Java. #### Companion object -`Array`'s companion object provides various factory methods for the -instantiation of single- and multi-dimensional arrays, an extractor method -[`unapplySeq`](08-pattern-matching.html#extractor-patterns) which enables pattern matching -over arrays and additional utility methods: +`Array`'s companion object provides various factory methods for the instantiation of single- and multi-dimensional arrays, an extractor method [`unapplySeq`](08-pattern-matching.html#extractor-patterns) which enables pattern matching over arrays and additional utility methods: ```scala package scala @@ -623,10 +529,8 @@ trait Node { ## The `Predef` Object -The `Predef` object defines standard functions and type aliases -for Scala programs. It is implicitly imported, as described in -[the chapter on name binding](02-identifiers-names-and-scopes.html), -so that all its defined members are available without qualification. +The `Predef` object defines standard functions and type aliases for Scala programs. +It is implicitly imported, as described in [the chapter on name binding](02-identifiers-names-and-scopes.html), so that all its defined members are available without qualification. Its definition for the JVM environment conforms to the following signature: ```scala @@ -728,89 +632,70 @@ object Predef { ### Predefined Implicit Definitions The `Predef` object also contains a number of implicit definitions, which are available by default (because `Predef` is implicitly imported). -Implicit definitions come in two priorities. High-priority implicits are defined in the `Predef` class itself whereas low priority implicits are defined in a class inherited by `Predef`. The rules of -static [overloading resolution](06-expressions.html#overloading-resolution) -stipulate that, all other things being equal, implicit resolution -prefers high-priority implicits over low-priority ones. +Implicit definitions come in two priorities. +High-priority implicits are defined in the `Predef` class itself whereas low priority implicits are defined in a class inherited by `Predef`. +The rules of static [overloading resolution](06-expressions.html#overloading-resolution) stipulate that, all other things being equal, implicit resolution prefers high-priority implicits over low-priority ones. The available low-priority implicits include definitions falling into the following categories. -1. For every primitive type, a wrapper that takes values of that type - to instances of a `runtime.Rich*` class. For instance, values of type `Int` - can be implicitly converted to instances of class `runtime.RichInt`. +1. For every primitive type, a wrapper that takes values of that type to instances of a `runtime.Rich*` class. +For instance, values of type `Int` can be implicitly converted to instances of class `runtime.RichInt`. -1. For every array type with elements of primitive type, a wrapper that - takes the arrays of that type to instances of a `ArraySeq` class. For instance, values of type `Array[Float]` can be implicitly converted to instances of class `ArraySeq[Float]`. - There are also generic array wrappers that take elements - of type `Array[T]` for arbitrary `T` to `ArraySeq`s. +1. For every array type with elements of primitive type, a wrapper that takes the arrays of that type to instances of a `ArraySeq` class. +For instance, values of type `Array[Float]` can be implicitly converted to instances of class `ArraySeq[Float]`. +There are also generic array wrappers that take elements of type `Array[T]` for arbitrary `T` to `ArraySeq`s. 1. An implicit conversion from `String` to `WrappedString`. The available high-priority implicits include definitions falling into the following categories. - * An implicit wrapper that adds `ensuring` methods - with the following overloaded variants to type `Any`. - - ```scala - def ensuring(cond: Boolean): A = { assert(cond); x } - def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x } - def ensuring(cond: A => Boolean): A = { assert(cond(x)); x } - def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x } - ``` - - * An implicit wrapper that adds a `->` method with the following implementation - to type `Any`. - - ```scala - def -> [B](y: B): (A, B) = (x, y) - ``` - - * For every array type with elements of primitive type, a wrapper that - takes the arrays of that type to instances of a `runtime.ArrayOps` - class. For instance, values of type `Array[Float]` can be implicitly - converted to instances of class `runtime.ArrayOps[Float]`. There are - also generic array wrappers that take elements of type `Array[T]` for - arbitrary `T` to `ArrayOps`s. - - * An implicit wrapper that adds `+` and `formatted` method with the following - implementations to type `Any`. - - ```scala - def +(other: String) = String.valueOf(self) + other - def formatted(fmtstr: String): String = fmtstr format self - ``` - - * Numeric primitive conversions that implement the transitive closure of the - following mappings: - - ``` - Byte -> Short - Short -> Int - Char -> Int - Int -> Long - Long -> Float - Float -> Double - ``` - - * Boxing and unboxing conversions between primitive types and their boxed - versions: - - ``` - Byte <-> java.lang.Byte - Short <-> java.lang.Short - Char <-> java.lang.Character - Int <-> java.lang.Integer - Long <-> java.lang.Long - Float <-> java.lang.Float - Double <-> java.lang.Double - Boolean <-> java.lang.Boolean - ``` - - * An implicit definition that generates instances of type `T <:< T`, for - any type `T`. Here, `<:<` is a class defined as follows. - - ```scala - sealed abstract class <:<[-From, +To] extends (From => To) - ``` - - Implicit parameters of `<:<` types are typically used to implement type constraints. +* An implicit wrapper that adds `ensuring` methods with the following overloaded variants to type `Any`. +```scala +def ensuring(cond: Boolean): A = { assert(cond); x } +def ensuring(cond: Boolean, msg: Any): A = { assert(cond, msg); x } +def ensuring(cond: A => Boolean): A = { assert(cond(x)); x } +def ensuring(cond: A => Boolean, msg: Any): A = { assert(cond(x), msg); x } +``` + +* An implicit wrapper that adds a `->` method with the following implementation to type `Any`. +```scala +def -> [B](y: B): (A, B) = (x, y) +``` + +* For every array type with elements of primitive type, a wrapper that takes the arrays of that type to instances of a `runtime.ArrayOps` class. +For instance, values of type `Array[Float]` can be implicitly converted to instances of class `runtime.ArrayOps[Float]`. +There are also generic array wrappers that take elements of type `Array[T]` for arbitrary `T` to `ArrayOps`s. + +* An implicit wrapper that adds `+` and `formatted` method with the following implementations to type `Any`. +```scala +def +(other: String) = String.valueOf(self) + other +def formatted(fmtstr: String): String = fmtstr format self +``` + +* Numeric primitive conversions that implement the transitive closure of the following mappings: +``` +Byte -> Short +Short -> Int +Char -> Int +Int -> Long +Long -> Float +Float -> Double +``` + +* Boxing and unboxing conversions between primitive types and their boxed versions: +``` +Byte <-> java.lang.Byte +Short <-> java.lang.Short +Char <-> java.lang.Character +Int <-> java.lang.Integer +Long <-> java.lang.Long +Float <-> java.lang.Float +Double <-> java.lang.Double +Boolean <-> java.lang.Boolean +``` + +* An implicit definition that generates instances of type `T <:< T`, for any type `T`. Here, `<:<` is a class defined as follows. +```scala +sealed abstract class <:<[-From, +To] extends (From => To) +``` +Implicit parameters of `<:<` types are typically used to implement type constraints. diff --git a/docs/_spec/13-syntax-summary.md b/docs/_spec/13-syntax-summary.md index e799a6f579b3..7c1d394bd4e1 100644 --- a/docs/_spec/13-syntax-summary.md +++ b/docs/_spec/13-syntax-summary.md @@ -88,8 +88,7 @@ semi ::= ‘;’ | nl {nl} ## Context-free Syntax -The context-free syntax of Scala is given by the following EBNF -grammar: +The context-free syntax of Scala is given by the following EBNF grammar: ```ebnf Literal ::= [‘-’] integerLiteral diff --git a/docs/_spec/README.md b/docs/_spec/README.md index e1c7e3497601..5aa9240c6158 100644 --- a/docs/_spec/README.md +++ b/docs/_spec/README.md @@ -39,6 +39,10 @@ and open http://0.0.0.0:4000/ to view the spec. Jekyll will rebuild as you edit - Use of the appropriate unicode characters instead of the latex modifiers for accents, etc. is necessary. For example, é instead of `\'e`. - MathJAX errors will appear within the rendered DOM as span elements with class `mtext` and style attribute `color: red` applied. It is possible to search for this combination in the development tools of the browser of your choice. In chrome, CTRL+F / CMD+F within the inspect element panel allows you to do this. +- This document follows the "one sentence <=> one line" convention, with the following exceptions below. +- - A multiline code bloc is part of the sentence +- - An enumeration of links is long enough + ### Macro replacements: - While MathJAX just support LaTeX style command definition, it is recommended to not use this as it will likely cause issues with preparing the document for PDF or ebook distribution. From 75d671fe392c406851924f062d679ee98cd2c372 Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Wed, 12 Oct 2022 16:54:18 +0200 Subject: [PATCH 08/11] Replace function by method wherever possible --- docs/_spec/01-lexical-syntax.md | 2 +- docs/_spec/03-types.md | 2 +- .../04-basic-declarations-and-definitions.md | 42 +++++++++---------- docs/_spec/05-classes-and-objects.md | 2 +- docs/_spec/06-expressions.md | 32 +++++++------- docs/_spec/08-pattern-matching.md | 2 +- docs/_spec/12-the-scala-standard-library.md | 2 +- 7 files changed, 42 insertions(+), 42 deletions(-) diff --git a/docs/_spec/01-lexical-syntax.md b/docs/_spec/01-lexical-syntax.md index 032cf3703bb9..862e85a014be 100644 --- a/docs/_spec/01-lexical-syntax.md +++ b/docs/_spec/01-lexical-syntax.md @@ -234,7 +234,7 @@ A single new line token is accepted > (y: Int) = x + y > ``` > -> With an additional newline character, the same code is interpreted as an abstract function definition and a syntactically illegal statement: +> With an additional newline character, the same code is interpreted as an abstract method definition and a syntactically illegal statement: > > ```scala > def func(x: Int) diff --git a/docs/_spec/03-types.md b/docs/_spec/03-types.md index 664ddea49713..42157b176888 100644 --- a/docs/_spec/03-types.md +++ b/docs/_spec/03-types.md @@ -335,7 +335,7 @@ An argument type of the form ´\Rightarrow T´ represents a [call-by-name parame Function types associate to the right, e.g. ´S \Rightarrow T \Rightarrow U´ is the same as ´S \Rightarrow (T \Rightarrow U)´. -Function types are shorthands for class types that define `apply` functions. +Function types are shorthands for class types that define an `apply` method. Specifically, the ´n´-ary function type ´(T_1 , \ldots , T_n) \Rightarrow U´ is a shorthand for the class type `Function´_n´[´T_1´ , … , ´T_n´, ´U´]`. Such class types are defined in the Scala library for ´n´ between 0 and 22 as follows. diff --git a/docs/_spec/04-basic-declarations-and-definitions.md b/docs/_spec/04-basic-declarations-and-definitions.md index f9e55b15a59b..af98eef2a37d 100644 --- a/docs/_spec/04-basic-declarations-and-definitions.md +++ b/docs/_spec/04-basic-declarations-and-definitions.md @@ -183,7 +183,7 @@ VarDef ::= PatDef | ids ‘:’ Type ‘=’ ‘_’ ``` -A variable declaration `var ´x´: ´T´` is equivalent to the declarations of both a _getter function_ ´x´ *and* a _setter function_ `´x´_=`: +A variable declaration `var ´x´: ´T´` is equivalent to the declarations of both a _getter method_ ´x´ *and* a _setter method_ `´x´_=`: ```scala def ´x´: ´T´ @@ -215,9 +215,9 @@ The default value depends on the type ´T´ as follows: |`()` | `Unit` | |`null` | all other types | -When they occur as members of a template, both forms of variable definition also introduce a getter function ´x´ which returns the value currently assigned to the variable, as well as a setter function `´x´_=` which changes the value currently assigned to the variable. -The functions have the same signatures as for a variable declaration. -The template then has these getter and setter functions as members, whereas the original variable cannot be accessed directly as a template member. +When they occur as members of a template, both forms of variable definition also introduce a getter method ´x´ which returns the value currently assigned to the variable, as well as a setter method `´x´_=` which changes the value currently assigned to the variable. +The methods have the same signatures as for a variable declaration. +The template then has these getter and setter methods as members, whereas the original variable cannot be accessed directly as a template member. ###### Example @@ -287,7 +287,7 @@ A _type alias_ `type ´t´ = ´T´` defines ´t´ to be an alias name for the ty The left hand side of a type alias may have a type parameter clause, e.g. `type ´t´[´\mathit{tps}\,´] = ´T´`. The scope of a type parameter extends over the right hand side ´T´ and the type parameter clause ´\mathit{tps}´ itself. -The scope rules for [definitions](#basic-declarations-and-definitions) and [type parameters](#function-declarations-and-definitions) make it possible that a type name appears in its own bound or in its right-hand side. +The scope rules for [definitions](#basic-declarations-and-definitions) and [type parameters](#method-declarations-and-definitions) make it possible that a type name appears in its own bound or in its right-hand side. However, it is a static error if a type alias refers recursively to the defined type constructor itself. That is, the type ´T´ in a type alias `type ´t´[´\mathit{tps}\,´] = ´T´` may not refer directly or indirectly to the name ´t´. It is also an error if an abstract type is directly or indirectly its own upper or lower bound. @@ -346,7 +346,7 @@ VariantTypeParam ::= {Annotation} [‘+’ | ‘-’] TypeParam TypeParam ::= (id | ‘_’) [TypeParamClause] [‘>:’ Type] [‘<:’ Type] [‘:’ Type] ``` -Type parameters appear in type definitions, class definitions, and function definitions. +Type parameters appear in type definitions, class definitions, and method definitions. In this section we consider only type parameter definitions with lower bounds `>: ´L´` and upper bounds `<: ´U´` whereas a discussion of context bounds `: ´U´` and view bounds `<% ´U´` is deferred to [here](07-implicits.html#context-bounds-and-view-bounds). The most general form of a proper type parameter is @@ -497,7 +497,7 @@ abstract class OutputChannel[-A] { With that annotation, we have that `OutputChannel[AnyRef]` conforms to `OutputChannel[String]`. That is, a channel on which one can write any object can substitute for a channel on which one can write only strings. -## Function Declarations and Definitions +## Method Declarations and Definitions ```ebnf Dcl ::= ‘def’ FunDcl @@ -515,23 +515,23 @@ ParamType ::= Type | Type ‘*’ ``` -A _function declaration_ has the form `def ´f\,\mathit{psig}´: ´T´`, where ´f´ is the function's name, ´\mathit{psig}´ is its parameter signature and ´T´ is its result type. -A _function definition_ `def ´f\,\mathit{psig}´: ´T´ = ´e´` also includes a _function body_ ´e´, i.e. an expression which defines the function's result. +A _method declaration_ has the form `def ´f\,\mathit{psig}´: ´T´`, where ´f´ is the method's name, ´\mathit{psig}´ is its parameter signature and ´T´ is its result type. +A _method definition_ `def ´f\,\mathit{psig}´: ´T´ = ´e´` also includes a _method body_ ´e´, i.e. an expression which defines the method's result. A parameter signature consists of an optional type parameter clause `[´\mathit{tps}\,´]`, followed by zero or more value parameter clauses `(´\mathit{ps}_1´)...(´\mathit{ps}_n´)`. Such a declaration or definition introduces a value with a (possibly polymorphic) method type whose parameter types and result type are as given. -The type of the function body is expected to [conform](06-expressions.html#expression-typing) to the function's declared result type, if one is given. -If the function definition is not recursive, the result type may be omitted, in which case it is determined from the packed type of the function body. +The type of the method body is expected to [conform](06-expressions.html#expression-typing) to the method's declared result type, if one is given. +If the method definition is not recursive, the result type may be omitted, in which case it is determined from the packed type of the method body. A _type parameter clause_ ´\mathit{tps}´ consists of one or more [type declarations](#type-declarations-and-type-aliases), which introduce type parameters, possibly with bounds. -The scope of a type parameter includes the whole signature, including any of the type parameter bounds as well as the function body, if it is present. +The scope of a type parameter includes the whole signature, including any of the type parameter bounds as well as the method body, if it is present. A _value parameter clause_ ´\mathit{ps}´ consists of zero or more formal parameter bindings such as `´x´: ´T´` or `´x: T = e´`, which bind value parameters and associate them with their types. ### Default Arguments Each value parameter declaration may optionally define a default argument. -The default argument expression ´e´ is type-checked with an expected type ´T'´ obtained by replacing all occurrences of the function's type parameters in ´T´ by the undefined type. +The default argument expression ´e´ is type-checked with an expected type ´T'´ obtained by replacing all occurrences of the method's type parameters in ´T´ by the undefined type. For every parameter ´p_{i,j}´ with a default argument a method named `´f\$´default´\$´n` is generated which computes the default argument expression. Here, ´n´ denotes the parameter's position in the method declaration. @@ -555,7 +555,7 @@ def compare´\$´default´\$´1[T]: Int = 0 def compare´\$´default´\$´2[T](a: T): T = a ``` -The scope of a formal value parameter name ´x´ comprises all subsequent parameter clauses, as well as the method return type and the function body, if they are given. +The scope of a formal value parameter name ´x´ comprises all subsequent parameter clauses, as well as the method return type and the method body, if they are given. Both type parameter names and value parameter names must be pairwise distinct. A default value which depends on earlier parameters uses the actual arguments if they are provided, not the default arguments. @@ -582,7 +582,7 @@ ParamType ::= ‘=>’ Type The type of a value parameter may be prefixed by `=>`, e.g. `´x´: => ´T´`. The type of such a parameter is then the parameterless method type `=> ´T´`. -This indicates that the corresponding argument is not evaluated at the point of function application, but instead is evaluated at each use within the function. +This indicates that the corresponding argument is not evaluated at the point of method application, but instead is evaluated at each use within the method. That is, the argument is evaluated using _call-by-name_. The by-name modifier is disallowed for parameters of classes that carry a `val` or `var` prefix, including parameters of case classes for which a `val` prefix is implicitly generated. @@ -654,11 +654,11 @@ FunDcl ::= FunSig FunDef ::= FunSig [nl] ‘{’ Block ‘}’ ``` -Special syntax exists for procedures, i.e. functions that return the `Unit` value `()`. -A _procedure declaration_ is a function declaration where the result type is omitted. +Special syntax exists for procedures, i.e. methods that return the `Unit` value `()`. +A _procedure declaration_ is a method declaration where the result type is omitted. The result type is then implicitly completed to the `Unit` type. E.g., `def ´f´(´\mathit{ps}´)` is equivalent to `def ´f´(´\mathit{ps}´): Unit`. -A _procedure definition_ is a function definition where the result type and the equals sign are omitted; its defining expression must be a block. +A _procedure definition_ is a method definition where the result type and the equals sign are omitted; its defining expression must be a block. E.g., `def ´f´(´\mathit{ps}´) {´\mathit{stats}´}` is equivalent to `def ´f´(´\mathit{ps}´): Unit = {´\mathit{stats}´}`. ###### Example @@ -686,8 +686,8 @@ object Terminal extends Writer { ### Method Return Type Inference -A class member definition ´m´ that overrides some other function ´m'´ in a base class of ´C´ may leave out the return type, even if it is recursive. -In this case, the return type ´R'´ of the overridden function ´m'´, seen as a member of ´C´, is taken as the return type of ´m´ for each recursive invocation of ´m´. +A class member definition ´m´ that overrides some other method ´m'´ in a base class of ´C´ may leave out the return type, even if it is recursive. +In this case, the return type ´R'´ of the overridden method ´m'´, seen as a member of ´C´, is taken as the return type of ´m´ for each recursive invocation of ´m´. That way, a type ´R´ for the right-hand side of ´m´ can be determined, which is then taken as the return type of ´m´. Note that ´R´ may be different from ´R'´, as long as ´R´ conforms to ´R'´. @@ -709,7 +709,7 @@ Here, it is OK to leave out the result type of `factorial` in `C`, even though t \label{sec:overloaded-defs} \todo{change} -An overloaded definition is a set of ´n > 1´ value or function +An overloaded definition is a set of ´n > 1´ value or method definitions in the same statement sequence that define the same name, binding it to types `´T_1 \commadots T_n´`, respectively. The individual definitions are called _alternatives_. Overloaded diff --git a/docs/_spec/05-classes-and-objects.md b/docs/_spec/05-classes-and-objects.md index d89fcfb115ff..622f9dc8ae59 100644 --- a/docs/_spec/05-classes-and-objects.md +++ b/docs/_spec/05-classes-and-objects.md @@ -603,7 +603,7 @@ The self constructor invocation must construct a generic instance of the class. I.e. if the class in question has name ´C´ and type parameters `[´\mathit{tps}\,´]`, then a self constructor invocation must generate an instance of `´C´[´\mathit{tps}\,´]`; it is not permitted to instantiate formal type parameters. The signature and the self constructor invocation of a constructor definition are type-checked and evaluated in the scope which is in effect at the point of the enclosing class definition, augmented by any type parameters of the enclosing class and by any [early definitions](#early-definitions) of the enclosing template. -The rest of the constructor expression is type-checked and evaluated as a function body in the current class. +The rest of the constructor expression is type-checked and evaluated as a method body in the current class. If there are auxiliary constructors of a class ´C´, they form together with ´C´'s primary [constructor](#class-definitions) an overloaded constructor definition. The usual rules for [overloading resolution](06-expressions.html#overloading-resolution) apply for constructor invocations of ´C´, including for the self constructor invocations in the constructor expressions themselves. diff --git a/docs/_spec/06-expressions.md b/docs/_spec/06-expressions.md index 597756550e6f..92697e64f0ac 100644 --- a/docs/_spec/06-expressions.md +++ b/docs/_spec/06-expressions.md @@ -190,7 +190,7 @@ Then we have: Note that the `superB` method returns different results depending on whether `B` is mixed in with class `Root` or `A`. -## Function Applications +## Method Applications ```ebnf SimpleExpr ::= SimpleExpr1 ArgumentExprs @@ -201,8 +201,8 @@ ArgumentExprs ::= ‘(’ [Exprs] ‘)’ Exprs ::= Expr {‘,’ Expr} ``` -An application `´f(e_1, ..., e_m)´` applies the function `´f´` to the argument expressions `´e_1, ..., e_m´`. -For this expression to be well-typed, the function must be *applicable* to its arguments, which is defined next by case analysis on ´f´'s type. +An application `´f(e_1, ..., e_m)´` applies the expression `´f´` to the argument expressions `´e_1, ..., e_m´`. +For the overal expression to be well-typed, ´f´ must be *applicable* to its arguments, which is defined next by case analysis on ´f´'s type. If ´f´ has a method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´`, each argument expression ´e_i´ is typed with the corresponding parameter type ´T_i´ as expected type. Let ´S_i´ be the type of argument ´e_i´ ´(i = 1, ..., m)´. @@ -223,8 +223,8 @@ The value `´f´` is applicable to the given arguments if `´f´.apply` is appli The application `´f´(´e_1, ..., e_n´)` evaluates ´f´ and then each argument ´e_1, ..., e_n´ from left to right, except for arguments that correspond to a by-name parameter (see below). Each argument expression is converted to the type of its corresponding formal parameter. -After that, the application is rewritten to the function's right hand side, with actual arguments substituted for formal parameters. -The result of evaluating the rewritten right-hand side is finally converted to the function's declared result type, if one is given. +After that, the application is rewritten to the method's right hand side, with actual arguments substituted for formal parameters. +The result of evaluating the rewritten right-hand side is finally converted to the method's declared result type, if one is given. The case of a formal parameter with a parameterless method type `=> ´T´` is treated specially. In this case, the corresponding actual argument expression ´e´ is not evaluated before the application. @@ -232,7 +232,7 @@ Instead, every use of the formal parameter on the right-hand side of the rewrite In other words, the evaluation order for `=>`-parameters is _call-by-name_ whereas the evaluation order for normal parameters is _call-by-value_. Furthermore, it is required that ´e´'s [packed type](#expression-typing) conforms to the parameter type ´T´. The behavior of by-name parameters is preserved if the application is transformed into a block due to named or default arguments. -In this case, the local value for that parameter has the form `val ´y_i´ = () => ´e´` and the argument passed to the function is `´y_i´()`. +In this case, the local value for that parameter has the form `val ´y_i´ = () => ´e´` and the argument passed to the method is `´y_i´()`. The last argument in an application may be marked as a sequence argument, e.g. `´e´: _*`. Such an argument must correspond to a [repeated parameter](04-basic-declarations-and-definitions.html#repeated-parameters) of type `´S´*` and it must be the only argument matching this parameter (i.e. the number of formal parameters and actual arguments must be the same). @@ -243,7 +243,7 @@ When the application uses named arguments, the vararg parameter has to be specif If only a single argument is supplied, it may be supplied as a block expression and parentheses can be omitted, in the form `´f´ { block }`. This is valid when `f` has a single formal parameter or when all other formal parameters have default values. -A function application usually allocates a new frame on the program's run-time stack. +A method application usually allocates a new frame on the program's run-time stack. However, if a local method or a final method calls itself as its last action, the call is executed using the stack-frame of the caller. ###### Example @@ -304,7 +304,7 @@ The result of transforming ´f´ is a block of the form where every argument in ´(\mathit{args}\_1), ..., (\mathit{args}\_l)´ is a reference to one of the values ´x_1, ..., x_k´. To integrate the current application into the block, first a value definition using a fresh name ´y_i´ is created for every argument in ´e_1, ..., e_m´, which is initialised to ´e_i´ for positional arguments and to ´e'_i´ for named arguments of the form `´x_i=e'_i´`. -Then, for every parameter which is not specified by the argument list, a value definition using a fresh name ´z_i´ is created, which is initialized using the method computing the [default argument](04-basic-declarations-and-definitions.html#function-declarations-and-definitions) of this parameter. +Then, for every parameter which is not specified by the argument list, a value definition using a fresh name ´z_i´ is created, which is initialized using the method computing the [default argument](04-basic-declarations-and-definitions.html#method-declarations-and-definitions) of this parameter. Let ´\mathit{args}´ be a permutation of the generated names ´y_i´ and ´z_i´ such such that the position of each name matches the position of its corresponding parameter in the method type `(´p_1:T_1, ..., p_n:T_n´)´U´`. The final result of the transformation is a block of the form @@ -366,13 +366,13 @@ Note that a space is necessary between a method name and the trailing underscore SimpleExpr ::= SimpleExpr TypeArgs ``` -A _type application_ `´e´[´T_1, ..., T_n´]` instantiates a polymorphic value ´e´ of type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´` with argument types `´T_1, ..., T_n´`. +A _type application_ `´e´[´T_1, ..., T_n´]` instantiates a polymorphic method ´e´ of type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´S´` with argument types `´T_1, ..., T_n´`. Every argument type ´T_i´ must obey the corresponding bounds ´L_i´ and ´U_i´. That is, for each ´i = 1, ..., n´, we must have ´\sigma L_i <: T_i <: \sigma U_i´, where ´\sigma´ is the substitution ´[a_1 := T_1, ..., a_n := T_n]´. The type of the application is ´\sigma S´. -If the function part ´e´ is of some value type, the type application is taken to be equivalent to `´e´.apply[´T_1 , ...,´ T´_n´]`, i.e. the application of an `apply` method defined by ´e´. +If ´e´ is not a method, and is instead of some value type, the type application is taken to be equivalent to `´e´.apply[´T_1 , ...,´ T´_n´]`, i.e. the application of an `apply` method defined by ´e´. Type applications can be omitted if [local type inference](#local-type-inference) can infer best type parameters for a polymorphic method from the types of the actual method arguments and the expected result type. @@ -1146,12 +1146,12 @@ Otherwise, if ´e´ has method type ´()T´, it is implicitly applied to the emp ### Overloading Resolution If an identifier or selection ´e´ references several members of a class, the context of the reference is used to identify a unique member. -The way this is done depends on whether or not ´e´ is used as a function. +The way this is done depends on whether or not ´e´ is used as a method. Let ´\mathscr{A}´ be the set of members referenced by ´e´. Assume first that ´e´ appears as a function in an application, as in `´e´(´e_1´, ..., ´e_m´)`. -One first determines the set of functions that is potentially [applicable](#function-applications) based on the _shape_ of the arguments. +One first determines the set of methods that are potentially [applicable](#method-applications) based on the _shape_ of the arguments. The *shape* of an argument expression ´e´, written ´\mathit{shape}(e)´, is a type that is defined as follows: - For a function expression `(´p_1´: ´T_1, ..., p_n´: ´T_n´) => ´b´: (Any, ..., Any) => ´\mathit{shape}(b)´`, where `Any` occurs ´n´ times in the argument type. @@ -1159,7 +1159,7 @@ The *shape* of an argument expression ´e´, written ´\mathit{shape}(e)´, is - For a named argument `´n´ = ´e´`: ´\mathit{shape}(e)´. - For all other expressions: `Nothing`. -Let ´\mathscr{B}´ be the set of alternatives in ´\mathscr{A}´ that are [_applicable_](#function-applications) to expressions ´(e_1, ..., e_n)´ of types ´(\mathit{shape}(e_1), ..., \mathit{shape}(e_n))´. +Let ´\mathscr{B}´ be the set of alternatives in ´\mathscr{A}´ that are [_applicable_](#method-applications) to expressions ´(e_1, ..., e_n)´ of types ´(\mathit{shape}(e_1), ..., \mathit{shape}(e_n))´. If there is precisely one alternative in ´\mathscr{B}´, that alternative is chosen. Otherwise, let ´S_1, ..., S_m´ be the list of types obtained by typing each argument as follows. @@ -1197,7 +1197,7 @@ question: given so the method is not more specific than the value. --> -- A parameterized method ´m´ of type `(´p_1:T_1, ..., p_n:T_n´)´U´` is _as specific as_ some other member ´m'´ of type ´S´ if ´m'´ is [applicable](#function-applications) to arguments `(´p_1, ..., p_n´)` of types ´T_1, ..., T_n´. +- A parameterized method ´m´ of type `(´p_1:T_1, ..., p_n:T_n´)´U´` is _as specific as_ some other member ´m'´ of type ´S´ if ´m'´ is [applicable](#method-applications) to arguments `(´p_1, ..., p_n´)` of types ´T_1, ..., T_n´. - A polymorphic method of type `[´a_1´ >: ´L_1´ <: ´U_1, ..., a_n´ >: ´L_n´ <: ´U_n´]´T´` is as specific as some other member of type ´S´ if ´T´ is as specific as ´S´ under the assumption that for ´i = 1, ..., n´ each ´a_i´ is an abstract type name bounded from below by ´L_i´ and from above by ´U_i´. - A member of any other type is always as specific as a parameterized method or a polymorphic method. - Given two members of types ´T´ and ´U´ which are neither parameterized nor polymorphic method types, the member of type ´T´ is as specific as the member of type ´U´ if the existential dual of ´T´ conforms to the existential dual of ´U´. @@ -1220,12 +1220,12 @@ An alternative ´A´ is _more specific_ than an alternative ´B´ if the relativ It is an error if there is no alternative in ´\mathscr{CC}´ which is more specific than all other alternatives in ´\mathscr{CC}´. -Assume next that ´e´ appears as a function in a type application, as in `´e´[´\mathit{targs}\,´]`. +Assume next that ´e´ appears as a method in a type application, as in `´e´[´\mathit{targs}\,´]`. Then all alternatives in ´\mathscr{A}´ which take the same number of type parameters as there are type arguments in ´\mathit{targs}´ are chosen. It is an error if no such alternative exists. If there are several such alternatives, overloading resolution is applied again to the whole expression `´e´[´\mathit{targs}\,´]`. -Assume finally that ´e´ does not appear as a function in either an application or a type application. +Assume finally that ´e´ does not appear as a method in either an application or a type application. If an expected type is given, let ´\mathscr{B}´ be the set of those alternatives in ´\mathscr{A}´ which are [compatible](03-types.html#compatibility) to it. Otherwise, let ´\mathscr{B}´ be the same as ´\mathscr{A}´. In this last case we choose the most specific alternative among all alternatives in ´\mathscr{B}´. diff --git a/docs/_spec/08-pattern-matching.md b/docs/_spec/08-pattern-matching.md index 45d777f584a0..97fb73d58b06 100644 --- a/docs/_spec/08-pattern-matching.md +++ b/docs/_spec/08-pattern-matching.md @@ -474,7 +474,7 @@ The expected type of the pattern `y: Number` is `Term[B]`. The type `Number` does not conform to `Term[B]`; hence Case 2 of the rules above applies. This means that `B` is treated as another type variable for which subtype constraints are inferred. In our case the applicable constraint is `Number <: Term[B]`, which entails `B = Int`. Hence, `B` is treated in the case clause as an abstract type with lower and upper bound `Int`. -Therefore, the right hand side of the case clause, `y.n`, of type `Int`, is found to conform to the function's declared result type, `Number`. +Therefore, the right hand side of the case clause, `y.n`, of type `Int`, is found to conform to the method's declared result type, `Number`. ## Pattern Matching Expressions diff --git a/docs/_spec/12-the-scala-standard-library.md b/docs/_spec/12-the-scala-standard-library.md index 086d396ba4dd..401735286a51 100644 --- a/docs/_spec/12-the-scala-standard-library.md +++ b/docs/_spec/12-the-scala-standard-library.md @@ -529,7 +529,7 @@ trait Node { ## The `Predef` Object -The `Predef` object defines standard functions and type aliases for Scala programs. +The `Predef` object defines standard methods and type aliases for Scala programs. It is implicitly imported, as described in [the chapter on name binding](02-identifiers-names-and-scopes.html), so that all its defined members are available without qualification. Its definition for the JVM environment conforms to the following signature: From ac6fcafdcd35deddaf5e11319c172c5641904838 Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Fri, 3 Feb 2023 15:11:31 +0100 Subject: [PATCH 09/11] Update readme --- docs/_spec/README.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/_spec/README.md b/docs/_spec/README.md index 5aa9240c6158..b9eba413f8a2 100644 --- a/docs/_spec/README.md +++ b/docs/_spec/README.md @@ -1,4 +1,6 @@ -# Scala Language Reference +# WIP Scala 3 Language Specification + +**This is still a work in progress, and should *not* be regarded as a source of truth.** First of all, the language specification is meant to be correct, precise and clear. @@ -16,9 +18,6 @@ We aim to track the configuration GitHub Pages uses but differences may arise as ## Building - -Travis CI builds the spec automatically after every merged pull release and publishes to https://www.scala-lang.org/files/archive/spec/2.13/. - To preview locally, run the following commands in the docs/_spec subfolder: @@ -40,8 +39,16 @@ and open http://0.0.0.0:4000/ to view the spec. Jekyll will rebuild as you edit - MathJAX errors will appear within the rendered DOM as span elements with class `mtext` and style attribute `color: red` applied. It is possible to search for this combination in the development tools of the browser of your choice. In chrome, CTRL+F / CMD+F within the inspect element panel allows you to do this. - This document follows the "one sentence <=> one line" convention, with the following exceptions below. -- - A multiline code bloc is part of the sentence -- - An enumeration of links is long enough + - A multiline code block is part of the sentence + - An enumeration of links is long enough + +- Whenever doing an enumeration of the kind "a, ..., z", follow the following conventions: + - It should always be "separator whitespace period period period separator whitespace", for example `, ..., ` or `,\n...,\n` for multiline. + - If in a code block, only the elements (a and z above) should be in math mode (between forward ticks) + - If in a math expression, the whole thing should be in a single math mode + - Look at the [Tuple Types section](docs/_spec/03-types.html#tuple-types) for an example of the different cases above. + +- Try to use "Note" blocks to point out logical conclusions that are not obvious, for examples, look at the [Tuple Types section](docs/_spec/03-types.html#tuple-types). ### Macro replacements: @@ -51,7 +58,7 @@ and open http://0.0.0.0:4000/ to view the spec. Jekyll will rebuild as you edit - As MathJAX has no support for slanted font (latex command \sl), so in all instances this should be replaced with \mathit{} - The macro \U{ABCD} used for unicode character references can be replaced with \\uABCD. - The macro \URange{ABCD}{DCBA} used for unicode character ranges can be replaced with \\uABCD-\\uDBCA. -- The macro \commadots can be replaced with ` , … , `. +- The macro \commadots can be replaced with ` , … , ` (But should not, see above). - There is no adequate replacement for `\textsc{...}` (small caps) in pandoc markdown. While unicode contains a number of small capital letters, it is notably missing Q and X as these glyphs are intended for phonetic spelling, therefore these cannot be reliably used. For now, the best option is to use underscore emphasis and capitalise the text manually, `_LIKE THIS_`. ### Unicode Character replacements From ec261b64f50b77d69d1ad4c57b05aeb9e4691c7d Mon Sep 17 00:00:00 2001 From: Quentin Bernet Date: Fri, 3 Feb 2023 15:36:31 +0100 Subject: [PATCH 10/11] Remove travis key --- docs/_spec/id_dsa_travis.enc | 68 ------------------------------------ 1 file changed, 68 deletions(-) delete mode 100644 docs/_spec/id_dsa_travis.enc diff --git a/docs/_spec/id_dsa_travis.enc b/docs/_spec/id_dsa_travis.enc deleted file mode 100644 index 6709463580af..000000000000 --- a/docs/_spec/id_dsa_travis.enc +++ /dev/null @@ -1,68 +0,0 @@ -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 From 9db5c9e66d05a6f6d0a75aa7ca1cd94914ec1d57 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 6 Feb 2023 15:26:17 +0100 Subject: [PATCH 11/11] install correct sass-embedded --- docs/_spec/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/_spec/Dockerfile b/docs/_spec/Dockerfile index a08c5d0e7f98..1fc28081c59f 100644 --- a/docs/_spec/Dockerfile +++ b/docs/_spec/Dockerfile @@ -5,7 +5,9 @@ RUN apt-get install -y curl \ && apt-get install -y nodejs \ && curl -L https://www.npmjs.com/install.sh | sh -RUN gem install bundler:1.17.2 jekyll +RUN gem update --system +RUN gem install sass-embedded -v 1.58.0 +RUN gem install bundler:1.17.2 jekyll WORKDIR /srv/jekyll
  • a@s{PF5LiM~Zls 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 ST-$`aYk)Swf|ItD{i> literal 0 HcmV?d00001 diff --git a/docs/_spec/public/images/github-logo@2x.png b/docs/_spec/public/images/github-logo@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..285b0fee2f32c760121718e28cc489c6eb2ca884 GIT binary patch literal 1753 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%u1Od5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|80+w{G(j&jGsViy$k^G<#l*G&eP`1g19yq1PCvUQklVEdbi=l3J8mmYU*Ll%J~r_OewbZnqfVG!Lpb z1-Dxaaq86vIz}H9u}BdO69T3l5EGtkfgE_kPt60S_99@i-f;Hl9$;?q^>lFzskpUf zy0=GYph(;MuWM(l*OpYv;1Wh}Z97|oif!##Yc~M3ZzlPT7%udh43R=Mn z+0q^?P@kgY%5Tc?Q zr#2OBkZo~bj9^kZAn}5E?gCjG#>ev(bu~zcG*uaheas8`u6Ckd)LtT$?b3nD0M?)> z^-OyhZ4)N!OI^S*rI9DJTH-d)6>i~Jay5u;0RSi>0v#Ek& z-?^n{qb9KWt=f_AIBRx;cG{Ci)`vfp-&;Q0uSnw(-xHG`$F^Pla(&g0>1!EgPRq2b z;S_pVpD`_5e+T=o18YA0XPkd9_CoTlJK^gO|5RJ{bK!sSg4z6OXW6eyMef-;ga1yX z>~7uXd+G;y<1sH$o)EM=e{nS_>qO#(X zcpUf9nTHQ;Sf$YJzp9^UlFuH+xXmsO6Ixx0yL^9YDDbHDE~r;ya;w;X$K=ox@36ZS{|-9n=yv@3q_5#$tLYX2a#0 zl~?V0{)xN@e=2)s+mU%)i);jzEmB(*!yfiwpHR;c!=jVi{kvo?pUp}ul6fv$D&cvp zsKxrRquu%Bx(kc?BC{`To8N5ltjLF5;Kz+o_l5T!p3`W=&*XH*@X)F2XK(UWh(4$hF3l=El6>jguDa*k zf(xdvcq1&#{i34j^_~<%`{ma*9gNFcswfw?^N+3kv$ET)^BThpUa7u_XJljGYQA-< Te@gmWP-Wxk>gTe~DWM4f?xCf( literal 0 HcmV?d00001 diff --git a/docs/_spec/public/images/scala-spiral-white.png b/docs/_spec/public/images/scala-spiral-white.png new file mode 100644 index 0000000000000000000000000000000000000000..46aaf80824c1b820733039260d6e37733a276a32 GIT binary patch literal 1442 zcmeAS@N?(olHy`uVBq!ia0vp^azJdr!3HGRrk#2Mq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1Ffc1+hD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Keo`G(%fti7VnW3Jc zv5C34xsHO7fuVuEfswwUk*=Y+m9dePfq?=PC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2DR zmzV368|&p4rRy77T3Uk4Ff!5ws?aU2%qvN((9J7WhMC}!TAW;zSx}OhpQivaF)=B> zw8T~k=u(Imatq+b<`qMO2^e7d6^RAATTyF! zZ>Ia|Gds#0^9@=kbR}BDNm=EH{<3m zb;TBGN6#x&Zu30Vgi}}VzU@&qDL!rc&42aAn`c)VEn3EPcH7$}_YZMIux*P!#1g?= zIor2F)k&N^*dfmSOu9>Jlf*8G?*5Nf@1E>GQSzh ztaB3>N`fW+8O}9m2(-I$e4qFh0~;SljxEh@7mg%!eyDu@@{9L1uVV*I!j~~$*}1V% zWs616?ulCuPLu3dt+{QLq8)?h{v-Mc@^6})3tml)aD8N$Y?%C}W^G&ir2eUY* z=}z>EkK}naw@ZFT*!MYSSyL_9UoLs~)XbVQ?TOv`?#(?eCzVf5lWboG)I4D)ulGlx z$2mI=dE}&Y95G3}5onbtz{}HZcIniL?xK}lf7VXhc=Jren@78~-(N_ZcdK{GrzZmH z)2jlltJIqIS_%9wFT9n%(dN~frl}MBjVhh)ut+;`oL;?jn&6DI2g?<_cK+?t<+|jv zdVRL(VlVr3J#AWfQ)jvEj4z$XTD~PRCBWwK)9(Kw2@EFeJ;v9I8=FC;rl+f)%Q~lo FCIHvI5+DEo literal 0 HcmV?d00001 diff --git a/docs/_spec/public/octicons/LICENSE.txt b/docs/_spec/public/octicons/LICENSE.txt new file mode 100644 index 000000000000..259b43d14de3 --- /dev/null +++ b/docs/_spec/public/octicons/LICENSE.txt @@ -0,0 +1,9 @@ +(c) 2012-2014 GitHub + +When using the GitHub logos, be sure to follow the GitHub logo guidelines (https://github.com/logos) + +Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL) +Applies to all font files + +Code License: MIT (http://choosealicense.com/licenses/mit/) +Applies to all other files diff --git a/docs/_spec/public/octicons/octicons.css b/docs/_spec/public/octicons/octicons.css new file mode 100644 index 000000000000..a5dcd153a856 --- /dev/null +++ b/docs/_spec/public/octicons/octicons.css @@ -0,0 +1,235 @@ +@font-face { + font-family: 'octicons'; + src: url('octicons.eot?#iefix') format('embedded-opentype'), + url('octicons.woff') format('woff'), + url('octicons.ttf') format('truetype'), + url('octicons.svg#octicons') format('svg'); + font-weight: normal; + font-style: normal; +} + +/* + +.octicon is optimized for 16px. +.mega-octicon is optimized for 32px but can be used larger. + +*/ +.octicon, .mega-octicon { + font: normal normal normal 16px/1 octicons; + display: inline-block; + text-decoration: none; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.mega-octicon { font-size: 32px; } + + +.octicon-alert:before { content: '\f02d'} /*  */ +.octicon-alignment-align:before { content: '\f08a'} /*  */ +.octicon-alignment-aligned-to:before { content: '\f08e'} /*  */ +.octicon-alignment-unalign:before { content: '\f08b'} /*  */ +.octicon-arrow-down:before { content: '\f03f'} /*  */ +.octicon-arrow-left:before { content: '\f040'} /*  */ +.octicon-arrow-right:before { content: '\f03e'} /*  */ +.octicon-arrow-small-down:before { content: '\f0a0'} /*  */ +.octicon-arrow-small-left:before { content: '\f0a1'} /*  */ +.octicon-arrow-small-right:before { content: '\f071'} /*  */ +.octicon-arrow-small-up:before { content: '\f09f'} /*  */ +.octicon-arrow-up:before { content: '\f03d'} /*  */ +.octicon-beer:before { content: '\f069'} /*  */ +.octicon-book:before { content: '\f007'} /*  */ +.octicon-bookmark:before { content: '\f07b'} /*  */ +.octicon-briefcase:before { content: '\f0d3'} /*  */ +.octicon-broadcast:before { content: '\f048'} /*  */ +.octicon-browser:before { content: '\f0c5'} /*  */ +.octicon-bug:before { content: '\f091'} /*  */ +.octicon-calendar:before { content: '\f068'} /*  */ +.octicon-check:before { content: '\f03a'} /*  */ +.octicon-checklist:before { content: '\f076'} /*  */ +.octicon-chevron-down:before { content: '\f0a3'} /*  */ +.octicon-chevron-left:before { content: '\f0a4'} /*  */ +.octicon-chevron-right:before { content: '\f078'} /*  */ +.octicon-chevron-up:before { content: '\f0a2'} /*  */ +.octicon-circle-slash:before { content: '\f084'} /*  */ +.octicon-circuit-board:before { content: '\f0d6'} /*  */ +.octicon-clippy:before { content: '\f035'} /*  */ +.octicon-clock:before { content: '\f046'} /*  */ +.octicon-cloud-download:before { content: '\f00b'} /*  */ +.octicon-cloud-upload:before { content: '\f00c'} /*  */ +.octicon-code:before { content: '\f05f'} /*  */ +.octicon-color-mode:before { content: '\f065'} /*  */ +.octicon-comment-add:before, +.octicon-comment:before { content: '\f02b'} /*  */ +.octicon-comment-discussion:before { content: '\f04f'} /*  */ +.octicon-credit-card:before { content: '\f045'} /*  */ +.octicon-dash:before { content: '\f0ca'} /*  */ +.octicon-dashboard:before { content: '\f07d'} /*  */ +.octicon-database:before { content: '\f096'} /*  */ +.octicon-device-camera:before { content: '\f056'} /*  */ +.octicon-device-camera-video:before { content: '\f057'} /*  */ +.octicon-device-desktop:before { content: '\f27c'} /*  */ +.octicon-device-mobile:before { content: '\f038'} /*  */ +.octicon-diff:before { content: '\f04d'} /*  */ +.octicon-diff-added:before { content: '\f06b'} /*  */ +.octicon-diff-ignored:before { content: '\f099'} /*  */ +.octicon-diff-modified:before { content: '\f06d'} /*  */ +.octicon-diff-removed:before { content: '\f06c'} /*  */ +.octicon-diff-renamed:before { content: '\f06e'} /*  */ +.octicon-ellipsis:before { content: '\f09a'} /*  */ +.octicon-eye-unwatch:before, +.octicon-eye-watch:before, +.octicon-eye:before { content: '\f04e'} /*  */ +.octicon-file-binary:before { content: '\f094'} /*  */ +.octicon-file-code:before { content: '\f010'} /*  */ +.octicon-file-directory:before { content: '\f016'} /*  */ +.octicon-file-media:before { content: '\f012'} /*  */ +.octicon-file-pdf:before { content: '\f014'} /*  */ +.octicon-file-submodule:before { content: '\f017'} /*  */ +.octicon-file-symlink-directory:before { content: '\f0b1'} /*  */ +.octicon-file-symlink-file:before { content: '\f0b0'} /*  */ +.octicon-file-text:before { content: '\f011'} /*  */ +.octicon-file-zip:before { content: '\f013'} /*  */ +.octicon-flame:before { content: '\f0d2'} /*  */ +.octicon-fold:before { content: '\f0cc'} /*  */ +.octicon-gear:before { content: '\f02f'} /*  */ +.octicon-gift:before { content: '\f042'} /*  */ +.octicon-gist:before { content: '\f00e'} /*  */ +.octicon-gist-secret:before { content: '\f08c'} /*  */ +.octicon-git-branch-create:before, +.octicon-git-branch-delete:before, +.octicon-git-branch:before { content: '\f020'} /*  */ +.octicon-git-commit:before { content: '\f01f'} /*  */ +.octicon-git-compare:before { content: '\f0ac'} /*  */ +.octicon-git-merge:before { content: '\f023'} /*  */ +.octicon-git-pull-request-abandoned:before, +.octicon-git-pull-request:before { content: '\f009'} /*  */ +.octicon-globe:before { content: '\f0b6'} /*  */ +.octicon-graph:before { content: '\f043'} /*  */ +.octicon-heart:before { content: '\2665'} /* ♥ */ +.octicon-history:before { content: '\f07e'} /*  */ +.octicon-home:before { content: '\f08d'} /*  */ +.octicon-horizontal-rule:before { content: '\f070'} /*  */ +.octicon-hourglass:before { content: '\f09e'} /*  */ +.octicon-hubot:before { content: '\f09d'} /*  */ +.octicon-inbox:before { content: '\f0cf'} /*  */ +.octicon-info:before { content: '\f059'} /*  */ +.octicon-issue-closed:before { content: '\f028'} /*  */ +.octicon-issue-opened:before { content: '\f026'} /*  */ +.octicon-issue-reopened:before { content: '\f027'} /*  */ +.octicon-jersey:before { content: '\f019'} /*  */ +.octicon-jump-down:before { content: '\f072'} /*  */ +.octicon-jump-left:before { content: '\f0a5'} /*  */ +.octicon-jump-right:before { content: '\f0a6'} /*  */ +.octicon-jump-up:before { content: '\f073'} /*  */ +.octicon-key:before { content: '\f049'} /*  */ +.octicon-keyboard:before { content: '\f00d'} /*  */ +.octicon-law:before { content: '\f0d8'} /* */ +.octicon-light-bulb:before { content: '\f000'} /*  */ +.octicon-link:before { content: '\f05c'} /*  */ +.octicon-link-external:before { content: '\f07f'} /*  */ +.octicon-list-ordered:before { content: '\f062'} /*  */ +.octicon-list-unordered:before { content: '\f061'} /*  */ +.octicon-location:before { content: '\f060'} /*  */ +.octicon-gist-private:before, +.octicon-mirror-private:before, +.octicon-git-fork-private:before, +.octicon-lock:before { content: '\f06a'} /*  */ +.octicon-logo-github:before { content: '\f092'} /*  */ +.octicon-mail:before { content: '\f03b'} /*  */ +.octicon-mail-read:before { content: '\f03c'} /*  */ +.octicon-mail-reply:before { content: '\f051'} /*  */ +.octicon-mark-github:before { content: '\f00a'} /*  */ +.octicon-markdown:before { content: '\f0c9'} /*  */ +.octicon-megaphone:before { content: '\f077'} /*  */ +.octicon-mention:before { content: '\f0be'} /*  */ +.octicon-microscope:before { content: '\f089'} /*  */ +.octicon-milestone:before { content: '\f075'} /*  */ +.octicon-mirror-public:before, +.octicon-mirror:before { content: '\f024'} /*  */ +.octicon-mortar-board:before { content: '\f0d7'} /* */ +.octicon-move-down:before { content: '\f0a8'} /*  */ +.octicon-move-left:before { content: '\f074'} /*  */ +.octicon-move-right:before { content: '\f0a9'} /*  */ +.octicon-move-up:before { content: '\f0a7'} /*  */ +.octicon-mute:before { content: '\f080'} /*  */ +.octicon-no-newline:before { content: '\f09c'} /*  */ +.octicon-octoface:before { content: '\f008'} /*  */ +.octicon-organization:before { content: '\f037'} /*  */ +.octicon-package:before { content: '\f0c4'} /*  */ +.octicon-paintcan:before { content: '\f0d1'} /*  */ +.octicon-pencil:before { content: '\f058'} /*  */ +.octicon-person-add:before, +.octicon-person-follow:before, +.octicon-person:before { content: '\f018'} /*  */ +.octicon-pin:before { content: '\f041'} /*  */ +.octicon-playback-fast-forward:before { content: '\f0bd'} /*  */ +.octicon-playback-pause:before { content: '\f0bb'} /*  */ +.octicon-playback-play:before { content: '\f0bf'} /*  */ +.octicon-playback-rewind:before { content: '\f0bc'} /*  */ +.octicon-plug:before { content: '\f0d4'} /*  */ +.octicon-repo-create:before, +.octicon-gist-new:before, +.octicon-file-directory-create:before, +.octicon-file-add:before, +.octicon-plus:before { content: '\f05d'} /*  */ +.octicon-podium:before { content: '\f0af'} /*  */ +.octicon-primitive-dot:before { content: '\f052'} /*  */ +.octicon-primitive-square:before { content: '\f053'} /*  */ +.octicon-pulse:before { content: '\f085'} /*  */ +.octicon-puzzle:before { content: '\f0c0'} /*  */ +.octicon-question:before { content: '\f02c'} /*  */ +.octicon-quote:before { content: '\f063'} /*  */ +.octicon-radio-tower:before { content: '\f030'} /*  */ +.octicon-repo-delete:before, +.octicon-repo:before { content: '\f001'} /*  */ +.octicon-repo-clone:before { content: '\f04c'} /*  */ +.octicon-repo-force-push:before { content: '\f04a'} /*  */ +.octicon-gist-fork:before, +.octicon-repo-forked:before { content: '\f002'} /*  */ +.octicon-repo-pull:before { content: '\f006'} /*  */ +.octicon-repo-push:before { content: '\f005'} /*  */ +.octicon-rocket:before { content: '\f033'} /*  */ +.octicon-rss:before { content: '\f034'} /*  */ +.octicon-ruby:before { content: '\f047'} /*  */ +.octicon-screen-full:before { content: '\f066'} /*  */ +.octicon-screen-normal:before { content: '\f067'} /*  */ +.octicon-search-save:before, +.octicon-search:before { content: '\f02e'} /*  */ +.octicon-server:before { content: '\f097'} /*  */ +.octicon-settings:before { content: '\f07c'} /*  */ +.octicon-log-in:before, +.octicon-sign-in:before { content: '\f036'} /*  */ +.octicon-log-out:before, +.octicon-sign-out:before { content: '\f032'} /*  */ +.octicon-split:before { content: '\f0c6'} /*  */ +.octicon-squirrel:before { content: '\f0b2'} /*  */ +.octicon-star-add:before, +.octicon-star-delete:before, +.octicon-star:before { content: '\f02a'} /*  */ +.octicon-steps:before { content: '\f0c7'} /*  */ +.octicon-stop:before { content: '\f08f'} /*  */ +.octicon-repo-sync:before, +.octicon-sync:before { content: '\f087'} /*  */ +.octicon-tag-remove:before, +.octicon-tag-add:before, +.octicon-tag:before { content: '\f015'} /*  */ +.octicon-telescope:before { content: '\f088'} /*  */ +.octicon-terminal:before { content: '\f0c8'} /*  */ +.octicon-three-bars:before { content: '\f05e'} /*  */ +.octicon-tools:before { content: '\f031'} /*  */ +.octicon-trashcan:before { content: '\f0d0'} /*  */ +.octicon-triangle-down:before { content: '\f05b'} /*  */ +.octicon-triangle-left:before { content: '\f044'} /*  */ +.octicon-triangle-right:before { content: '\f05a'} /*  */ +.octicon-triangle-up:before { content: '\f0aa'} /*  */ +.octicon-unfold:before { content: '\f039'} /*  */ +.octicon-unmute:before { content: '\f0ba'} /*  */ +.octicon-versions:before { content: '\f064'} /*  */ +.octicon-remove-close:before, +.octicon-x:before { content: '\f081'} /*  */ +.octicon-zap:before { content: '\26A1'} /* ⚡ */ diff --git a/docs/_spec/public/octicons/octicons.eot b/docs/_spec/public/octicons/octicons.eot new file mode 100644 index 0000000000000000000000000000000000000000..22881a8b6c4342720d2d4318ef5887c8abbfc8a2 GIT binary patch literal 31440 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 + + + +(c) 2012-2014 GitHub + +When using the GitHub logos, be sure to follow the GitHub logo guidelines (https://github.com/logos) + +Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL) +Applies to all font files + +Code License: MIT (http://choosealicense.com/licenses/mit/) +Applies to all other files + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_spec/public/octicons/octicons.ttf b/docs/_spec/public/octicons/octicons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..189ca2813d4920f3be1bd1a43b19a09740d1eb2c GIT binary patch literal 31272 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 F{||dHN2&k- literal 0 HcmV?d00001 diff --git a/docs/_spec/public/octicons/octicons.woff b/docs/_spec/public/octicons/octicons.woff new file mode 100644 index 0000000000000000000000000000000000000000..2b770e429f38d820c1916bb395f7e72ddafa60c5 GIT binary patch literal 17492 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/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/docs/_spec/public/scripts/main.js b/docs/_spec/public/scripts/main.js new file mode 100644 index 000000000000..9ade9c770f1e --- /dev/null +++ b/docs/_spec/public/scripts/main.js @@ -0,0 +1,71 @@ +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(); + } +} + +// ignore when using wkhtmltopdf, or it won't work... +if(window.jekyllEnv !== 'spec-pdf') { + $('#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: [] +}); + +// KaTeX configuration +document.addEventListener("DOMContentLoaded", function() { + renderMathInElement(document.body, { + delimiters: [ + {left: "´", right: "´", display: false}, // "display: false" -> inline + {left: "$$", right: "$$", display: true} + ], + ignoredTags: ['script', 'noscript', 'style', 'textarea'], + }); + // syntax highlighting after KaTeX is loaded, + // so that math can be used in code blocks + hljs.initHighlighting(); + $("pre nobr").addClass("fixws"); + // point when all necessary js is done, so PDF to be rendered + window.status = "loaded"; +}); + +$("#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/docs/_spec/public/scripts/toc.js b/docs/_spec/public/scripts/toc.js new file mode 100644 index 000000000000..5b0bded12cfc --- /dev/null +++ b/docs/_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).on('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) + .on('click', function(e) { + $(window).off('scroll', highlightOnScroll); + scrollTo(e, function() { + $(window).on('scroll', highlightOnScroll); + }); + el.trigger('selected', $(this).attr('href')); + }); + + var li = $('