Skip to content

Remainder of the Spec updates about removals #16841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions docs/_spec/01-lexical-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ A single new line token is accepted

## Literals

There are literals for integer numbers, floating point numbers, characters, booleans, symbols, strings.
There are literals for integer numbers, floating point numbers, characters, booleans, strings.
The syntax of these literals is in each case as in Java.

<!-- TODO
Expand All @@ -274,7 +274,6 @@ Literal ::= [‘-’] integerLiteral
| characterLiteral
| stringLiteral
| interpolatedString
| symbolLiteral
| ‘null’
```

Expand Down Expand Up @@ -490,16 +489,6 @@ In addition, Unicode escape sequences of the form `\uxxxx`, where each `x` is a

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.
Expand Down
262 changes: 89 additions & 173 deletions docs/_spec/03-types.md

Large diffs are not rendered by default.

81 changes: 2 additions & 79 deletions docs/_spec/04-basic-declarations-and-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,53 +40,15 @@ by commas. These are expanded according to the following scheme:
\VAL;x, y: T = e && \VAL; x: T = e \\
&& \VAL; y: T = x \\[0.5em]

\LET;x, y: T = e && \LET; x: T = e \\
&& \VAL; y: T = x \\[0.5em]

\DEF;x, y (ps): T = e &\tab\mbox{expands to}\tab& \DEF; x(ps): T = e \\
&& \DEF; y(ps): T = x(ps)\\[0.5em]

\VAR;x, y: T := e && \VAR;x: T := e\\
&& \VAR;y: T := x\\[0.5em]

\TYPE;t,u = T && \TYPE; t = T\\
&& \TYPE; u = t\\[0.5em]
\eda

All definitions have a ``repeated form`` where the initial
definition keyword is followed by several constituent definitions
which are separated by commas. A repeated definition is
always interpreted as a sequence formed from the
constituent definitions. E.g. the function definition
`def f(x) = x, g(y) = y` expands to
`def f(x) = x; def g(y) = y` and
the type definition
`type T, U <: B` expands to
`type T; type U <: B`.
}
\comment{
If an element in such a sequence introduces only the defined name,
possibly with some type or value parameters, but leaves out any
additional parts in the definition, then those parts are implicitly
copied from the next subsequent sequence element which consists of
more than just a defined name and parameters. Examples:

- []
The variable declaration `var x, y: Int`
expands to `var x: Int; var y: Int`.
- []

The value definition `val x, y: Int = 1`
expands to `val x: Int = 1; val y: Int = 1`.
- []
The class definition `case class X(), Y(n: Int) extends Z` expands to
`case class X extends Z; case class Y(n: Int) extends Z`.
- The object definition `case object Red, Green, Blue extends Color`~
expands to
```scala
case object Red extends Color
case object Green extends Color
case object Blue extends Color
```
-->

## Value Declarations and Definitions
Expand Down Expand Up @@ -647,49 +609,10 @@ By contrast, the following application is well formed and yields again the resul
sum(xs: _*)
```

### Procedures

```ebnf
FunDcl ::= FunSig
FunDef ::= FunSig [nl] ‘{’ Block ‘}’
```

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 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
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 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'´.
In this case, whether or not `m` is recursive, its return type will be the return type of ´m'´.

###### Example
Assume the following definitions:
Expand Down
63 changes: 1 addition & 62 deletions docs/_spec/05-classes-and-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,6 @@ If this is not a template of a trait, then its _evaluation_ consists of the foll
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
Expand Down Expand Up @@ -305,57 +295,6 @@ It is a static error if the inheritance closure of a class type consists of an i

[^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, <null>"`.

## Modifiers

```ebnf
Expand Down Expand Up @@ -602,7 +541,7 @@ A constructor expression is either a self constructor invocation `this(´\mathit
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 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.
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.
Expand Down
Loading