Skip to content

Commit

Permalink
Specify tail-recursive call elimination and annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Nov 7, 2023
1 parent 370bff5 commit 76aef71
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 66 deletions.
19 changes: 19 additions & 0 deletions spec/04-basic-declarations-and-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,25 @@ class C extends I {
Here, it is OK to leave out the result type of `factorial`
in `C`, even though the method is recursive.

### Tail-Recursive Call Elimination

Method definitions which contain self-recursive invocations in tail position
are optimized for stack safety. Self-invocations which are the last operation
before returning from the method are replaced with jumps to the beginning of
the method, much as in a while loop. Sibling-invocations, in which a method
calls itself but with a different instance as receiver, are also optimized.

This transform is performed automatically by the compiler whenever possible.
A method definition bearing the annotation, `scala.annotation.tailrec`,
will fail to compile if the transform is not possible. (The annotation is intended
for cases where deoptimization would likely result in a stack overflow.)

```scala
@annotation.tailrec
def sum(xs: List[Int], acc: Int): Int =
xs match { case h :: t => sum(t, acc + h) case _ => acc }
```

<!-- ## Overloaded Definitions
\label{sec:overloaded-defs}
\todo{change}
Expand Down
141 changes: 75 additions & 66 deletions spec/11-annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,76 +37,31 @@ String @local // Type 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.
Predefined annotations are found in the `scala.annotation` package,
and also in the `scala` package.

* `@SerialVersionUID(<longlit>)` 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 = <longlit>
```

* `@throws(<classlit>)` 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: <stringlit>, since: <stringlit>)`<br/>
Marks a definition as deprecated. Accesses to the
defined entity will then cause a deprecated warning mentioning the
_message_ `<stringlit>` to be issued from the compiler.
The argument _since_ documents since when the definition should be considered deprecated.<br/>
Deprecated warnings are suppressed in code that belongs itself to a definition
that is labeled deprecated.
### Scala Compiler Annotations

* `@deprecatedName(name: <stringlit>, since: <stringlit>)`<br/>
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.
* `@tailrec` Marks a method which must be transformed by the compiler
to eliminate self-recursive invocations in tail position.
It is an error if there are no such invocations, or a recursive call
not in tail position.

### Scala Compiler Annotations
* `@switch` Marks the expression submitted to a match as "switchable",
such that the match can be compiled to an efficient form.
The compiler will warn if the type of the expression is not a switchable type.
Certain degenerate matches may remain unoptimized without a warning.

* `@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.
would be produced for the method definition below, or the similar value definition.

```scala
def f(x: Option[Int]) = (x: @unchecked) match {
case Some(y) => y
}
val Some(y) = x: @unchecked
```

Without the `@unchecked` annotation, a Scala compiler could
Expand All @@ -131,14 +86,12 @@ Java platform, the following annotations have a standard meaning.
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.
* `@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`
`Unit`, `Int` and `Double`:

```scala
trait Function0[@specialized(Unit, Int, Double) T] {
Expand All @@ -148,8 +101,64 @@ Java platform, the following annotations have a standard meaning.

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.
See the [specialization SID](https://docs.scala-lang.org/sips/scala-specialization.html) for more details of the implementation.

### Deprecation Annotations

* `@deprecated(message: <stringlit>, since: <stringlit>)`<br/>
Marks a definition as deprecated. Accesses to the
defined entity will then cause a deprecated warning mentioning the
_message_ `<stringlit>` to be issued from the compiler.
The argument _since_ documents since when the definition should be considered deprecated.<br/>
Deprecated warnings are suppressed in code that belongs itself to a definition
that is labeled deprecated.

* `@deprecatedName(name: <stringlit>, since: <stringlit>)`<br/>
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.

### Java Platform Annotations

The meaning of other 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(<longlit>)` 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 = <longlit>
```

* `@throws(<classlit>)` 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`.

## User-defined Annotations

Expand Down

0 comments on commit 76aef71

Please sign in to comment.