summaryrefslogtreecommitdiff
path: root/07-classes-and-objects.md
diff options
context:
space:
mode:
authorIain McGinniss <iainmcgin@gmail.com>2012-11-03 14:43:13 +0000
committerIain McGinniss <iainmcgin@gmail.com>2012-11-03 14:43:13 +0000
commitfd283b64dd8ae98f7d17d2bb5b71b3d4aa1d51c6 (patch)
tree0748e6975056c039a844a0057c4f74f63ac0aab2 /07-classes-and-objects.md
parent79833dcccf2c02bc2a5621d534b0cbf1d941e4ef (diff)
downloadscala-fd283b64dd8ae98f7d17d2bb5b71b3d4aa1d51c6.tar.gz
scala-fd283b64dd8ae98f7d17d2bb5b71b3d4aa1d51c6.tar.bz2
scala-fd283b64dd8ae98f7d17d2bb5b71b3d4aa1d51c6.zip
conversion of classes and objects chapter
Diffstat (limited to '07-classes-and-objects.md')
-rw-r--r--07-classes-and-objects.md1842
1 files changed, 895 insertions, 947 deletions
diff --git a/07-classes-and-objects.md b/07-classes-and-objects.md
index ab274ffa47..881bca36d5 100644
--- a/07-classes-and-objects.md
+++ b/07-classes-and-objects.md
@@ -1,46 +1,46 @@
Classes and Objects
===================
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+TmplDef ::= [`case'] `class' ClassDef
+ | [`case'] `object' ObjectDef
+ | `trait' TraitDef
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-\syntax\begin{lstlisting}
- TmplDef ::= [`case'] `class' ClassDef
- | [`case'] `object' ObjectDef
- | `trait' TraitDef
-\end{lstlisting}
+[Classes](#class-definitions) and [objects](#object-definitions)
+are both defined in terms of _templates_.
-Classes (\sref{sec:class-defs}) and objects
-(\sref{sec:object-defs}) are both defined in terms of {\em templates}.
-\section{Templates}
-\label{sec:templates}
+Templates
+---------
-\syntax\begin{lstlisting}
- 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 `=>'
-\end{lstlisting}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+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
-~\lstinline@$sc$ with $mt_1$ with $\ldots$ with $mt_n$ {$\stats\,$}@~
+`$sc$ with $mt_1$ with $\ldots$ with $mt_n$ { $\mathit{stats}$ }`
consists of a constructor invocation $sc$
-which defines the template's {\em superclass}, trait references
-~\lstinline@$mt_1 \commadots mt_n$@~ $(n \geq 0)$, which define the
-template's {\em traits}, and a statement sequence $\stats$ which
+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 (\sref{sec:traits}).
+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.
-~\lstinline@$mt_1$ with $\ldots$ with $mt_n$@. In that case the list
+`$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 first parent type. The new supertype must have at least one
constructor that does not take parameters. In the following, we will
@@ -49,368 +49,330 @@ the first parent class of a template is a regular superclass
constructor, not a trait reference.
The list of parents of every class is also always implicitly extended
-by a reference to the \code{scala.ScalaObject} trait as last
-mixin. E.g.\
-\begin{lstlisting}
-$sc$ with $mt_1$ with $\ldots$ with $mt_n$ {$\stats\,$}
-\end{lstlisting}
+by a reference to the `scala.ScalaObject` trait as last
+mixin. E.g.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+$sc$ with $mt_1$ with $\ldots$ with $mt_n$ { $\mathit{stats}$ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
becomes
-\begin{lstlisting}
-$mt_1$ with $\ldots$ with $mt_n$ with ScalaObject {$\stats\,$}.
-\end{lstlisting}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+$mt_1$ with $\ldots$ with $mt_n$ with ScalaObject { $\mathit{stats}$ }.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The list of parents of a template must be well-formed. This means that
the class denoted by the superclass constructor $sc$ must be a
-subclass of the superclasses of all the traits $mt_1 \commadots mt_n$.
+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 {\em least proper supertype} of a template is the class type or
-compound type (\sref{sec:compound-types}) consisting of all its parent
+The _least proper supertype_ of a template is the class type or
+[compound type](#compound-types) consisting of all its parent
class types.
-The statement sequence $\stats$ contains member definitions that
+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 $\stats$ may also contain declarations of abstract
+statement part $\mathit{stats}$ may also contain declarations of abstract
members. If the template forms part of a concrete class definition,
-$\stats$ may still contain declarations of abstract type members, but
-not of abstract term members. Furthermore, $\stats$ may in any case
+$\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.\ \lstinline@$x$ =>@, or
-~\lstinline@$x$:$T$ =>@. If a formal parameter is given, it can be
-used as an alias for the reference \lstinline@this@ throughout the
+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 {\em self type} $S$ of the underlying class or object as follows: Let $C$ be the type
+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 \code{this} is assumed to be $S$.
+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
-~\lstinline@this: $S$ =>@. It prescribes the type $S$ for \lstinline@this@
+`this: $S$ =>`. It prescribes the type $S$ for `this`
without introducing an alias name for it.
-\example Consider the following class definitions:
+(@) Consider the following class definitions:
-\begin{lstlisting}
-class Base extends Object {}
-trait Mixin extends Base {}
-object O extends Mixin {}
-\end{lstlisting}
-In this case, the definition of \code{O} is expanded to:
-\begin{lstlisting}
-object O extends Base with Mixin {}
-\end{lstlisting}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+ class Base extends Object {}
+ trait Mixin extends Base {}
+ object O extends Mixin {}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-%The type of each non-private definition or declaration of a
-%template must be equivalent to a type which does not refer to any
-%private members of that template.
+ In this case, the definition of `O` is expanded to:
-\todo{Make all references to Java generic}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+ object O extends Base with Mixin {}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-\paragraph{\em Inheriting from Java Types} A template may have a Java class as
-its superclass and Java interfaces as its mixins.
-\paragraph{\em Template Evaluation}
-Consider a template ~\lstinline@$sc$ with $mt_1$ with $mt_n$ {$\stats\,$}@.
+<!-- TODO: Make all references to Java generic -->
-If this is the template of a trait (\sref{sec:traits}) then its {\em
-mixin-evaluation} consists of an evaluation of the statement sequence
-$\stats$.
+**Inheriting from Java Types** \
+A template may have a Java class as its superclass and Java interfaces as its
+mixins.
-If this is not a template of a trait, then its {\em evaluation}
+**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.
-\begin{itemize}
-\item
-First, the superclass constructor $sc$ is evaluated (\sref{sec:constr-invoke}).
-\item
-Then, all base classes in the template's linearization
-(\sref{sec:linearization}) up to the
-template's superclass denoted by $sc$ are
-mixin-evaluated. Mixin-evaluation happens in reverse order of
-occurrence in the linearization.
-\item
-Finally the statement sequence $\stats\,$ is evaluated.
-\end{itemize}
-
-\paragraph{\em Delayed Initializaton}
-The initialization code of an object or class (but not a trait) that follows the superclass
+
+- 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 Initializaton_ \
+The initialization code of an object or class (but not a trait) that follows
+the superclass
constructor invocation and the mixin-evaluation of the template's base
classes is passed to a special hook, which is inaccessible from user
code. Normally, that hook simply executes the code that is passed to
-it. But templates inheriting the \lstinline@scala.DelayedInit@ trait
-can override the hook by re-implementing the \lstinline@delayedInit@
+it. But templates inheriting the `scala.DelayedInit` trait
+can override the hook by re-implementing the `delayedInit`
method, which is defined as follows:
-\begin{lstlisting}
- def delayedInit(body: => Unit)
-\end{lstlisting}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+def delayedInit(body: => Unit)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Constructor Invocations
-\subsection{Constructor Invocations}
-\label{sec:constr-invoke}
-\syntax\begin{lstlisting}
- Constr ::= AnnotType {`(' [Exprs] `)'}
-\end{lstlisting}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+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
-~\lstinline@$x$.$c$[$\targs$]($\args_1$)$\ldots$($\args_n$)@, where $x$ is a stable identifier
-(\sref{sec:stable-ids}), $c$ is a type name which either designates a
-class or defines an alias type for one, $\targs$ is a type argument
-list, $\args_1 \commadots \args_n$ are argument lists, and there is a
-constructor of that class which is applicable (\sref{sec:apply})
+`$x$.$c$[$\mathit{targs}$]($\mathit{args}_1$)$\ldots$($\mathit{args}_n$)`, where $x$ is a
+[stable identifier](#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](#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 in (\sref{sec:named-default}).
+same transformation as described [here](sec:named-default).
-The prefix `\lstinline@$x$.@' can be omitted. A type argument list
+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 (\sref{sec:local-type-inf}). If no explicit
-arguments are given, an empty list \lstinline@()@ is implicitly supplied.
+using [local type inference](#local-type-inference). If no explicit
+arguments are given, an empty list `()` is implicitly supplied.
An evaluation of a constructor invocation
-~\lstinline@$x$.$c$[$\targs$]($\args_1$)$\ldots$($\args_n$)@~
+`$x$.$c$[$\mathit{targs}$]($\mathit{args}_1$)$\ldots$($\mathit{args}_n$)`
consists of the following steps:
-\begin{itemize}
-\item First, the prefix $x$ is evaluated.
-\item Then, the arguments $\args_1 \commadots \args_n$ are evaluated from left to right.
-\item Finally, the class being constructed is initialized by evaluating the
+
+- 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$.
-\end{itemize}
-\subsection{Class Linearization}\label{sec:linearization}
+### Class Linearization
The classes reachable through transitive closure of the direct
-inheritance relation from a class $C$ are called the {\em
-base classes} of $C$. Because of mixins, the inheritance relationship
+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.
-\newcommand{\uright}{\;\vec +\;}
-\newcommand{\lin}[1]{{\cal L}(#1)}
-
-\begin{definition}\label{def:lin} Let $C$ be a class with template
-~\lstinline@$C_1$ with ... with $C_n$ { $\stats$ }@.
-The {\em linearization} of $C$, $\lin C$ is defined as follows:
-\bda{rcl}
-\lin C &=& C\ , \ \lin{C_n} \uright \ldots \uright \lin{C_1}
-\eda
-Here $\uright$ denotes concatenation where elements of the right operand
-replace identical elements of the left operand:
-\bda{lcll}
-\{a, A\} \uright B &=& a, (A \uright B) &{\bf if} a \not\in B \\
- &=& A \uright B &{\bf if} a \in B
-\eda
-\end{definition}
-
-\example Consider the following class definitions.
-\begin{lstlisting}
-abstract class AbsIterator extends AnyRef { ... }
-trait RichIterator extends AbsIterator { ... }
-class StringIterator extends AbsIterator { ... }
-class Iter extends StringIterator with RichIterator { ... }
-\end{lstlisting}
-Then the linearization of class \lstinline@Iter@ is
-\begin{lstlisting}
-{ Iter, RichIterator, StringIterator, AbsIterator, ScalaObject, AnyRef, Any }
-\end{lstlisting}
-Trait \lstinline@ScalaObject@ appears in this list because it
-is added as last mixin to every Scala class (\sref{sec:templates}).
-
-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.
-\ref{def:lin} 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
-\lstinline@StringIterator@ is
-\begin{lstlisting}
-{ StringIterator, AbsIterator, ScalaObject, AnyRef, Any }
-\end{lstlisting}
-which is a suffix of the linearization of its subclass \lstinline@Iter@.
-The same is not true for the linearization of mixins.
-For instance, the linearization of \lstinline@RichIterator@ is
-\begin{lstlisting}
-{ RichIterator, AbsIterator, ScalaObject, AnyRef, Any }
-\end{lstlisting}
-which is not a suffix of the linearization of \lstinline@Iter@.
-
-
-\subsection{Class Members}
-\label{sec:members}
+
+> 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:
+>
+> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.math}
+> \[
+> \begin{array}{lcll}
+> \{a, A\} \;\vec{+}\; B &=& a, (A \;\vec{+}\; B) &{\bf if} \; a \not\in B \\
+> &=& A \;\vec{+}\; B &{\bf if} \; a \in B
+> \end{array}
+> \]
+> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+(@) Consider the following class definitions.
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.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
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ { Iter, RichIterator, StringIterator, AbsIterator, ScalaObject, AnyRef, Any }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Trait `ScalaObject` appears in this list because it
+ is added as last mixin to every Scala class ( [see here](#templates) ).
+
+ 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.
+ \ref{def:lin} 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
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ { StringIterator, AbsIterator, ScalaObject, AnyRef, Any }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ which is a suffix of the linearization of its subclass `Iter`.
+ The same is not true for the linearization of mixins.
+ For instance, the linearization of `RichIterator` is
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ { RichIterator, AbsIterator, ScalaObject, AnyRef, Any }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ which is not a suffix of the linearization of `Iter`.
+
+
+### Class Members
+
A class $C$ defined by a template
-~\lstinline@$C_1$ with $\ldots$ with $C_n$ { $\stats$ }@~
+`$C_1$ with $\ldots$ with $C_n$ { $\mathit{stats}$ }`
can define members in its statement sequence
-$\stats$ and can inherit members from all parent classes. Scala
+$\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 {\em matching} on members:
-
-\begin{definition}
-A member definition $M$ {\em matches} a member definition $M'$, if $M$
-and $M'$ bind the same name, and one of following holds.
-\begin{enumerate}
-\item Neither $M$ nor $M'$ is a method definition.
-\item $M$ and $M'$ define both monomorphic methods with equivalent argument
- types.
-\item $M$ defines a parameterless method and $M'$ defines a method
- with an empty parameter list \code{()} or {\em vice versa}.
-\item $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$.
-%every argument type
-%$T_i$ of $M$ is equal to the corresponding argument type $T'_i$ of
-%$M'$ where every occurrence of a type parameter $t'$ of $M'$ has been replaced by the corresponding type parameter $t$ of $M$.
-\end{enumerate}
-\end{definition}
+following definition of _matching_ on members:
+
+> **Definition** \
+> A member definition $M$ _matches_ a member definition $M'$, if $M$
+> and $M'$ bind the same name, and one of following holds.
+>
+> #. Neither $M$ nor $M'$ is a method definition.
+> #. $M$ and $M'$ define both monomorphic methods with equivalent argument
+> types.
+> #. $M$ defines a parameterless method and $M'$ defines a method
+> with an empty parameter list `()` or _vice versa_.
+> #. $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$.
+> by the corresponding type parameter $t$ of $M$.
+
+
Member definitions fall into two categories: concrete and abstract.
-Members of class $C$ are either {\em directly defined} (i.e.\ they appear in
-$C$'s statement sequence $\stats$) or they are {\em inherited}. There are two rules
+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:
-\begin{definition}\label{def:member}
-A {\em concrete member} of a class $C$ is any concrete definition $M$ in
-some class $C_i \in \lin C$, except if there is a preceding class $C_j
-\in \lin C$ where $j < i$ which directly defines a concrete member $M'$ matching $M$.
-
-An {\em abstract member} of a class $C$ is any abstract definition $M$
-in some class $C_i \in \lin C$, except if $C$ contains already a
-concrete member $M'$ matching $M$, or if there is a preceding class
-$C_j \in \lin C$ where $j < i$ which directly defines an abstract member $M'$ matching
-$M$.
-\end{definition}
-This definition also determines the overriding relationships between
-matching members of a class $C$ and its parents (\sref{sec:overriding}).
-First, a concrete definition always overrides an abstract definition. Second, for
+> 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 (\sref{sec:erasure}).
+or inherited) with the same name and the same [erased type](#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.
-\comment{
-The type of a member $m$ is determined as follows: If $m$ is defined
-in $\stats$, then its type is the type as given in the member's
-declaration or definition. Otherwise, if $m$ is inherited from the
-base class ~\lstinline@$B$[$T_1$, $\ldots$. $T_n$]@, $B$'s class declaration has formal
-parameters ~\lstinline@[$a_1 \commadots a_n$]@, and $M$'s type in $B$ is $U$, then
-$M$'s type in $C$ is ~\lstinline@$U$[$a_1$ := $T_1 \commadots a_n$ := $T_n$]@.
-
-\ifqualified{
-Members of templates have internally qualified names $Q\qex x$ where
-$x$ is a simple name and $Q$ is either the empty name $\epsilon$, or
-is a qualified name referencing the module or class that first
-introduces the member. A basic declaration or definition of $x$ in a
-module or class $M$ introduces a member with the following qualified
-name:
-\begin{enumerate}
-\item
-If the binding is labeled with an ~\lstinline@override $Q$@\notyet{Override
- with qualifier} modifier,
-where $Q$ is a fully qualified name of a base class of $M$, then the
-qualified name is the qualified expansion (\sref{sec:names}) of $x$ in
-$Q$.
-\item
-If the binding is labeled with an \code{override} modifier without a
-base class name, then the qualified name is the qualified expansion
-of $x$ in $M$'s least proper supertype (\sref{sec:templates}).
-\item
-An implicit \code{override} modifier is added and case (2) also
-applies if $M$'s least proper supertype contains an abstract member
-with simple name $x$.
-\item
-If no \code{override} modifier is given or implied, then if $M$ is
-labeled \code{qualified}, the qualified name is $M\qex x$. If $M$ is
-not labeled \code{qualified}, the qualified name is $\epsilon\qex x$.
-\end{enumerate}
-}
-}
+(@) Consider the trait definitions:
-\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 }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-\begin{lstlisting}
-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 }
-\end{lstlisting}
+ 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 \code{D} has a directly defined abstract member \code{h}. It
-inherits member \code{f} from trait \code{C} and member \code{g} from
-trait \code{B}.
-\subsection{Overriding}
-\label{sec:overriding}
+### Overriding
-\todo{Explain that classes cannot override each other}
+<!-- TODO: Explain that classes cannot override each other -->
-A member $M$ of class $C$ that matches (\sref{sec:members})
+A member $M$ of class $C$ that [matches](#class-members)
a non-private member $M'$ of a
-base class of $C$ is said to {\em override} that member. In this case
-the binding of the overriding member $M$ must subsume
-(\sref{sec:conformance}) the binding of the overridden member $M'$.
+base class of $C$ is said to _override_ that member. In this case
+the binding of the overriding member $M$ must [subsume](#conformance)
+the binding of the overridden member $M'$.
Furthermore, the following restrictions on modifiers apply to $M$ and
$M'$:
-\begin{itemize}
-\item
-$M'$ must not be labeled \code{final}.
-\item
-$M$ must not be \code{private} (\sref{sec:modifiers}).
-\item
-If $M$ is labeled ~\lstinline@private[$C$]@~ for some enclosing class or package $C$,
-then $M'$ must be labeled ~\lstinline@private[$C'$]@~ for some class or package $C'$ where
-$C'$ equals $C$ or $C'$ is contained in $C$. \todo{check whether this is accurate}
-\item
-If $M$ is labeled \code{protected}, then $M'$ must also be
-labeled \code{protected}.
-\item
-If $M'$ is not an abstract member, then
-$M$ must be labeled \code{override}.
-Furthermore, one of two possibilities must hold:
-\begin{itemize}
-\item either $M$ is defined in a subclass of the class where is $M'$ is defined,
-\item or both $M$ and $M'$ override a third member $M''$ which is defined
+
+- $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$.
+ <!-- TODO: check whether this is accurate -->
+- 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'$
-\end{itemize}
-\item
-If $M'$ is incomplete (\sref{sec:modifiers}) in $C$ then $M$ must be
-labeled \code{abstract override}.
-\item
-If $M$ and $M'$ are both concrete value definitions, then either none
-of them is marked \code{lazy} or both must be marked \code{lazy}.
-\end{itemize}
+- 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 special rule concerns parameterless methods. If a paramterless
-method defined as \lstinline@def $f$: $T$ = ...@ or
-\lstinline@def $f$ = ...@ overrides a method of
+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.
Another restriction applies to abstract type members: An abstract type
-member with a volatile type (\sref{sec:volatile-types}) as its upper
+member with a [volatile type](#volatile-types) as its upper
bound may not override an abstract type member which does not have a
volatile upper bound.
@@ -420,59 +382,62 @@ 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\label{ex:compound-a}
-Consider the definitions:
-\begin{lstlisting}
-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
-\end{lstlisting}
-Then the class definition \code{C} is not well-formed because the
-binding of \code{T} in \code{C} is
-~\lstinline@type T <: B@,
-which fails to subsume the binding ~\lstinline@type T <: A@~ of \code{T}
-in type \code{A}. The problem can be solved by adding an overriding
-definition of type \code{T} in class \code{C}:
-\begin{lstlisting}
-class C extends A with B { type T <: C }
-\end{lstlisting}
-
-\subsection{Inheritance Closure}\label{sec:inheritance-closure}
-
-Let $C$ be a class type. The {\em inheritance closure} of $C$ is the
-smallest set $\SS$ of types such that
-\begin{itemize}
-\item
-If $T$ is in $\SS$, then every type $T'$ which forms syntactically
-a part of $T$ is also in $\SS$.
-\item
-If $T$ is a class type in $\SS$, then all parents (\sref{sec:templates})
-of $T$ are also in $\SS$.
-\end{itemize}
+(@compounda) 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
+
+- 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
-\cite{kennedy-pierce:decidable}).
+necessary to make subtyping decidable [@kennedy-pierce:decidable]).
-\subsection{Early Definitions}\label{sec:early-defs}
-\syntax\begin{lstlisting}
- EarlyDefs ::= `{' [EarlyDef {semi EarlyDef}] `}' `with'
- EarlyDef ::= {Annotation} {Modifier} PatVarDef
-\end{lstlisting}
+### Early Definitions
-A template may start with an {\em early field definition} clause,
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+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
-\begin{lstlisting}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
{ val $p_1$: $T_1$ = $e_1$
...
val $p_n$: $T_n$ = $e_n$
-} with $sc$ with $mt_1$ with $mt_n$ {$\stats\,$}
-\end{lstlisting}
-The initial pattern definitions of $p_1 \commadots p_n$ are called
-{\em early definitions}. They define fields
+} 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.
@@ -480,8 +445,8 @@ 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
-\lstinline@this@ in the right-hand side of an early definition refers
-to the identity of \lstinline@this@ just outside the template. Consequently, it
+`this` in the right-hand side of an early definition refers
+to the identity of `this` just outside the template. Consequently, it
is impossible that an early definition refers to the object being
constructed by the template, or refers to one of its fields and
methods, except for any other preceding early definition in the same
@@ -495,44 +460,46 @@ definitions.
Early definitions are evaluated in the order they are being defined
before the superclass constructor of the template is called.
-\example Early definitions are particularly useful for
-traits, which do not have normal constructor parameters. Example:
-\begin{lstlisting}
-trait Greeting {
- val name: String
- val msg = "How are you, "+name
-}
-class C extends {
- val name = "Bob"
-} with Greeting {
- println(msg)
-}
-\end{lstlisting}
-In the code above, the field \code{name} is initialized before the
-constructor of \code{Greeting} is called. Therefore, field \lstinline@msg@ in
-class \code{Greeting} is properly initialized to \code{"How are you, Bob"}.
-
-If \code{name} had been initialized instead in \code{C}'s normal class
-body, it would be initialized after the constructor of
-\code{Greeting}. In that case, \lstinline@msg@ would be initialized to
-\code{"How are you, <null>"}.
+(@) 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>"`.
-\section{Modifiers}
-\label{sec:modifiers}
-
-\syntax\begin{lstlisting}
- Modifier ::= LocalModifier
- | AccessModifier
- | `override'
- LocalModifier ::= `abstract'
- | `final'
- | `sealed'
- | `implicit'
- | `lazy'
- AccessModifier ::= (`private' | `protected') [AccessQualifier]
- AccessQualifier ::= `[' (id | `this') `]'
-\end{lstlisting}
+Modifiers
+---------
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+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
@@ -540,332 +507,326 @@ 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.
-\begin{itemize}
-\item
-The \code{private} modifier can be used with any definition or
-declaration in a template. Such members can be accessed only from
-within the directly enclosing template and its companion module or
-companion class (\sref{def:companion}). They
-are not inherited by subclasses and they may not override definitions
-in parent classes.
-
-The modifier can be {\em qualified} with an identifier $C$ (e.g.
-~\lstinline@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
-(\sref{sec:object-defs}). Such members are also inherited only from
-templates inside $C$.
-
-An different form of qualification is \code{private[this]}. A member
-$M$ marked with this modifier 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 \code{this} or \lstinline@$O$.this@, for some
-class $O$ enclosing the reference. In addition, the restrictions for
-unqualified \code{private} apply.
-
-Members marked private without a qualifier are called {\em
-class-private}, whereas members labeled with \lstinline@private[this]@
-are called {\em object-private}. A member {\em is private} if it is
-either class-private or object-private, but not if it is marked
-\lstinline@private[$C$]@ where $C$ is an identifier; in the latter
-case the member is called {\em qualified private}.
-
-Class-private or object-private members may not be abstract, and may
-not have \code{protected} or \code{override} modifiers.
-\item
-The \code{protected} modifier applies to class member definitions.
-Protected members of a class can be accessed from within
-\begin{itemize}
-\item the template of the defining class,
-\item all templates that have the defining class as a base class,
-\item the companion module of any of those classes.
-\end{itemize}
-A \code{protected} modifier can be qualified with an
-identifier $C$ (e.g. ~\lstinline@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 (\sref{sec:object-defs}).
-
-A protected identifier $x$ may be used as a member name in a selection
-\lstinline@$r$.$x$@ only if one of the following applies:
-\begin{itemize}
-\item 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
-\item $r$ is one of the reserved words \code{this} and
- \code{super}, or
-\item $r$'s type conforms to a type-instance of the
- class which contains the access.
-\end{itemize}
-
-A different form of qualification is \code{protected[this]}. A member
-$M$ marked with this modifier 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 \code{this} or \lstinline@$O$.this@, for some
-class $O$ enclosing the reference. In addition, the restrictions for
-unqualified \code{protected} apply.
-
-\item
-The \code{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 \code{override}
-modifier is given, there must be at least one overridden member
-definition or declaration (either concrete or abstract).
-\item
-The \code{override} modifier has an additional significance when
-combined with the \code{abstract} modifier. That modifier combination
-is only allowed for value members of traits.
-
-We call a member $M$ of a template {\em incomplete} if it is either
-abstract (i.e.\ defined by a declaration), or it is labeled
-\code{abstract} and \code{override} and
-every member overridden by $M$ is again incomplete.
-
-Note that the \code{abstract override} modifier combination does not
-influence the concept whether a member is concrete or abstract. A
-member is {\em abstract} if only a declaration is given for it; it is
-{\em concrete} if a full definition is given.
-\item
-The \code{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
-(\sref{sec:inst-creation}) 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 \code{abstract} modifier can also be used in conjunction with
-\code{override} for class member definitions. In that case the
-previous discussion applies.
-\item
-The \code{final} modifier applies to class member definitions and to
-class definitions. A \code{final} class member definition may not be
-overridden in subclasses. A \code{final} class may not be inherited by
-a template. \code{final} is redundant for object definitions. Members
-of final classes or objects are implicitly also final, so the
-\code{final} modifier is generally redundant for them, too. Note, however, that
-constant value definitions (\sref{sec:valdef}) do require an explicit \code{final} modifier,
-even if they are defined in a final class or object.
-\code{final} may
-not be applied to incomplete members, and it may not be combined in one
-modifier list with \code{sealed}.
-\item
-The \code{sealed} modifier applies to class definitions. A
-\code{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.
-\item
-The \code{lazy} modifier applies to value definitions. A \code{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.
-\end{itemize}
-
-\example The following code illustrates the use of qualified private:
-\begin{lstlisting}
-package outerpkg.innerpkg
-class Outer {
- class Inner {
- private[Outer] def f()
- private[innerpkg] def g()
- private[outerpkg] def h()
- }
-}
-\end{lstlisting}
-Here, accesses to the method \lstinline@f@ can appear anywhere within
-\lstinline@OuterClass@, but not outside it. Accesses to method
-\lstinline@g@ can appear anywhere within the package
-\lstinline@outerpkg.innerpkg@, as would be the case for
-package-private methods in Java. Finally, accesses to method
-\lstinline@h@ can appear anywhere within package \lstinline@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
-\code{abstract} and \code{sealed}:
-
-\begin{lstlisting}
-object m {
- abstract sealed class C (x: Int) {
- def nextC = new C(x + 1) {}
- }
- val empty = new C(0) {}
-}
-\end{lstlisting}
-For instance, in the code above clients can create instances of class
-\lstinline@m.C@ only by calling the \code{nextC} method of an existing \lstinline@m.C@
-object; it is not possible for clients to create objects of class
-\lstinline@m.C@ directly. Indeed the following two lines are both in error:
-
-\begin{lstlisting}
- new m.C(0) // **** error: C is abstract, so it cannot be instantiated.
- new m.C(0) {} // **** error: illegal inheritance from sealed class.
-\end{lstlisting}
-
-A similar access restriction can be achieved by marking the primary
-constructor \code{private} (see \ref{ex:private-constr}).
-
-\section{Class Definitions}
-\label{sec:class-defs}
-
-\syntax\begin{lstlisting}
- 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]
-\end{lstlisting}
+
+- The `private` modifier can be used with any definition or
+ declaration in a template. Such members can be accessed only from
+ within the directly enclosing template and its companion module or
+ [companion class](#object-definitions). They
+ are not inherited by subclasses and they may not override definitions
+ in parent classes.
+
+ The 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). Such members are also inherited only
+ from templates inside $C$.
+
+ An different form of qualification is `private[this]`. A member
+ $M$ marked with this modifier 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.
+
+- 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 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.
+
+- 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).
+
+- 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.
+
+- 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](#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 `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](#value-declarations-and-definitions) do require
+ an explicit `final` modifier, even if they are defined in a final class or
+ object. `final` may not be applied to incomplete members, and it may not be
+ combined in one modifier list with `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.
+
+- 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 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
+ `OuterClass`, 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.
+
+
+(@) 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` (see \ref{ex:private-constr}).
+
+
+Class Definitions
+-----------------
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+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
-\begin{lstlisting}
-class $c$[$\tps\,$] $as$ $m$($\ps_1$)$\ldots$($\ps_n$) extends $t$ $\gap(n \geq 0)$.
-\end{lstlisting}
-Here,
-\begin{itemize}
-\item[]
-$c$ is the name of the class to be defined.
-\item[] $\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 \lstinline@[$\tps\,$]@ may be omitted. A class with a type
-parameter section is called {\em polymorphic}, otherwise it is called
-{\em monomorphic}.
-\item[] $as$ is a possibly empty sequence of annotations
- (\sref{sec:annotations}). If any annotations are given,
-they apply to the primary constructor of the class.
-\item[] $m$ is an access modifier (\sref{sec:modifiers}) such as
-\code{private} or \code{protected}, possibly with a qualification. If
-such an access modifier is given it applies to the primary constructor
-to the class.
-\item[]
-$(\ps_1)\ldots(\ps_n)$ are formal value parameter clauses for the {\em 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 no formal parameter sections are given,
-an empty parameter section \lstinline@()@ is assumed.
-
-If a formal parameter declaration $x: T$ is preceded by a \code{val}
-or \code{var} keyword, an accessor (getter) definition
-(\sref{sec:vardef}) 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
-\code{var}, a setter accessor \lstinline@$x$_=@ (\sref{sec:vardef}) is also
-implicitly added to the class. In invocation of that setter \lstinline@$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). A formal parameter prefixed
-by \code{val} or \code{var} may not at the same time be a call-by-name
-parameter (\sref{sec:by-name-params}).
-\item[]
-$t$ is a
-template (\sref{sec:templates}) of the form
-\begin{lstlisting}
-$sc$ with $mt_1$ with $\ldots$ with $mt_m$ { $\stats$ } $\gap(m \geq 0)$
-\end{lstlisting}
-which defines the base classes, behavior and initial state of objects of
-the class. The extends clause ~\lstinline@extends $sc$ with $mt_1$ with $\ldots$ with $mt_m$@~
-can be omitted, in which case
-~\lstinline@extends scala.AnyRef@~ is assumed. The class body
-~\lstinline@{$\stats\,$}@~ may also be omitted, in which case the empty body
-\lstinline@{}@ is assumed.
-\end{itemize}
-This class definition defines a type \lstinline@$c$[$\tps\,$]@ and a constructor
-which when applied to parameters conforming to types $\ps$
-initializes instances of type \lstinline@$c$[$\tps\,$]@ by evaluating the template
-$t$.
-\example The following example illustrates \code{val} and \code{var}
-parameters of a class \code{C}:
-\begin{lstlisting}
-class C(x: Int, val y: String, var z: List[String])
-val c = new C(1, "abc", List())
-c.z = c.y :: c.z
-\end{lstlisting}
-
-\example\label{ex:private-constr}
-The following class can be created only from its companion
-module.
-\begin{lstlisting}
-object Sensitive {
- def makeSensitive(credentials: Certificate): Sensitive =
- if (credentials == Admin) new Sensitive()
- else throw new SecurityViolationException
-}
-class Sensitive private () {
- ...
-}
-\end{lstlisting}
-
-\comment{
-For any index $i$ let $\csig_i$ be a class signature consisting of a class
-name and optional type parameter and value parameter sections. Let $ct$
-be a class template.
-Then a class definition
-~\lstinline@class $\csig_1 \commadots \csig_n$ $ct$@~
-is a shorthand for the sequence of class definitions
-~\lstinline@class $\csig_1$ $ct$; ...; class $\csig_n$ $ct$@.
-A class definition
-~\lstinline@class $\csig_1 \commadots \csig_n: T$ $ct$@~
-is a shorthand for the sequence of class definitions
-~\lstinline@class $\csig_1: T$ $ct$; ...; class $\csig_n: T$ $ct$@.
-}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+class $c$[$\mathit{tps}\,$] $as$ $m$($\mathit{ps}_1$)$\ldots$($\mathit{ps}_n$) extends $t$ $\gap(n \geq 0)$.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Here,
-\subsection{Constructor Definitions}\label{sec:constr-defs}
+ - $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](#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
+ to the class.
+ - $(\mathit{ps}_1)\ldots(\mathit{ps}_n)$ are formal value parameter clauses for
+ the {\em 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 no formal parameter sections are given,
+ 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](#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$_=`](#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). A formal parameter prefixed
+ by `val` or `var` may not at the same time be a
+ [call-by-name parameter](#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$.
-\syntax\begin{lstlisting}
- FunDef ::= `this' ParamClause ParamClauses
- (`=' ConstrExpr | [nl] ConstrBlock)
- ConstrExpr ::= SelfInvocation
- | ConstrBlock
- ConstrBlock ::= `{' SelfInvocation {semi BlockStat} `}'
- SelfInvocation ::= `this' ArgumentExprs {ArgumentExprs}
-\end{lstlisting}
+(@) 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
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(@privateconstr) 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
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+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
-~\lstinline@def this($\ps_1$)$\ldots$($\ps_n$) = $e$@. Such a
+`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 $\ps_1
-\commadots \ps_n$, and whose evaluation is defined by the constructor
+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 \lstinline@this($\args_1$)$\ldots$($\args_n$)@ or a block
+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
-\lstinline@[$\tps\,$]@, then a self constructor invocation must
-generate an instance of \lstinline@$C$[$\tps\,$]@; it is not permitted
+`[$\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 (\sref{sec:early-defs}) of the enclosing template.
+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 (\sref{sec:class-defs})
+with $C$'s primary [constructor](#class-definitions)
an overloaded constructor
-definition. The usual rules for overloading resolution
-(\sref{sec:overloading-resolution}) apply for constructor invocations of $C$,
+definition. The usual rules for
+[overloading resolution](#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
@@ -874,156 +835,163 @@ 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
-\begin{lstlisting}
-class LinkedList[A]() {
- var head = _
- var tail = null
- def isEmpty = tail != null
- def this(head: A) = { this(); this.head = head }
- def this(head: A, tail: List[A]) = { this(head); this.tail = tail }
-}
-\end{lstlisting}
-This defines a class \code{LinkedList} with three constructors. The
-second constructor constructs an singleton list, while the
-third one constructs a list with a given head and tail.
+(@) Consider the class definition
+
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.scala}
+ class LinkedList[A]() {
+ var head = _
+ var tail = null
+ def isEmpty = tail != null
+ def this(head: A) = { this(); this.head = head }
+ def this(head: A, tail: List[A]) = { this(head); this.tail = tail }
+ }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This defines a class `LinkedList` with three constructors. The
+ second constructor constructs an singleton list, while the
+ third one constructs a list with a given head and tail.
+
Case Classes
------------
-\label{sec:case-classes}
-
-\syntax\begin{lstlisting}
- TmplDef ::= `case' `class' ClassDef
-\end{lstlisting}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+TmplDef ::= `case' `class' ClassDef
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If a class definition is prefixed with \code{case}, the class is said
-to be a {\em case class}.
+If a class definition is prefixed with `case`, the class is said
+to be a _case class_.
The formal parameters in the first parameter section of a case class
-are called {\em elements}; they are treated
+are called _elements_; they are treated
specially. First, the value of such a parameter can be extracted as a
-field of a constructor pattern. Second, a \code{val} prefix is
+field of a constructor pattern. Second, a `val` prefix is
implicitly added to such a parameter, unless the parameter carries
-already a \code{val} or \code{var} modifier. Hence, an accessor
-definition for the parameter is generated (\sref{sec:class-defs}).
+already a `val` or `var` modifier. Hence, an accessor
+definition for the parameter is [generated](#class-definitions).
-A case class definition of ~\lstinline@$c$[$\tps\,$]($\ps_1\,$)$\ldots$($\ps_n$)@~ with type
-parameters $\tps$ and value parameters $\ps$ implicitly
-generates an extractor object (\sref{sec:extractor-patterns}) which is
+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}$ implicitly
+generates an [extractor object](#extractor-patterns) which is
defined as follows:
-\begin{lstlisting}
- object $c$ {
- def apply[$\tps\,$]($\ps_1\,$)$\ldots$($\ps_n$): $c$[$\tps\,$] = new $c$[$\Ts\,$]($\xs_1\,$)$\ldots$($\xs_n$)
- def unapply[$\tps\,$]($x$: $c$[$\tps\,$]) =
- if (x eq null) scala.None
- else scala.Some($x.\xs_{11}\commadots x.\xs_{1k}$)
- }
-\end{lstlisting}
-Here,
- $\Ts$ stands for the vector of types defined in the type
-parameter section $\tps$,
-each $\xs_i$ denotes the parameter names of the parameter
-section $\ps_i$, and
-$\xs_{11}\commadots \xs_{1k}$ denote the names of all parameters
-in the first parameter section $\xs_1$.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.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 \lstinline@apply@ and
-\lstinline@unapply@ methods.
-The definition of \lstinline@apply@ is omitted if class $c$ is
-\lstinline@abstract@.
+class, it is also missing in the `apply` and
+`unapply` methods.
+The definition of `apply` is omitted if class $c$ is
+`abstract`.
If the case class definition contains an empty value parameter list, the
-\lstinline@unapply@ method returns a \lstinline@Boolean@ instead of an \lstinline@Option@ type and
+`unapply` method returns a `Boolean` instead of an `Option` type and
is defined as follows:
-\begin{lstlisting}
- def unapply[$\tps\,$]($x$: $c$[$\tps\,$]) = x ne null
-\end{lstlisting}
-The name of the \lstinline@unapply@ method is changed to \lstinline@unapplySeq@ if the first
-parameter section $\ps_1$ of $c$ ends in a repeated parameter of (\sref{sec:repeated-params}).
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.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](#repeated-parameters).
If a companion object $c$ exists already, no new object is created,
-but the \lstinline@apply@ and \lstinline@unapply@ methods are added to the existing
+but the `apply` and `unapply` methods are added to the existing
object instead.
-A method named \code{copy} is implicitly added to every case class unless the
+A method named `copy` is implicitly added to every case class unless the
class already has a member (directly defined or inherited) with that name. The
method is defined as follows:
-\begin{lstlisting}
- def copy[$\tps\,$]($\ps'_1\,$)$\ldots$($\ps'_n$): $c$[$\tps\,$] = new $c$[$\Ts\,$]($\xs_1\,$)$\ldots$($\xs_n$)
-\end{lstlisting}
-Again, $\Ts$ stands for the vector of types defined in the type parameter section $\tps$
-and each $\xs_i$ denotes the parameter names of the parameter section $\ps'_i$. Every value
-parameter $\ps'_{i,j}$ of the \code{copy} method has the form \lstinline@$x_{i,j}$:$T_{i,j}$=this.$x_{i,j}$@,
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.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, $\Ts$ stands for the vector of types defined in the type parameter section $\mathit{tps}$
+and each $\mathit{xs}_i$ denotes the parameter names of the parameter section $\mathit{ps}'_i$. Every value
+parameter $\mathit{ps}'_{i,j}$ of the `copy` method has the form `$x_{i,j}$:$T_{i,j}$=this.$x_{i,j}$`,
where $x_{i,j}$ and $T_{i,j}$ refer to the name and type of the corresponding class parameter
-$\ps_{i,j}$.
+$\mathit{ps}_{i,j}$.
Every case class implicitly overrides some method definitions of class
-\lstinline@scala.AnyRef@ (\sref{sec:cls-object}) unless a definition of the same
+[`scala.AnyRef`](#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 \code{AnyRef}. In particular:
-\begin{itemize}
-\item[] Method ~\lstinline@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 \code{equals}) constructor arguments.
-\item[]
-Method ~\lstinline@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.
-\item[] Method ~\lstinline@toString: String@~ returns a string representation which
-contains the name of the class and its elements.
-\end{itemize}
-
-\example Here is the definition of abstract syntax for lambda
-calculus:
-
-\begin{lstlisting}
-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
-\end{lstlisting}
-This defines a class \code{Expr} with case classes
-\code{Var}, \code{Apply} and \code{Lambda}. A call-by-value evaluator for lambda
-expressions could then be written as follows.
-
-\begin{lstlisting}
-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)
-}
-\end{lstlisting}
-
-It is possible to define further case classes that extend type
-\code{Expr} in other parts of the program, for instance
-\begin{lstlisting}
-case class Number(x: Int) extends Expr
-\end{lstlisting}
-
-This form of extensibility can be excluded by declaring the base class
-\code{Expr} \code{sealed}; in this case, all classes that
-directly extend \code{Expr} must be in the same source file as
-\code{Expr}.
-
-\subsection{Traits}
-\label{sec:traits}
-
-\syntax\begin{lstlisting}
- TmplDef ::= `trait' TraitDef
- TraitDef ::= id [TypeParamClause] TraitTemplateOpt
- TraitTemplateOpt ::= `extends' TraitTemplate | [[`extends'] TemplateBody]
-\end{lstlisting}
+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.
+- 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.
+
+
+(@) 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
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+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
@@ -1034,116 +1002,128 @@ 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 {\em actual
supertype} of $D$ in $x$ is the compound type consisting of all the
-base classes in $\lin C$ that succeed $D$. The actual supertype gives
-the context for resolving a \code{super} reference in a trait
-(\sref{sec:this-super}). Note that the actual supertype depends
+base classes in $\mathcal{L}(C)$ that succeed $D$. The actual supertype gives
+the context for resolving a [`super` reference](#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\label{ex:comparable} The following trait defines the property
-of being comparable to objects of some type. It contains an abstract
-method \lstinline@<@ and default implementations of the other
-comparison operators \lstinline@<=@, \lstinline@>@, and
-\lstinline@>=@.
-
-\begin{lstlisting}
-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
-}
-\end{lstlisting}
-
-\example Consider an abstract class \code{Table} that implements maps
-from a type of keys \code{A} to a type of values \code{B}. The class
-has a method \code{set} to enter a new key / value pair into the table,
-and a method \code{get} that returns an optional value matching a
-given key. Finally, there is a method \code{apply} which is like
-\code{get}, except that it returns a given default value if the table
-is undefined for the given key. This class is implemented as follows.
-\begin{lstlisting}
-abstract class Table[A, B](defaultValue: B) {
- def get(key: A): Option[B]
- def set(key: A, value: B)
- def apply(key: A) = get(key) match {
- case Some(value) => value
- case None => defaultValue
- }
-}
-\end{lstlisting}
-Here is a concrete implementation of the \code{Table} class.
-\begin{lstlisting}
-class ListTable[A, B](defaultValue: B) extends Table[A, B](defaultValue) {
- private var elems: List[(A, B)]
- def get(key: A) = elems.find(._1.==(key)).map(._2)
- def set(key: A, value: B) = { elems = (key, value) :: elems }
-}
-\end{lstlisting}
-Here is a trait that prevents concurrent access to the
-\code{get} and \code{set} operations of its parent class:
-\begin{lstlisting}
-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) }
-}
-
-\end{lstlisting}
-Note that \code{SynchronizedTable} does not pass an argument to
-its superclass, \code{Table}, even though \code{Table} is defined with a
-formal parameter. Note also that the \code{super} calls
-in \code{SynchronizedTable}'s \code{get} and \code{set} methods
-statically refer to abstract methods in class \code{Table}. This is
-legal, as long as the calling method is labeled
-\code{abstract override} (\sref{sec:modifiers}).
-
-Finally, the following mixin composition creates a synchronized list table
-with strings as keys and integers as values and with a default value \code{0}:
-\begin{lstlisting}
-object MyTable extends ListTable[String, Int](0) with SynchronizedTable
-\end{lstlisting}
-The object \code{MyTable} inherits its \code{get} and \code{set}
-method from \code{SynchronizedTable}. The \code{super} calls in these
-methods are re-bound to refer to the corresponding implementations in
-\code{ListTable}, which is the actual supertype of \code{SynchronizedTable}
-in \code{MyTable}.
-
-\section{Object Definitions}
-\label{sec:object-defs}
-\label{def:companion}
-
-\syntax\begin{lstlisting}
- ObjectDef ::= id ClassTemplate
-\end{lstlisting}
+(@comparable) 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
+ }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(@) 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)
+ 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)]
+ 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
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ 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
+------------------
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.grammar}
+ObjectDef ::= id ClassTemplate
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An object definition defines a single object of a new class. Its
most general form is
-~\lstinline@object $m$ extends $t$@. Here,
+`object $m$ extends $t$`. Here,
$m$ is the name of the object to be defined, and
-$t$ is a template (\sref{sec:templates}) of the form
-\begin{lstlisting}
-$sc$ with $mt_1$ with $\ldots$ with $mt_n$ { $\stats$ }
-\end{lstlisting}
+$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 ~\lstinline@extends $sc$ with $mt_1$ with $\ldots$ with $mt_n$@~
+The extends clause `extends $sc$ with $mt_1$ with $\ldots$ with $mt_n$`
can be omitted, in which case
-~\lstinline@extends scala.AnyRef@~ is assumed. The class body
-~\lstinline@{$\stats\,$}@~ may also be omitted, in which case the empty body
-\lstinline@{}@ is assumed.
+`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: {\em module})
+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:
-\begin{lstlisting}
-lazy val $m$ = new $sc$ with $mt_1$ with $\ldots$ with $mt_n$ { this: $m.type$ => $\stats$ }
-\end{lstlisting}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.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 ~\lstinline@new $m\Dollar$cls@~ constructor is evaluated
+lazily. The `new $m\Dollar$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 in
@@ -1154,69 +1134,37 @@ 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 (\sref{sec:pkg-obj}). Instead,
+top-level outside of a [package object](#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.
-\begin{lstlisting}
-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 }
-}
-\end{lstlisting}
-This defines a class \code{Point} and an object \code{Point} which
-contains \code{origin} as a member. Note that the double use of the
-name \code{Point} is legal, since the class definition defines the
-name \code{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 {\em 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 {\em companion class}
-of the module.
-
-
-\comment{
-Let $ct$ be a class template.
-Then an object definition
-~\lstinline@object $x_1 \commadots x_n$ $ct$@~
-is a shorthand for the sequence of object definitions
-~\lstinline@object $x_1$ $ct$; ...; object $x_n$ $ct$@.
-An object definition
-~\lstinline@object $x_1 \commadots x_n: T$ $ct$@~
-is a shorthand for the sequence of object definitions
-~\lstinline@object $x_1: T$ $ct$; ...; object $x_n: T$ $ct$@.
-}
-
-\comment{
-\example Here's an outline of a module definition for a file system.
-
-\begin{lstlisting}
-object FileSystem {
- private type FileDirectory
- private val dir: FileDirectory
-
- trait File {
- def read(xs: Array[Byte])
- def close: Unit
- }
-
- private class FileHandle extends File { $\ldots$ }
-
- def open(name: String): File = $\ldots$
-}
-\end{lstlisting}
-}
+(@) 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.