summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorschinz <schinz@epfl.ch>2003-08-22 08:42:57 +0000
committerschinz <schinz@epfl.ch>2003-08-22 08:42:57 +0000
commit8a94b49aab6f7802b80f65592c27189377607cc0 (patch)
treee1ee98dd0aa8a5cc2fb9f144cc6a10e6333eae02 /doc
parent54886f80121b45b0772235702bd06033f3f39c14 (diff)
downloadscala-8a94b49aab6f7802b80f65592c27189377607cc0.tar.gz
scala-8a94b49aab6f7802b80f65592c27189377607cc0.tar.bz2
scala-8a94b49aab6f7802b80f65592c27189377607cc0.zip
- removed obsolete files (which were renamed)
Diffstat (limited to 'doc')
-rw-r--r--doc/reference/examples.bib20
-rw-r--r--doc/reference/examples.verb.tex5494
-rw-r--r--doc/reference/rationale-chapter.verb.tex125
-rw-r--r--doc/reference/rationale.verb.tex21
-rw-r--r--doc/reference/reference.verb.tex5025
5 files changed, 0 insertions, 10685 deletions
diff --git a/doc/reference/examples.bib b/doc/reference/examples.bib
deleted file mode 100644
index a0bbd57115..0000000000
--- a/doc/reference/examples.bib
+++ /dev/null
@@ -1,20 +0,0 @@
-
-@Book{ abelson-sussman:structure,
- author = {Harold Abelson and Gerald Jay Sussman and Julie Sussman},
- title = {The Structure and Interpretation of Computer Programs, 2nd
- edition},
- year = {1996},
- publisher = {MIT Press},
- address = {Cambridge, Massachusetts}
-}
-
-@InProceedings{ odersky-et-al:fool10,
- author = {Martin Odersky and Vincent Cremet and Christine R\"ockl
- and Matthias Zenger},
- title = {A Nominal Theory of Objects with Dependent Types},
- booktitle = {Proc. FOOL 10},
- year = 2003,
- month = jan,
- note = {\verb@http://www.cis.upenn.edu/~bcpierce/FOOL/FOOL10.html@}
-
-}
diff --git a/doc/reference/examples.verb.tex b/doc/reference/examples.verb.tex
deleted file mode 100644
index 24bcb5c363..0000000000
--- a/doc/reference/examples.verb.tex
+++ /dev/null
@@ -1,5494 +0,0 @@
-%% $Id$
-
-\documentclass[11pt]{book}
-
-\usepackage{fleqn,a4wide,vquote,modefs,math,prooftree,scaladefs}
-\newcommand{\exercise}{\paragraph{Exercise:}}
-\newcommand{\rewriteby}[1]{\mbox{\tab\tab\rm(#1)}}
-
-\title{Scala By Examples}
-
-\author{
-Martin Odersky \\ LAMP/EPFL
-}
-
-\sloppy
-\begin{document}
-\maketitle
-\bibliographystyle{alpha}
-
-\chapter{\label{chap:intro}Introduction}
-
-\input{rationale-chapter.tex}
-
-The rest of this document is structured as
-follows. Chapters~\ref{chap:example-one} and
-\ref{chap:example-auction} highlight some of the features that make
-Scala interesting. The following chapters introduce the language
-constructs of Scala in a more thorough
-way. Chapter~\ref{chap:simple-funs} introduces basic expressions and
-simple functions. Chapter~\ref{chap:first-class-funs} introduces
-higher-order functions. (to be continued).
-
-This document ows a great dept to Sussman and Abelson's wonderful book
-``Structure and Interpretation of Computer
-Programs''\cite{abelson-sussman:structure}. Many of their examples and
-exercises are also present here. Of course, the working language has
-in each case been changed from Scheme to Scala. Furthermore, the
-examples make use of Scala's object-oriented constructs where
-appropriate.
-
-
-\chapter{\label{chap:example-one}A First Example}
-
-As a first example, here is an implementation of Quicksort in Scala.
-\begin{verbatim}
-def sort(xs: Array[int]): unit = {
-
- def swap(i: int, j: int): unit = {
- val t = xs(i); xs(i) = xs(j); xs(j) = t;
- }
-
- def sort1(l: int, r: int): unit = {
- val pivot = xs((l + r) / 2);
- var i = l, j = r;
- while (i <= j) {
- while (xs(i) < pivot) { i = i + 1 }
- while (xs(j) > pivot) { j = j - 1 }
- if (i <= j) {
- swap(i, j);
- i = i + 1;
- j = j - 1;
- }
- }
- if (l < j) sort1(l, j);
- if (j < r) sort1(i, r);
- }
-
- sort1(0, xs.length - 1);
-}
-\end{verbatim}
-The implementation looks quite similar to what one would write in Java
-or C. We use the same operators and similar control structures.
-There are also some minor syntactical differences. In particular:
-\begin{itemize}
-\item
-Definitions start with a reserved word. Function definitions start
-with \verb@def@, variable definitions start with \verb@var@ and
-definitions of values (i.e. read only variables) start with \verb@val@.
-\item
-The declared type of a symbol is given after the symbol and a colon.
-The declared type can often be omitted, because the compiler can infer
-it from the context.
-\item
-We use \verb@unit@ instead of \verb@void@ to define the result type of
-a procedure.
-\item
-Array types are written \verb@Array[T]@ rather than \verb@T[]@,
-and array selections are written \verb@a(i)@ rather than \verb@a[i]@.
-\item
-Functions can be nested inside other functions. Nested functions can
-access parameters and local variables of enclosing functions. For
-instance, the name of the array \verb@a@ is visible in functions
-\verb@swap@ and \verb@sort1@, and therefore need not be passed as a
-parameter to them.
-\end{itemize}
-So far, Scala looks like a fairly conventional language with some
-syntactic pecularities. In fact it is possible to write programs in a
-conventional imperative or object-oriented style. This is important
-because it is one of the things that makes it easy to combine Scala
-components with components written in mainstream languages such as
-Java, C\# or Visual Basic.
-
-However, it is also possible to write programs in a style which looks
-completely different. Here is Quicksort again, this time written in
-functional style.
-
-\begin{verbatim}
-def sort(xs: List[int]): List[int] = {
- val pivot = a(a.length / 2);
- sort(a.filter(x => x < pivot))
- ::: a.filter(x => x == pivot)
- ::: sort(a.filter(x => x > pivot))
-}
-\end{verbatim}
-
-The functional program works with lists instead of arrays.\footnote{In
-a future complete implemenetation of Scala, we could also have used arrays
-instead of lists, but at the moment arrays do not yet support
-\verb@filter@ and \verb@:::@.}
-It captures the essence of the quicksort algorithm in a concise way:
-\begin{itemize}
-\item Pick an element in the middle of the list as a pivot.
-\item Partition the lists into two sub-lists containing elements that
-are less than, respectively greater than the pivot element, and a
-third list which contains elements equal to privot.
-\item Sort the first two sub-lists by a recursive invocation of
-the sort function.\footnote{This is not quite what the imperative algorithm does;
-the latter partitions the array into two sub-arrays containing elements
-less than or greater or equal to pivot.}
-\item The result is obtained by appending the three sub-lists together.
-\end{itemize}
-Both the imperative and the functional implementation have the same
-asymptotic complexity -- $O(N;log(N))$ in the average case and
-$O(N^2)$ in the worst case. But where the imperative implementation
-operates in place by modifying the argument array, the functional
-implementation returns a new sorted list and leaves the argument
-list unchanged. The functional implementation thus requires more
-transient memory than the imperative one.
-
-The functional implementation makes it look like Scala is a language
-that's specialized for functional operations on lists. In fact, it
-is not; all of the operations used in the example are simple library
-methods of a class \verb@List[t]@ which is part of the standard
-Scala library, and which itself is implemented in Scala.
-
-In particular, there is the method \verb@filter@ which takes as
-argument a {\em predicate function} that maps list elements to
-boolean values. The result of \verb@filter@ is a list consisting of
-all the elements of the original list for which the given predicate
-function is true. The \verb@filter@ method of an object of type
-\verb@List[t]@ thus has the signature
-\begin{verbatim}
- def filter(p: t => boolean): List[t] .
-\end{verbatim}
-Here, \verb@t => boolean@ is the type of functions that take an element
-of type \verb@t@ and return a \verb@boolean@. Functions like
-\verb@filter@ that take another function as argument or return one as
-result are called {\em higher-order} functions.
-
-In the quicksort program, \verb@filter@ is applied three times to an
-anonymous function argument. The first argument,
-\verb@x => x <= pivot@ represents the function that maps its parameter
-\verb@x@ to the boolean value \verb@x <= pivot@. That is, it yields
-true if \verb@x@ is smaller or equal than \verb@pivot@, false
-otherwise. The function is anonymous, i.e.\ it is not defined with a
-name. The type of the \verb@x@ parameter is omitted because a Scala
-compiler can infer it automatically from the context where the
-function is used. To summarize, \verb@xs.filter(x => x <= pivot)@
-returns a list consisting of all elements of the list \verb@xs@ that are
-smaller than \verb@pivot@.
-
-\comment{
-It is also possible to apply higher-order functions such as
-\verb@filter@ to named function arguments. Here is functional
-quicksort again, where the two anonymous functions are replaced by
-named auxiliary functions that compare the argument to the
-\verb@pivot@ value.
-
-\begin{verbatim}
-def sort (xs: List[int]): List[int] = {
- val pivot = xs(xs.length / 2);
- def leqPivot(x: int) = x <= pivot;
- def gtPivot(x: int) = x > pivot;
- def eqPivot(x: int) = x == pivot;
- sort(xs filter leqPivot)
- ::: sort(xs filter eqPivot)
- ::: sort(xs filter gtPivot)
-}
-\end{verbatim}
-}
-
-An object of type \verb@List[t]@ also has a method ``\verb@:::@''
-which takes an another list and which returns the result of appending this
-list to itself. This method has the signature
-\begin{verbatim}
- def :::(that: List[t]): List[t] .
-\end{verbatim}
-Scala does not distinguish between identifiers and operator names. An
-identifier can be either a sequence of letters and digits which begins
-with a letter, or it can be a sequence of special characters, such as
-``\verb@+@'', ``\verb@*@'', or ``\verb@:@''. The last definition thus
-introduced a new method identifier ``\verb@:::@''. This identifier is
-used in the Quicksort example as a binary infix operator that connects
-the two sub-lists resulting from the partition. In fact, any method
-can be used as an operator in Scala. The binary operation $E;op;E'$
-is always interpreted as the method call $E.op(E')$. This holds also
-for binary infix operators which start with a letter. The recursive call
-to \verb@sort@ in the last quicksort example is thus equivalent to
-\begin{verbatim}
- sort(a.filter(x => x < pivot))
- .:::(sort(a.filter(x => x == pivot)))
- .:::(sort(a.filter(x => x > pivot))) .
-\end{verbatim}
-
-Looking again in detail at the first, imperative implementation of
-Quicksort, we find that many of the language constructs used in the
-second solution are also present, albeit in a disguised form.
-
-For instance, ``standard'' binary operators such as \verb@+@,
-\verb@-@, or \verb@<@ are not treated in any special way. Like
-\verb@append@, they are methods of their left operand. Consequently,
-the expression \verb@i + 1@ is regarded as the invocation
-\verb@i.+(1)@ of the \verb@+@ method of the integer value \verb@x@.
-Of course, a compiler is free (if it is moderately smart, even expected)
-to recognize the special case of calling the \verb@+@ method over
-integer arguments and to generate efficient inline code for it.
-
-Control constructs such as \verb@while@ are also not primitive but are
-predefined functions in the standard Scala library. Here is the
-definition of \verb@while@ in Scala.
-\begin{verbatim}
-def while (def p: boolean) (def s: unit): unit = if (p) { s ; while(p)(s) }
-\end{verbatim}
-The \verb@while@ function takes as first parameter a test function,
-which takes no parameters and yields a boolean value. As second
-parameter it takes a command function which also takes no parameters
-and yields a trivial result. \verb@while@ invokes the command function
-as long as the test function yields true. Again, compilers are free to
-pick specialized implementations of \verb@while@ that have the same
-behavior as the invocation of the function given above.
-
-\chapter{\label{chap:example-auction}Programming with Actors and Messages}
-
-Here's an example that shows an application area for which Scala is
-particularly well suited. Consider the task of implementing an
-electronic auction service. We use an Erlang-style actor process
-model to implement the participants of the auction. Actors are
-objects to which messages are sent. Every process has a ``mailbox'' of
-its incoming messages which is represented as a queue. It can work
-sequentially through the messages in its mailbox, or search for
-messages matching some pattern.
-
-For every traded item there is an auctioneer process that publishes
-information about the traded item, that accepts offers from clients
-and that communicates with the seller and winning bidder to close the
-transaction. We present an overview of a simple implementation
-here.
-
-As a first step, we define the messages that are exchanged during an
-auction. There are two abstract base classes (called {\em traits}):
-\verb@AuctionMessage@ for messages from clients to the auction
-service, and \verb@AuctionReply@ for replies from the service to the
-clients. These are defined as follows.
-\begin{verbatim}
-trait AuctionMessage;
-case class
- Offer(bid: int, client: Actor), \=// make a bid
- Inquire(client: Actor) extends AuctionMessage; \>// inquire status
-
-trait AuctionReply;
-case class
- Status(asked: int, expiration: Date), \>// asked sum, expiration date
- BestOffer, \>// yours is the best offer
- BeatenOffer(maxBid: int), \>// offer beaten by maxBid
- AuctionConcluded(seller: Actor, client: Actor), \>// auction concluded
- AuctionFailed, \>// failed with no bids
- AuctionOver extends AuctionReply; \>// bidding is closed
-\end{verbatim}
-
-\begin{figure}[htb]
-\begin{verbatim}
-class Auction(seller: Actor, minBid: int, closing: Date) extends Actor {
- val timeToShutdown = 36000000; // msec
- val bidIncrement = 10;
- def execute {
- var maxBid = minBid - bidIncrement;
- var maxBidder: Actor = _;
- var running = true;
- while (running) {
- receiveWithin ((closing.getTime() - new Date().getTime())) {
- case Offer(bid, client) =>
- if (bid >= maxBid + bidIncrement) {
- if (maxBid >= minBid) maxBidder send BeatenOffer(bid);
- maxBid = bid; maxBidder = client; client send BestOffer;
- } else {
- client send BeatenOffer(maxBid);
- }
-
- case Inquire(client) =>
- client send Status(maxBid, closing);
-
- case TIMEOUT =>
- if (maxBid >= minBid) {
- val reply = AuctionConcluded(seller, maxBidder);
- maxBidder send reply; seller send reply;
- } else {
- seller send AuctionFailed;
- }
- receiveWithin(timeToShutdown) {
- case Offer(_, client) => client send AuctionOver
- case TIMEOUT => running = false;
- }}}}}
-\end{verbatim}
-\caption{\label{fig:simple-auction}Implementation of an Auction Service}
-\end{figure}
-
-For each base class, there are a number of {\em case classes} which
-define the format of particular messages in the class. These messages
-might well be ultimately mapped to small XML documents. We expect
-automatic tools to exist that convert between XML documents and
-internal data structures like the ones defined above.
-
-Figure~\ref{fig:simple-auction} presents a Scala implementation of a
-class \verb@Auction@ for auction processes that coordinate the bidding
-on one item. Objects of this class are created by indicating
-\begin{itemize}
-\item
-a seller process which needs to be notified when the auction is over,
-\item
-a minimal bid,
-\item
-the date when the auction is to be closed.
-\end{itemize}
-The process behavior is defined by its \verb@run@ method. That method
-repeatedly selects (using \verb@receiveWithin@) a message and reacts to it,
-until the auction is closed, which is signalled by a \verb@TIMEOUT@
-message. Before finally stopping, it stays active for another period
-determined by the \verb@timeToShutdown@ constant and replies to
-further offers that the auction is closed.
-
-Here are some further explanations of the constructs used in this
-program:
-\begin{itemize}
-\item
-The \verb@receiveWithin@ method of class \verb@Actor@ takes as
-parameters a time span given in milliseconds and a function that
-processes messages in the mailbox. The function is given by a sequence
-of cases that each specify a pattern and an action to perform for
-messages matching the pattern. The \verb@receiveWithin@ method selects
-the first message in the mailbox which matches one of these patterns
-and applies the corresponding action to it.
-\item
-The last case of \verb@receiveWithin@ is guarded by a
-\verb@TIMEOUT@ pattern. If no other messages are received in the meantime, this
-pattern is triggered after the time span which is passed as argument
-to the enclosing \verb@receiveWithin@ method. \verb@TIMEOUT@ is a
-particular instance of class \verb@Message@, which is triggered by the
-\verb@Actor@ implementation itself.
-\item
-Reply messages are sent using syntax of the form
-\verb@destination send SomeMessage@. \verb@send@ is used here as a
-binary operator with a process and a message as arguments. This is
-equivalent in Scala to the method call
-\verb@destination.send(SomeMessage)@, i.e. the invocation of
-the \verb@send@ of the destination process with the given message as
-parameter.
-\end{itemize}
-The preceding discussion gave a flavor of distributed programming in
-Scala. It might seem that Scala has a rich set of language constructs
-that support actor processes, message sending and receiving,
-programming with timeouts, etc. In fact, the opposite is true. All the
-constructs discussed above are offered as methods in the library class
-\verb@Actor@. That class is itself implemented in Scala, based on the underlying
-thread model of the host language (e.g. Java, or .NET).
-The implementation of all features of class \verb@Actor@ used here is
-given in Section~\ref{sec:actors}.
-
-The advantages of this approach are relative simplicity of the core
-language and flexibility for library designers. Because the core
-language need not specify details of high-level process communication,
-it can be kept simpler and more general. Because the particular model
-of messages in a mailbox is a library module, it can be freely
-modified if a different model is needed in some applications. The
-approach requires however that the core language is expressive enough
-to provide the necessary language abstractions in a convenient
-way. Scala has been designed with this in mind; one of its major
-design goals was that it should be flexible enough to act as a
-convenient host language for domain specific languages implemented by
-library modules. For instance, the actor communication constructs
-presented above can be regarded as one such domain specific language,
-which conceptually extends the Scala core.
-
-\chapter{\label{chap:simple-funs}Expressions and Simple Functions}
-
-The previous examples gave an impression of what can be done with
-Scala. We now introduce its constructs one by one in a more
-systematic fashion. We start with the smallest level, expressions and
-functions.
-
-\section{Expressions And Simple Functions}
-
-A Scala system comes with an interpreter which can be seen as a
-fancy calculator. A user interacts with the calculator by typing in
-expressions and obtaining the results of their evaluation. Example:
-
-\begin{verbatim}
-? 87 + 145
-232
-
-? 1000 - 333
-667
-
-? 5 + 2 * 3
-11
-\end{verbatim}
-It is also possible to name a sub-expression and use the name instead
-of the expression afterwards:
-\begin{verbatim}
-? def size = 2
-def size: int
-
-? 5 * size
-10
-\end{verbatim}
-\begin{verbatim}
-? def pi = 3.14159
-def pi: double
-
-? def radius = 10
-def radius: int
-
-
-? 2 * pi * radius
-62.8318
-\end{verbatim}
-Definitions start with the reserved word \verb@def@; they introduce a
-name which stands for the expression following the \verb@=@ sign. The
-interpreter will answer with the introduced name and its type.
-
-Executing a definition such as \verb@def x = e@ will not evaluate the
-expression \verb@e@. Instead \verb@e@ is evaluated whenever \verb@x@
-is used. Alternatively, Scala offers a value definition
-\verb@val x = e@, which does evaluate the right-hand-side \verb@e@ as part of the
-evaluation of the definition. If \verb@x@ is then used subsequently,
-it is immediately replaced by the pre-computed value of
-\verb@e@, so that the expression need not be evaluated again.
-
-How are expressions evaluated? An expression consisting of operators
-and operands is evaluated by repeatedly applying the following
-simplification steps.
-\begin{itemize}
-\item pick the left-most operation
-\item evaluate its operands
-\item apply the operator to the operand values.
-\end{itemize}
-A name defined by \verb@def@\ is evaluated by replacing the name by the
-definition's right hand side. A name defined by \verb@val@ is
-evaluated by replacing the name by the value of the definitions's
-right-hand side. The evaluation process stops once we have reached a
-value. A value is some data item such as a string, a number, an array,
-or a list.
-
-\example
-Here is an evaluation of an arithmetic expression.
-\begin{verbatim}
- \=(2 * pi) * radius
--> \>(2 * 3.14159) * radius
--> \>6.28318 * radius
--> \>6.28318 * 10
--> \>62.8318
-\end{verbatim}
-The process of stepwise simplification of expressions to values is
-called {\em reduction}.
-
-\section{Parameters}
-
-Using \verb@def@, one can also define functions with parameters. Example:
-\begin{verbatim}
-? def square(x: double) = x * x
-def square(x: double): double
-
-? square(2)
-4.0
-
-? square(5 + 4)
-81.0
-
-? square(square(4))
-256.0
-
-? def sumOfSquares(x: double, y: double) = square(x) + square(y)
-def sumOfSquares(x: double, y: double): double
-\end{verbatim}
-
-Function parameters follow the function name and are always enclosed
-in parentheses. Every parameter comes with a type, which is indicated
-following the parameter name and a colon. At the present time, we only
-need basic numeric types such as the type \verb@double@ of double
-precision numbers. These are written as in Java.
-
-Functions with parameters are evaluated analogously to operators in
-expressions. First, the arguments of the function are evaluated (in
-left-to-right order). Then, the function application is replaced by
-the function's right hand side, and at the same time all formal
-parameters of the function are replaced by their corresponding actual
-arguments.
-
-\example\
-
-\begin{verbatim}
- \=sumOfSquares(3, 2+2)
--> \>sumOfSquares(3, 4)
--> \>square(3) + square(4)
--> \>3 * 3 + square(4)
--> \>9 + square(4)
--> \>9 + 4 * 4
--> \>9 + 16
--> \>25
-\end{verbatim}
-
-The example shows that the interpreter reduces function arguments to
-values before rewriting the function application. One could instead
-have chosen to apply the function to unreduced arguments. This would
-have yielded the following reduction sequence:
-\begin{verbatim}
- \= sumOfSquares(3, 2+2)
--> \>square(3) + square(2+2)
--> \>3 * 3 + square(2+2)
--> \>9 + square(2+2)
--> \>9 + (2+2) * (2+2)
--> \>9 + 4 * (2+2)
--> \>9 + 4 * 4
--> \>9 + 16
--> \>25
-\end{verbatim}
-
-The second evaluation order is known as \emph{call-by-name},
-whereas the first one is known as \emph{call-by-value}. For
-expressions that use only pure functions and that therefore can be
-reduced with the substitution model, both schemes yield the same final
-values.
-
-Call-by-value has the advantage that it avoids repeated evaluation of
-arguments. Call-by-name has the advantage that it avoids evaluation of
-arguments when the parameter is not used at all by the function.
-Call-by-value is usually more efficient than call-by-name, but a
-call-by-value evaluation might loop where a call-by-name evaluation
-would terminate. Consider:
-\begin{verbatim}
-? def loop: int = loop
-def loop: int
-
-? def first(x: int, y: int) = x
-def first(x: int, y: int): int
-\end{verbatim}
-Then \verb@first(1, loop)@ reduces with call-by-name to \verb@1@,
-whereas the same term reduces with call-by-value repeatedly to itself,
-hence evaluation does not terminate.
-\begin{verbatim}
- \=first(1, loop)
--> \>first(1, loop)
--> \>first(1, loop)
--> \>...
-\end{verbatim}
-Scala uses call-by-value by default, but it switches to call-by-name evaluation
-if the parameter is preceded by \verb@def@.
-
-\example\
-
-\begin{verbatim}
-? def constOne(x: int, def y: int) = 1
-constOne(x: int, def y: int): int
-
-? constOne(1, loop)
-1
-
-? constOne(loop, 2) // gives an infinite loop.
-^C
-\end{verbatim}
-
-\section{Conditional Expressions}
-
-Scala's \verb@if-else@ lets one choose between two alternatives. Its
-syntax is like Java's \verb@if-else@. But where Java's \verb@if-else@
-can be used only as an alternative of statements, Scala allows the
-same syntax to choose between two expressions. Scala's \verb@if-else@
-hence also replaces Java's conditional expression \verb@ ... ? ... :
-...@.
-
-\example\
-
-\begin{verbatim}
-? def abs(x: double) = if (x >= 0) x else -x
-abs(x: double): double
-\end{verbatim}
-Scala's boolean expressions are similar to Java's; they are formed
-from the constants
-\verb@true@ and
-\verb@false@, comparison operators, boolean negation \verb@!@ and the
-boolean operators \verb@&&@ and \verb@||@.
-
-\section{\label{sec:sqrt}Example: Square Roots by Newton's Method}
-
-We now illustrate the language elements introduced so far in the
-construction of a more interesting program. The task is to write a
-function
-\begin{verbatim}
-def sqrt(x: double): double = ...
-\end{verbatim}
-which computes the square root of \verb@x@.
-
-A common way to compute square roots is by Newton's method of
-successive approximations. One starts with an initial guess \verb@y@
-(say: \verb@y = 1@). One then repeatedly improves the current guess
-\verb@y@ by taking the average of \verb@y@ and \verb@x/y@.
-As an example, the next three columns indicate the guess \verb@y@, the
-quotient \verb@x/y@, and their average for the first approximations of
-$\sqrt 2$.
-\begin{verbatim}
-1 \=2/1 = 2 \=1.5
-1.5 \>2/1.5 = 1.3333 \>1.4167
-1.4167 \>2/1.4167 = 1.4118 \>1.4142
-1.4142 \>... \>...
-
-y \>x/y \>(y + x/y)/2
-\end{verbatim}
-One can implement this algorithm in Scala by a set of small functions,
-which each represent one of the elements of the algorithm.
-
-We first define a function for iterating from a guess to the result:
-\begin{verbatim}
-def sqrtIter(guess: double, x: double): double =
- if (isGoodEnough(guess, x)) guess
- else sqrtIter(improve(guess, x), x);
-\end{verbatim}
-Note that \verb@sqrtIter@ calls itself recursively. Loops in
-imperative programs can always be modelled by recursion in functional
-programs.
-
-Note also that the definition of \verb@sqrtIter@ contains a return
-type, which follows the parameter section. Such return types are
-mandatory for recursive functions. For a non-recursive function, the
-return type is optional; if it is missing the type checker will
-compute it from the type of the function's right-hand side. However,
-even for non-recursive functions it is often a good idea to include a
-return type for better documentation.
-
-As a second step, we define the two functions called by
-\verb@sqrtIter@: a function to \verb@improve@ the guess and a
-termination test \verb@isGoodEnough@. Here's their definition.
-\begin{verbatim}
-def improve(guess: double, x: double) =
- (guess + x / guess) / 2;
-
-def isGoodEnough(guess: double, x: double) =
- abs(square(guess) - x) < 0.001;
-\end{verbatim}
-
-Finally, the \verb@sqrt@ function itself is defined by an aplication
-of \verb@sqrtIter@.
-\begin{verbatim}
-def sqrt(x: double) = sqrtIter(1.0, x);
-\end{verbatim}
-
-\exercise The \verb@isGoodEnough@ test is not very precise for small numbers
-and might lead to non-termination for very large ones (why?).
-Design a different version \verb@isGoodEnough@ which does not have these problems.
-
-\exercise Trace the execution of the \verb@sqrt(4)@ expression.
-
-\section{Nested Functions}
-
-The functional programming style encourages the construction of many
-small helper functions. In the last example, the implementation
-of \verb@sqrt@ made use of the helper functions
-\verb@sqrtIter@, \verb@improve@ and
-\verb@isGoodEnough@. The names of these functions
-are relevant only for the implementation of
-\verb@sqrt@. We normally do not want users of \verb@sqrt@ to acess these functions
-directly.
-
-We can enforce this (and avoid name-space pollution) by including
-the helper functions within the calling function itself:
-\begin{verbatim}
-def sqrt(x: double) = {
- def sqrtIter(guess: double, x: double): double =
- if (isGoodEnough(guess, x)) guess
- else sqrtIter(improve(guess, x), x);
-
- def improve(guess: double, x: double) =
- (guess + x / guess) / 2;
-
- def isGoodEnough(guess: double, x: double) =
- abs(square(guess) - x) < 0.001;
-
- sqrtIter(1.0, x)
-}
-\end{verbatim}
-In this program, the braces \verb@{ ... }@ enclose a {\em block}.
-Blocks in Scala are themselves expressions. Every block ends in a
-result expression which defines its value. The result expression may
-be preceded by auxiliary definitions, which are visible only in the
-block itself.
-
-Every definition in a block must be followed by a semicolon, which
-separates this definition from subsequent definitions or the result
-expression. However, a semicolon is inserted implicitly if the
-definition ends in a right brace and is followed by a new line.
-Therefore, the following are all legal:
-\begin{verbatim}
-def f(x) = x + 1; /* `;' mandatory */
-f(1) + f(2)
-
-def g(x) = {x + 1}
-g(1) + g(2)
-
-def h(x) = {x + 1}; /* `;' mandatory */ h(1) + h(2)
-\end{verbatim}
-Scala uses the usual block-structured scoping rules. A name defined in
-some outer block is visible also in some inner block, provided it is
-not redefined there. This rule permits us to simplify our
-\verb@sqrt@ example. We need not pass \verb@x@ around as an additional parameter of
-the nested functions, since it is always visible in them as a
-parameter of the outer function \verb@sqrt@. Here is the simplified code:
-\begin{verbatim}
-def sqrt(x: double) = {
- def sqrtIter(guess: double): double =
- if (isGoodEnough(guess)) guess
- else sqrtIter(improve(guess));
-
- def improve(guess: double) =
- (guess + x / guess) / 2;
-
- def isGoodEnough(guess: double) =
- abs(square(guess) - x) < 0.001;
-
- sqrtIter(1.0)
-}
-\end{verbatim}
-
-\section{Tail Recursion}
-
-Consider the following function to compute the greatest common divisor
-of two given numbers.
-
-\begin{verbatim}
-def gcd(a: int, b: int): int = if (b == 0) a else gcd(b, a % b)
-\end{verbatim}
-
-Using our substitution model of function evaluation,
-\verb@gcd(14, 21)@ evaluates as follows:
-
-\begin{verbatim}
- \=gcd(14, 21)
--> \>if (21 == 0) 14 else gcd(21, 14 % 21)
--> \>if (false) 14 else gcd(21, 14 % 21)
--> \>gcd(21, 14 % 21)
--> \>gcd(21, 14)
--> \>if (14 == 0) 21 else gcd(14, 21 % 14)
--> -> \>gcd(14, 21 % 14)
--> \>gcd(14, 7)
--> \>if (7 == 0) 14 else gcd(7, 14 % 7)
--> -> \>gcd(7, 14 % 7)
--> \>gcd(7, 0)
--> \>if (0 == 0) 7 else gcd(0, 7 % 0)
--> -> \>7
-\end{verbatim}
-
-Contrast this with the evaluation of another recursive function,
-\verb@factorial@:
-
-\begin{verbatim}
-def factorial(n: int): int = if (n == 0) 1 else n * factorial(n - 1)
-\end{verbatim}
-
-The application \verb@factorial(5)@ rewrites as follows:
-\begin{verbatim}
- \=factorial(5)
--> \>if (5 == 0) 1 else 5 * factorial(5 - 1)
--> \>5 * factorial(5 - 1)
--> \>5 * factorial(4)
--> ... -> \>5 * (4 * factorial(3))
--> ... -> \>5 * (4 * (3 * factorial(2)))
--> ... -> \>5 * (4 * (3 * (2 * factorial(1))))
--> ... -> \>5 * (4 * (3 * (2 * (1 * factorial(0))))
--> ... -> \>5 * (4 * (3 * (2 * (1 * 1))))
--> ... -> \>120
-
-\end{verbatim}
-There is an important difference between the two rewrite sequences:
-The terms in the rewrite sequence of \verb@gcd@ have again and again
-the same form. As evaluation proceeds, their size is bounded by a
-constant. By contrast, in the evaluation of factorial we get longer
-and longer chains of operands which are then multiplied in the last
-part of the evaluation sequence.
-
-Even though actual implementations of Scala do not work by rewriting
-terms, they nevertheless should have the same space behavior as in the
-rewrite sequences. In the implementation of \verb@gcd@, one notes that
-the recursive call to \verb@gcd@ is the last action performed in the
-evaluation of its body. One also says that \verb@gcd@ is
-``tail-recursive''. The final call in a tail-recursive function can be
-implemented by a jump back to the beginning of that function. The
-arguments of that call can overwrite the parameters of the current
-instantiation of \verb@gcd@, so that no new stack space is needed.
-Hence, tail recursive functions are iterative processes, which can be
-executed in constant space.
-
-By contrast, the recursive call in \verb@factorial@ is followed by a
-multiplication. Hence, a new stack frame is allocated for the
-recursive instance of factorial, and is decallocated after that
-instance has finished. The given formulation of the factorial function
-is not tail-recursive; it needs space proportional to its input
-parameter for its execution.
-
-More generally, if the last action of a function is a call to another
-(possibly the same) function, only a single stack frame is needed for
-both functions. Such calls are called ``tail calls''. In principle,
-tail calls can always re-use the stack frame of the calling function.
-However, some run-time environments (such as the Java VM) lack the
-primititives to make stack frame re-use for tail calls efficient. A
-production quality Scala implementation is therefore only required to re-use
-the stack frame of a directly tail-recursive function whose last
-action is a call to itself. Other tail calls might be optimized also,
-but one should not rely on this across
-implementations\footnote{The current Scala implementation is not yet
-production quality; it never optimizes tail calls, not even directly
-recursive ones}.
-
-\exercise Design a tail-recursive version of
-\verb@factorial@.
-
-\chapter{\label{chap:first-class-funs}First-Class Functions}
-
-A function in Scala is a ``first-class value''. Like any other value,
-it may be passed as a parameter or returned as a result. Functions
-which take other functions as parameters or return them as results are
-called {\em higher-order} functions. This chapter introduces
-higher-order functions and shows how they provide a flexible mechanism
-for program composition.
-
-As a motivating example, consider the following three related tasks:
-\begin{enumerate}
-\item
-Write a function to sum all integers between two given numbers \verb@a@ and \verb@b@:
-\begin{verbatim}
-def sumInts(a: int, b: int): double =
- if (a > b) 0 else a + sumInts(a + 1, b)
-\end{verbatim}
-\item
-Write a function to sum the cubes of all integers between two given numbers
-\verb@a@ and \verb@b@:
-\begin{verbatim}
-def cube(x: int): double = x * x * x
-def sumCubes(a: int, b: int): double =
- if (a > b) 0 else cube(a) + sumSqrts(a + 1, b)
-\end{verbatim}
-\item
-Write a function to sum the reciprocals of all integers between two given numbers
-\verb@a@ and \verb@b@:
-\begin{verbatim}
-def sumReciprocals(a: int, b: int): double =
- if (a > b) 0 else 1.0 / a + sumReciprocals(a + 1, b)
-\end{verbatim}
-\end{enumerate}
-These functions are all instances of
-\(\sum^b_a f(n)\) for different values of $f$.
-We can factor out the common pattern by defining a function \verb@sum@:
-\begin{verbatim}
-def sum(f: int => double, a: int, b: int): double =
- if (a > b) 0 else f(a) + sum(f, a + 1, b)
-\end{verbatim}
-The type \verb@int => double@ is the type of functions that
-take arguments of type \verb@int@ and return results of type
-\verb@double@. So \verb@sum@ is a function which takes another function as
-a parameter. In other words, \verb@sum@ is a {\em higher-order}
-function.
-
-Using \verb@sum@, we can formulate the three summing functions as
-follows.
-\begin{verbatim}
-def sumInts(a: int, b: int): double = sum(id, a, b);
-def sumCubes(a: int, b: int): double = sum(cube, a, b);
-def sumReciprocals(a: int, b: int): double = sum(reciprocal, a, b);
-\end{verbatim}
-where
-\begin{verbatim}
-def id(x: int): double = x;
-def cube(x: int): double = x * x * x;
-def reciprocal(x: int): double = 1.0/x;
-\end{verbatim}
-
-\section{Anonymous Functions}
-
-Parameterization by functions tends to create many small functions. In
-the previous example, we defined \verb@id@, \verb@cube@ and
-\verb@reciprocal@ as separate functions, so that they could be
-passed as arguments to \verb@sum@.
-
-Instead of using named function definitions for these small argument
-functions, we can formulate them in a shorter way as {\em anonymous
-functions}. An anonymous function is an expression that evaluates to a
-function; the function is defined without giving it a name. As an
-example consider the anonymous reciprocal function:
-\begin{verbatim}
- x: int => 1.0/x
-\end{verbatim}
-The part before the arrow `\verb@=>@' is the parameter of the function,
-whereas the part following the `\verb@=>@' is its body. If there are
-several parameters, we need to enclose them in parentheses. For
-instance, here is an anonymous function which multiples its two arguments.
-\begin{verbatim}
- (x: double, y: double) => x * y
-\end{verbatim}
-Using anonymous functions, we can reformulate the three summation
-functions without named auxiliary functions:
-\begin{verbatim}
-def sumInts(a: int, b: int): double = sum(x: int => x, a, b);
-def sumCubes(a: int, b: int): double = sum(x: int => x * x * x, a, b);
-def sumReciprocals(a: int, b: int): double = sum(x: int => 1.0/x, a, b);
-\end{verbatim}
-Often, the Scala compiler can deduce the parameter type(s) from the
-context of the anonymous function. In this case, they can be omitted.
-For instance, in the case of \verb@sumInts@, \verb@sumCubes@ and
-\verb@sumReciprocals@, one knows from the type of
-\verb@sum@ that the first parameter must be a function of type
-\verb@int => double@. Hence, the parameter type \verb@int@ is
-redundant and may be omitted:
-\begin{verbatim}
-def sumInts(a: int, b: int): double = sum(x => x, a, b);
-def sumCubes(a: int, b: int): double = sum(x => x * x * x, a, b);
-def sumReciprocals(a: int, b: int): double = sum(x => 1.0/x, a, b);
-\end{verbatim}
-
-Generally, the Scala term
-\verb@(x$_1$: T$_1$, ..., x$_n$: T$_n$) => E@
-defines a function which maps its parameters
-\verb@x$_1$, ..., x$_n$@ to the result of the expression \verb@E@
-(where \verb@E@ may refer to \verb@x$_1$, ..., x$_n$@). Anonymous
-functions are not essential language elements of Scala, as they can
-always be expressed in terms of named functions. Indeed, the
-anonymous function
-\verb@(x$_1$: T$_1$, ..., x$_n$: T$_n$) => E@
-is equivalent to the block
-\begin{verbatim}
-{ def f (x$_1$: T$_1$, ..., x$_n$: T$_n$) = E ; f }
-\end{verbatim}
-where \verb@f@ is fresh name which is used nowhere else in the program.
-We also say, anonymous functions are ``syntactic sugar''.
-
-\section{Currying}
-
-The latest formulation of the three summing function is already quite
-compact. But we can do even better. Note that
-\verb@a@ and \verb@b@ appear as parameters and arguments of every function
-but they do not seem to take part in interesting combinations. Is
-there a way to get rid of them?
-
-Let's try to rewrite \verb@sum@ so that it does not take the bounds
-\verb@a@ and \verb@b@ as parameters:
-\begin{verbatim}
-def sum(f: int => double) = {
- def sumF(a: int, b: int): double =
- if (a > b) 0 else f(a) + sumF(a + 1, b);
- sumF
-}
-\end{verbatim}
-In this formulation, \verb@sum@ is a function which returns another
-function, namely the specialized summing function \verb@sumF@. This
-latter function does all the work; it takes the bounds \verb@a@ and
-\verb@b@ as parameters, applies \verb@sum@'s function parameter \verb@f@ to all
-integers between them, and sums up the results.
-
-Using this new formulation of \verb@sum@, we can now define:
-\begin{verbatim}
-def sumInts = sum(x => x);
-def sumCubes = sum(x => x * x * x);
-def sumReciprocals = sum(x => 1.0/x);
-\end{verbatim}
-Or, equivalently, with value definitions:
-\begin{verbatim}
-val sumInts = sum(x => x);
-val sumCubes = sum(x => x * x * x);
-val sumReciprocals = sum(x => 1.0/x);
-\end{verbatim}
-These functions can be applied like other functions. For instance,
-\begin{verbatim}
-? sumCubes(1, 10) + sumReciprocals (10, 20)
-3025.7687714031754
-\end{verbatim}
-How are function-returning functions applied? As an example, in the expression
-\begin{verbatim}
-sum (x => x * x * x) (1, 10) ,
-\end{verbatim}
-the function \verb@sum@ is applied to the cubing function
-\verb@(x => x * x * x)@. The resulting function is then
-applied to the second argument list, \verb@(1, 10)@.
-
-This notation is possible because function application associates to the left.
-That is, if $args_1$ and $args_2$ are argument lists, then
-\bda{lcl}
-f(args_1)(args_2) & \ \ \mbox{is equivalent to}\ \ & (f(args_1))(args_2)
-\eda
-In our example, \verb@sum(x => x * x * x)(1, 10)@ is equivalent to
-\verb@(sum(x => x * x * x))(1, 10)@.
-
-The style of function-returning functions is so useful that Scala has
-special syntax for it. For instance, the next definition of \verb@sum@
-is equivalent to the previous one, but is shorter:
-\begin{verbatim}
-def sum(f: int => double)(a: int, b: int): double =
- if (a > b) 0 else f(a) + sum(f)(a + 1, b)
-\end{verbatim}
-Generally, a curried function definition
-\begin{verbatim}
-def f (args$_1$) ... (args$_n$) = E
-\end{verbatim}
-where $n > 1$ expands to
-\begin{verbatim}
-def f (args$_1$) ... (args$_{n-1}$) = { def g (args$_n$) = E ; g }
-\end{verbatim}
-where \verb@g@ is a fresh identifier. Or, shorter, using an anonymous function:
-\begin{verbatim}
-def f (args$_1$) ... (args$_{n-1}$) = ( args$_n$ ) => E .
-\end{verbatim}
-Performing this step $n$ times yields that
-\begin{verbatim}
-def f (args$_1$) ... (args$_n$) = E
-\end{verbatim}
-is equivalent to
-\begin{verbatim}
-def f = (args$_1$) => ... => (args$_n$) => E .
-\end{verbatim}
-Or, equivalently, using a value definition:
-\begin{verbatim}
-val f = (args$_1$) => ... => (args$_n$) => E .
-\end{verbatim}
-This style of function definition and application is called {\em
-currying} after its promoter, Haskell B.\ Curry, a logician of the
-20th century, even though the idea goes back further to Moses
-Sch\"onfinkel and Gottlob Frege.
-
-The type of a function-returning function is expressed analogously to
-its parameter list. Taking the last formulation of \verb@sum@ as an example,
-the type of \verb@sum@ is \verb@(int => double) => (int, int) => double@.
-This is possible because function types associate to the right. I.e.
-\begin{verbatim}
-T$_1$ => T$_2$ => T$_3$ \=$\mbox{is equivalent to}$ \=T$_1$ => (T$_2$ => T$_3$) .
-\end{verbatim}
-
-\subsection*{Exercises:}
-
-1. The \verb@sum@ function uses a linear recursion. Can you write a
-tail-recursive one by filling in the ??'s?
-
-\begin{verbatim}
-def sum(f: int => double)(a: int, b: int): double = {
- def iter (a, result) = {
- if (??) ??
- else iter (??, ??)
- }
- iter (??, ??)
-}
-\end{verbatim}
-
-2. Write a function \verb@product@ that computes the product of the
-values of functions at points over a given range.
-
-3. Write \verb@factorial@ in terms of \verb@product@.
-
-4. Can you write an even more general function which generalizes both
-\verb@sum@ and \verb@product@?
-
-\section{Example: Finding Fixed Points of Functions}
-
-A number \verb@x@ is called a {\em fixed point} of a function \verb@f@ if
-\begin{verbatim}
-f(x) = x .
-\end{verbatim}
-For some functions \verb@f@ we can locate the fixed point by beginning
-with an initial guess and then applying \verb@f@ repeatedly, until the
-value does not change anymore (or the change is within a small
-tolerance). This is possible if the sequence
-\begin{verbatim}
-x, f(x), f(f(x)), f(f(f(x))), ...
-\end{verbatim}
-converges to fixed point of $f$. This idea is captured in
-the following ``fixed-point finding function'':
-\begin{verbatim}
-val tolerance = 0.0001;
-def isCloseEnough(x: double, y: double) = abs((x - y) / x) < tolerance;
-def fixedPoint(f: double => double)(firstGuess: double) = {
- def iterate(guess: double): double = {
- val next = f(guess);
- if (isCloseEnough(guess, next)) next
- else iterate(next)
- }
- iterate(firstGuess)
-}
-\end{verbatim}
-We now apply this idea in a reformulation of the square root function.
-Let's start with a specification of \verb@sqrt@:
-\begin{verbatim}
-sqrt(x) \== $\mbox{the {\sl y} such that}$ y * y = x
- \>= $\mbox{the {\sl y} such that}$ y = x / y
-\end{verbatim}
-Hence, \verb@sqrt(x)@ is a fixed point of the function \verb@y => x / y@.
-This suggests that \verb@sqrt(x)@ can be computed by fixed point iteration:
-\begin{verbatim}
-def sqrt(x: double) = fixedPoint(y => x / y)(1.0)
-\end{verbatim}
-Unfortunately, this does not converge. Let's instrument the fixed point
-function with a print statement which keeps track of the current
-\verb@guess@ value:
-\begin{verbatim}
-def fixedPoint(f: double => double)(firstGuess: double) = {
- def iterate(guess: double): double = {
- val next = f(guess);
- System.out.println(next);
- if (isCloseEnough(guess, next)) next
- else iterate(next)
- }
- iterate(firstGuess)
-}
-\end{verbatim}
-Then, \verb@sqrt(2)@ yields:
-\begin{verbatim}
- 2.0
- 1.0
- 2.0
- 1.0
- 2.0
- ...
-\end{verbatim}
-One way to control such oscillations is to prevent the guess from changing too much.
-This can be achieved by {\em averaging} successive values of the original sequence:
-\begin{verbatim}
-> def sqrt(x: double) = fixedPoint(y => (y + x/y) / 2)(1.0)
-> sqrt(2.0)
- 1.5
- 1.4166666666666665
- 1.4142156862745097
- 1.4142135623746899
- 1.4142135623746899
-\end{verbatim}
-In fact, expanding the \verb@fixedPoint@ function yields exactly our
-previous definition of fixed point from Section~\ref{sec:sqrt}.
-
-The previous examples showed that the expressive power of a language
-is considerably enhanced if functions can be passed as arguments. The
-next example shows that functions which return functions can also be
-very useful.
-
-Consider again fixed point iterations. We started with the observation
-that $\sqrt(x)$ is a fixed point of the function \verb@y => x / y@.
-Then we made the iteration converge by averaging successive values.
-This technique of {\em average dampening} is so general that it
-can be wrapped in another function.
-\begin{verbatim}
-def averageDamp(f: double => double)(x: double) = (x + f(x)) / 2
-\end{verbatim}
-Using \verb@averageDamp@, we can reformulate the square root function
-as follows.
-\begin{verbatim}
-def sqrt(x: double) = fixedPoint(averageDamp(y => x/y))(1.0)
-\end{verbatim}
-This expresses the elements of the algorithm as clearly as possible.
-
-\exercise Write a function for cube roots using \verb@fixedPoint@ and
-\verb@averageDamp@.
-
-\section{Summary}
-
-We have seen in the previous chapter that functions are essential
-abstractions, because they permit us to introduce general methods of
-computing as explicit, named elements in our programming language.
-The current chapter has shown that these abstractions can be combined by
-higher-order functions to create further abstractions. As
-programmers, we should look out for opportunities to abstract and to
-reuse. The highest possible level of abstraction is not always the
-best, but it is important to know abstraction techniques, so that one
-can use abstractions where appropriate.
-
-\section{Language Elements Seen So Far}
-
-Chapters~\ref{chap:simple-funs} and \ref{chap:first-class-funs} have
-covered Scala's language elements to express expressions and types
-comprising of primitive data and functions. The context-free syntax
-of these language elements is given below in extended Backus-Naur
-form, where `\verb@|@' denotes alternatives, \verb@[...]@ denotes
-option (0 or 1 occurrences), and \verb@{...}@ denotes repetition (0 or
-more occurrences).
-
-\subsection*{Characters}
-
-Scala programs are sequences of (Unicode) characters. We distinguish the
-following character sets:
-\begin{itemize}
-\item
-whitespace, such as `\verb@ @', tabulator, or newline characters,
-\item
-letters `\verb@a@' to `\verb@z@', `\verb@A@' to `\verb@Z@',
-\item
-digits \verb@`0'@ to `\verb@9@',
-\item
-the delimiter characters
-\begin{verbatim}
-. , ; ( ) { } [ ] \ " '
-\end{verbatim}
-\item
-operator characters, such as `\verb@#@' `\verb@+@',
-`\verb@:@'. Essentially, these are printable characters which are
-in none of the character sets above.
-\end{itemize}
-
-\subsection*{Lexemes:}
-
-\begin{verbatim}
-ident ::= letter {letter | digit} | operator { operator } | ident `_' ident
-literal ::= $\mbox{``as in Java''}$
-\end{verbatim}
-
-Literals are as in Java. They define numbers, characters, strings, or
-boolean values. Examples of literals as \verb@0@, \verb@1.0d10@, \verb@'x'@,
-\verb@"he said \"hi!\""@, or \verb@true@.
-
-Identifiers can be of two forms. They either start with a letter,
-which is followed by a (possibly empty) sequence of letters or
-symbols, or they start with an operator character, which is followed
-by a (possibly empty) sequence of operator characters. Both forms of
-identifiers may contain underscore characters `\verb@_@'. Furthermore,
-an underscore character may be followed by either sort of
-identifier. Hence, the following are all legal identifiers:
-\begin{verbatim}
-x Room10a + -- foldl_: +_vector
-\end{verbatim}
-It follows from this rule that subsequent operator-identifiers need to
-be separated by whitespace. For instance, the input
-\verb@x+-y@ is parsed as the three token sequence \verb@x@, \verb@+-@,
-\verb@y@. If we want to express the sum of \verb@x@ with the
-negated value of \verb@y@, we need to add at least one space,
-e.g. \verb@x+ -y@.
-
-The `\verb@\$@' character is reserved for compiler-generated
-identifiers; it should not be used in source programs. %$
-
-The following are reserved words, they may not be used as identifiers:
-\begin{verbatim}
-abstract case catch class def
-do else extends false final
-finally for if import new
-null object override package private
-protected return sealed super this
-trait try true type val
-var while with yield
-_ : = => <- <: >: # @
-\end{verbatim}
-
-\subsection*{Types:}
-
-\begin{verbatim}
-Type \= = SimpleType | FunctionType
-FunctionType \> = SimpleType `=>' Type | `(' [Types] `)' `=>' Type
-SimpleType \> = byte | short | char | int | long | double | float | boolean | unit | String
-Types \> = Type {`,' Type}
-\end{verbatim}
-
-Types can be:
-\begin{itemize}
-\item number types \verb@byte@, \verb@short@, \verb@char@, \verb@int@, \verb@long@, \verb@float@ and \verb@double@ (these are as in Java),
-\item the type \verb@boolean@ with values \verb@true@ and \verb@false@,
-\item the type \verb@unit@ with the only value \verb@{}@,
-\item the type \verb@String@,
-\item function types such as \verb@(int, int) => int@ or \verb@String => Int => String@.
-\end{itemize}
-
-\subsection*{Expressions:}
-
-\begin{verbatim}
-Expr \= = InfixExpr | FunctionExpr | if `(' Expr `)' Expr else Expr
-InfixExpr \> = PrefixExpr | InfixExpr Operator InfixExpr
-Operator \> = ident
-PrefixExpr \> = [`+' | `-' | `!' | `~' ] SimpleExpr
-SimpleExpr \> = ident | literal | SimpleExpr `.' ident | Block
-FunctionExpr\> = Bindings `=> Expr
-Bindings \> = ident [`:' SimpleType] | `(' [Binding {`,' Binding}] `)'
-Binding \> = ident [`:' Type]
-Block \> = `{' {Def `;'} Expr `}'
-\end{verbatim}
-
-Expressions can be:
-\begin{itemize}
-\item
-identifiers such as \verb@x@, \verb@isGoodEnough@, \verb@*@, or \verb@+-@,
-\item
-literals, such as \verb@0@, \verb@1.0@, or \verb@"abc"@,
-\item
-field and method selections, such as \verb@System.out.println@,
-\item
-function applications, such as \verb@sqrt(x)@,
-\item
-operator applications, such as \verb@-x@ or \verb@y + x@,
-\item
-conditionals, such as \verb@if (x < 0) -x else x@,
-\item
-blocks, such as \verb@{ val x = abs(y) ; x * 2 }@,
-\item
-anonymous functions, such as \verb@x => x + 1@ or \verb@(x: int, y: int) => x + y@.
-\end{itemize}
-
-\subsection*{Definitions:}
-
-\begin{verbatim}
-Def \= = \=FunDef | ValDef
-FunDef \> = \>def ident {`(' [Parameters] `)'} [`:' Type] `=' Expr
-ValDef \> = \>val ident [`:' Type] `=' Expr
-Parameters \> = \>Parameter {`,' Parameter}
-Parameter \> = \>[def] ident `:' Type
-\end{verbatim}
-Definitions can be:
-\begin{itemize}
-\item
-function definitions such as \verb@def square(x: int) = x * x@,
-\item
-value definitions such as \verb@val y = square(2)@.
-\end{itemize}
-
-\chapter{Classes and Objects}
-\label{chap:classes}
-
-Scala does not have a built-in type of rational numbers, but it is
-easy to define one, using a class. Here's a possible implementation.
-
-\begin{verbatim}
-class Rational(n: int, d: int) {
- private def gcd(x: int, y: int): int = {
- if (x == 0) y
- else if (x < 0) gcd(-x, y)
- else if (y < 0) -gcd(x, -y)
- else gcd(y % x, x);
- }
- private val g = gcd(n, d);
-
- val numer: int = n/g;
- val denom: int = d/g;
- def +(that: Rational) =
- new Rational(numer * that.denom + that.numer * denom, denom * that.denom);
- def -(that: Rational) =
- new Rational(numer * that.denom - that.numer * denom, denom * that.denom);
- def *(that: Rational) =
- new Rational(numer * that.numer, denom * that.denom);
- def /(that: Rational) =
- new Rational(numer * that.denom, denom * that.numer);
-}
-\end{verbatim}
-This defines \verb@Rational@ as a class which takes two constructor
-arguments \verb@n@ and \verb@d@, containing the number's numerator and
-denominator parts. The class provides fields which return these parts
-as well as methods for arithmetic over rational numbers. Each
-arithmetic method takes as parameter the right operand of the
-operation. The left operand of the operation is always the rational
-number of which the method is a member.
-
-\paragraph{Private members.}
-The implementation of rational numbers defines a private method
-\verb@gcd@ which computes the greatest common denominator of two
-integers, as well as a private field \verb@g@ which contains the
-\verb@gcd@ of the constructor arguments. These members are inaccessible
-outside class \verb@Rational@. They are used in the implementation of
-the class to eliminate common factors in the constructor arguments in
-order to ensure that nominator and denominator are always in
-normalized form.
-
-\paragraph{Creating and Accessing Objects.}
-As an example of how rational numbers can be used, here's a program
-that prints the sum of all numbers $1/i$ where $i$ ranges from 1 to 10.
-\begin{verbatim}
-var i = 1;
-var x = Rational(0, 1);
-while (i <= 10) {
- x = x + Rational(1,i);
- i = i + 1;
-}
-System.out.println(x.numer + "/" + x.denom);
-\end{verbatim}
-The \verb@+@ operation converts both its operands to strings and returns the
-concatenation of the result strings. It thus corresponds to \verb@+@ in Java.
-
-\paragraph{Inheritance and Overriding.}
-Every class in Scala has a superclass which it extends.
-Excepted is only the root class \verb@Object@, which does not have a
-superclass, and which is indirectly extended by every other class.
-If a class does not mention a superclass in its definition, the root
-class \verb@Object@ is implicitly assumed. For instance, class
-\verb@Rational@ could equivalently be defined as
-\begin{verbatim}
-class Rational(n: int, d: int) extends Object {
- ... // as before
-}
-\end{verbatim}
-A class inherits all members from its superclass. It may also redefine
-(or: {\em override}) some inherited members. For instance, class
-\verb@Object@ defines
-a method
-\verb@toString@ which returns a representation of the object as a string:
-\begin{verbatim}
-class Object {
- ...
- def toString(): String = ...
-}
-\end{verbatim}
-The implementation of \verb@toString@ in \verb@Object@
-forms a string consisting of the object's class name and a number. It
-makes sense to redefine this method for objects that are rational
-numbers:
-\begin{verbatim}
-class Rational(n: int, d: int) extends Object {
- ... // as before
- override def toString() = numer + "/" + denom;
-}
-\end{verbatim}
-Note that, unlike in Java, redefining definitions need to be preceded
-by an \verb@override@ modifier.
-
-If class $A$ extends class $B$, then objects of type $A$ may be used
-wherever objects of type $B$ are expected. We say in this case that
-type $A$ {\em conforms} to type $B$. For instance, \verb@Rational@
-conforms to \verb@Object@, so it is legal to assign a \verb@Rational@
-value to a variable of type \verb@Object@:
-\begin{verbatim}
-var x: Object = new Rational(1,2);
-\end{verbatim}
-
-\paragraph{Parameterless Methods.}
-%Also unlike in Java, methods in Scala do not necessarily take a
-%parameter list. An example is \verb@toString@; the method is invoked
-%by simply mentioning its name. For instance:
-%\begin{verbatim}
-%val r = new Rational(1,2);
-%System.out.println(r.toString()); // prints``1/2''
-%\end{verbatim}
-Also unlike in Java, methods in Scala do not necessarily take a
-parameter list. An example is the \verb@square@ method below. This
-method is invoked by simply mentioning its name.
-\begin{verbatim}
-class Rational(n: int, d: int) extends Object {
- ... // as before
- def square = Rational(numer*numer, denom*denom);
-}
-val r = new Rational(3,4);
-System.out.println(r.square); // prints``9/16''
-\end{verbatim}
-That is, parameterless methods are accessed just as value fields such
-as \verb@numer@ are. The difference between values and parameterless
-methods lies in their definition. The right-hand side of a value is
-evaluated when the object is created, and the value does not change
-afterwards. A right-hand side of a parameterless method, on the other
-hand, is evaluated each time the method is called. The uniform access
-of fields and parameterless methods gives increased flexibility for
-the implementer of a class. Often, a field in one version of a class
-becomes a computed value in the next version. Uniform access ensures
-that clients do not have to be rewritten because of that change.
-
-\paragraph{Abstract Classes}
-
-Consider the task of writing a class for sets of integer numbers with
-two operations, \verb@incl@ and \verb@contains@. \verb@(s incl x)@
-should return a new set which contains the element \verb@x@ togther
-with all the elements of set \verb@s@. \verb@(s contains x)@ should
-return true if the set \verb@s@ contains the element \verb@x@, and
-should return \verb@false@ otherwise. The interface of such sets is
-given by:
-\begin{verbatim}
-abstract class IntSet {
- def incl(x: int): IntSet;
- def contains(x: int): boolean;
-}
-\end{verbatim}
-\verb@IntSet@ is labeled as an \emph{abstract class}. This has two
-consequences. First, abstract classes may have {\em deferred} members
-which are declared but which do not have an implementation. In our
-case, both \verb@incl@ and \verb@contains@ are such members. Second,
-because an abstract class might have unimplemented members, no objects
-of that class may be created using \verb@new@. By contrast, an
-abstract class may be used as a base class of some other class, which
-implements the deferred members.
-
-\paragraph{Traits.}
-
-Instead of ``\verb@abstract class@ one also often uses the keyword
-\verb@trait@ in Scala. A trait is an abstract class with no state, no
-constructor arguments, and no side effects during object
-initialization. Since \verb@IntSet@'s fall in this category, one can
-alternatively define them as traits:
-\begin{verbatim}
-trait IntSet {
- def incl(x: int): IntSet;
- def contains(x: int): boolean;
-}
-\end{verbatim}
-A trait corresponds to an interface in Java, except
-that a trait can also define implemented methods.
-
-\paragraph{Implementing Abstract Classes}
-
-Let's say, we plan to implement sets as binary trees. There are two
-possible forms of trees. A tree for the empty set, and a tree
-consisting of an integer and two subtrees. Here are their
-implementations.
-
-\begin{verbatim}
-class Empty extends IntSet {
- def contains(x: int): boolean = false;
- def incl(x: int): IntSet = new NonEmpty(x, new Empty, new Empty);
-}
-\end{verbatim}
-
-\begin{verbatim}
-class NonEmpty(elem:int, left:IntSet, right:IntSet) extends IntSet {
- def contains(x: int): boolean =
- if (x < elem) left contains x
- else if (x > elem) right contains x
- else true;
- def incl(x: int): IntSet =
- if (x < elem) new NonEmpty(elem, left incl x, right)
- else if (x > elem) new NonEmpty(elem, left, right incl x)
- else this;
-}
-\end{verbatim}
-Both \verb@Empty@ and \verb@NonEmpty@ extend class
-\verb@IntSet@. This implies that types \verb@Empty@ and
-\verb@NonEmpty@ conform to type \verb@IntSet@ -- a value of type \verb@Empty@ or \verb@NonEmpty@ may be used wherever a value of type \verb@IntSet@ is required.
-
-\exercise Write methods \verb@union@ and \verb@intersection@ to form
-the union and intersection between two sets.
-
-\exercise Add a method
-\begin{verbatim}
-def excl(x: int)
-\end{verbatim}
-to return the given set without the element \verb@x@. To accomplish this,
-it is useful to also implement a test method
-\begin{verbatim}
-def isEmpty: boolean
-\end{verbatim}
-for sets.
-
-\paragraph{Dynamic Binding}
-
-Object-oriented languages (Scala included) use \emph{dynamic dispatch}
-for method invocations. That is, the code invoked for a method call
-depends on the run-time type of the object which contains the method.
-For example, consider the expression \verb@s contains 7@ where
-\verb@s@ is a value of declared type \verb@s: IntSet@. Which code for
-\verb@contains@ is executed depends on the type of value of \verb@s@ at run-time.
-If it is an \verb@Empty@ value, it is the implementation of \verb@contains@ in class \verb@Empty@ that is executed, and analogously for \verb@NonEmpty@ values.
-This behavior is a direct consequence of our substitution model of evaluation.
-For instance,
-\begin{verbatim}
- (new Empty).contains(7)
-
--> $\rewriteby{by replacing {\sl contains} by its body in class {\sl Empty}}$
-
- false
-\end{verbatim}
-Or,
-\begin{verbatim}
- new NonEmpty(7, new Empty, new Empty).contains(1)
-
--> $\rewriteby{by replacing {\sl contains} by its body in class {\sl NonEmpty}}$
-
- if (1 < 7) new Empty contains 1
- else if (1 > 7) new Empty contains 1
- else true
-
--> $\rewriteby{by rewriting the conditional}$
-
- new Empty contains 1
-
--> $\rewriteby{by replacing {\sl contains} by its body in class {\sl Empty}}$
-
- false .
-\end{verbatim}
-
-Dynamic method dispatch is analogous to higher-order function
-calls. In both cases, the identity of code to be executed is known
-only at run-time. This similarity is not just superficial. Indeed,
-Scala represents every function value as an object (see
-Section~\ref{sec:funs-are-objects}).
-
-
-\paragraph{Objects}
-
-In the previous implementation of integer sets, empty sets were
-expressed with \verb@new Empty@; so a new object was created every time
-an empty set value was required. We could have avoided unnecessary
-object creations by defining a value \verb@empty@ once and then using
-this value instead of every occurrence of \verb@new Empty@. E.g.
-\begin{verbatim}
-val empty = new Empty;
-\end{verbatim}
-One problem with this approach is that a value definition such as the
-one above is not a legal top-level definition in Scala; it has to be
-part of another class or object. Also, the definition of class
-\verb@Empty@ now seems a bit of an overkill -- why define a class of objects,
-if we are only interested in a single object of this class? A more
-direct approach is to use an {\em object definition}. Here is
-a more streamlined alternative definition of the empty set:
-\begin{verbatim}
-object empty extends IntSet {
- def contains(x: int): boolean = false;
-
- def incl(x: int): IntSet = new NonEmpty(x, empty, empty);
-}
-\end{verbatim}
-The syntax of an object definition follows the syntax of a class
-definition; it has an optional extends clause as well as an optional
-body. As is the case for classes, the extends clause defines inherited
-members of the object whereas the body defines overriding or new
-members. However, an object definition defines a single object only;
-it is not possible to create other objects with the same structure
-using \verb@new@. Therefore, object definitions also lack constructor
-parameters, which might be present in class definitions.
-
-Object definitions can appear anywhere in a Scala program; including
-at top-level. Since there is no fixed execution order of top-level
-entities in Scala, one might ask exactly when the object defined by an
-object definition is created and initialized. The answer is that the
-object is created the first time one of its members is accessed. This
-strategy is called {\em lazy evaluation}.
-
-\paragraph{Standard Classes}
-
-Scala is a pure object-oriented language. This means that every value
-in Scala can be regarded as an object. In fact, even primitive types
-such as \verb@int@ or \verb@boolean@ are not treated specially. They
-are defined as type aliases of Scala classes in module \verb@Predef@:
-\begin{verbatim}
-type boolean = scala.Boolean;
-type int = scala.Int;
-type long = scala.Long;
-...
-\end{verbatim}
-For efficiency, the compiler usually represents values of type
-\verb@scala.Int@ by 32 bit integers, values of type
-\verb@scala.Boolean@ by Java's booleans, etc. But it converts these
-specialized representations to objects when required, for instance
-when a primitive \verb@int@ value is passed to a function that with a
-parameter of type \verb@Object@. Hence, the special representation of
-primitive values is just an optimization, it does not change the
-meaning of a program.
-
-Here is a specification of class \verb@Boolean@.
-\begin{verbatim}
-package scala;
-trait Boolean {
- def && (def x: Boolean)\=: Boolean;
- def || (def x: Boolean)\>: Boolean;
- def ! \>: Boolean;
-
- def == (x: Boolean)\>: Boolean
- def != (x: Boolean)\>: Boolean
- def < (x: Boolean)\>: Boolean
- def > (x: Boolean)\>: Boolean
- def <= (x: Boolean)\>: Boolean
- def >= (x: Boolean)\>: Boolean
-}
-\end{verbatim}
-Booleans can be defined using only classes and objects, without
-reference to a built-in type of booleans or numbers. A possible
-implementation of class \verb@Boolean@ is given below. This is not
-the actual implementation in the standard Scala library. For
-efficiency reasons the standard implementation is built from built-in
-booleans.
-\begin{verbatim}
-package scala;
-trait Boolean {
- def ifThenElse(def thenpart: Boolean, def elsepart: Boolean)
-
- def && (def x: Boolean)\=: Boolean = ifThenElse(x, false);
- def || (def x: Boolean)\>: Boolean = ifThenElse(true, x);
- def ! \>: Boolean = ifThenElse(false, true);
-
- def == (x: Boolean)\>: Boolean = ifThenElse(x, x.!);
- def != (x: Boolean)\>: Boolean = ifThenElse(x.!, x);
- def < (x: Boolean)\>: Boolean = ifThenElse(false, x);
- def > (x: Boolean)\>: Boolean = ifThenElse(x.!, false);
- def <= (x: Boolean)\>: Boolean = ifThenElse(x, true);
- def >= (x: Boolean)\>: Boolean = ifThenElse(true, x.!);
-}
-object True extends Boolean \={ def ifThenElse(def t: Boolean, def e: Boolean) = t }
-object False extends Boolean \>{ def ifThenElse(def t: Boolean, def e: Boolean) = e }
-\end{verbatim}
-Here is a partial specification of class \verb@Int@.
-
-\begin{verbatim}
-package scala;
-trait Int extends Long {
- def + (that: Double): Double;
- def + (that: Float): Float;
- def + (that: Long): Long;
- def + (that: Int): Int; \=/* analogous for -, *, /, % */
-
- def << (cnt: Int): Int; \>/* analogous for >>, >>> */
-
- def & (that: Long): Long;
- def & (that: Int): Int; \>/* analogous for |, ^ */
-
- def == (that: Double): Boolean;
- def == (that: Float): Boolean;
- def == (that: Long): Boolean; \> /* analogous for !=, <, >, <=, >= */
-}
-\end{verbatim}
-
-Class \verb@Int@ can in principle also be implemented using just
-objects and classes, without reference to a built in type of
-integers. To see how, we consider a slightly simpler problem, namely
-how to implement a type \verb@Nat@ of natural (i.e. non-negative)
-numbers. Here is the definition of a trait \verb@Nat@:
-\begin{verbatim}
-trait Nat {
- def isZero: Boolean;
- def predecessor: Nat;
- def successor: Nat;
- def + (that: Nat): Nat;
- def - (that: Nat): Nat;
-}
-\end{verbatim}
-To implement the operations of class \verb@Nat@, we define a subobject
-\verb@Zero@ and a subclass \verb@Succ@ (for successor). Each number
-\verb@N@ is represented as \verb@N@ applications of the \verb@Succ@
-constructor to \verb@Zero@:
-\[
-\underbrace{\mbox{\sl new Succ( ... new Succ}}_{\mbox{$N$ times}}\mbox{\sl (Zero) ... )}
-\]
-The implementation of the \verb@Zero@ object is straightforward:
-\begin{verbatim}
-object Zero extends Nat {
- def isZero: Boolean = true;
- def predecessor: Nat = error("negative number");
- def successor: Nat = new Succ(Zero);
- def + (that: Nat): Nat = that;
- def - (that: Nat): Nat = if (that.isZero) Zero else error("negative number")
-}
-\end{verbatim}
-
-The implementation of the predecessor and subtraction functions on
-\verb@Zero@ contains a call to the predefined \verb@error@
-function. This function aborts the program with the given error
-message.
-
-Here is the implementation of the successor class:
-\begin{verbatim}
-class Succ(x: Nat) extends Nat {
- def isZero: Boolean = false;
- def predecessor: Nat = x;
- def successor: Nat = new Succ(this);
- def + (that: Nat): Nat = x.+(that.successor);
- def - (that: Nat): Nat = x.-(that.predecessor)
-}
-\end{verbatim}
-Note the implementation of method \verb@successor@. To create the
-successor of a number, we need to pass the object itself as an
-argument to the \verb@Succ@ constructor. The object itself is
-referenced by the reserved name \verb@this@.
-
-The implementations of \verb@+@ and \verb@-@ each contain a recursive
-call with the constructor argument as receiver. The recursion will
-terminate once the receiver is the \verb@Zero@ object (which is
-guaranteed to happen eventually from the way numbers are formed).
-
-\exercise Write an implementation \verb@Integer@ of integer numbers
-The implementation should support all operations of class \verb@Nat@
-while adding two methods
-\begin{verbatim}
-def isPositive: Boolean
-def negate: Integer
-\end{verbatim}
-The first method should return \verb@true@ if the number is positive. The second method should negate the number.
-Do not use any of Scala's standard numeric classes in your
-implementation. (Hint: There are two possible ways to implement
-\verb@Integer@. One can either make use the existing implementation of
-\verb@Nat@, representing an integer as a natural number and a sign.
-Or one can generalize the given implementation of \verb@Nat@ to
-\verb@Integer@, using the three subclasses \verb@Zero@ for 0,
-\verb@Succ@ for positive numbers and \verb@Pred@ for negative numbers.)
-
-
-
-\paragraph{Language Elements Introduced In This Chapter}
-
-\paragraph{Types:}
-\begin{verbatim}
-Type \= = ... | ident
-\end{verbatim}
-
-Types can now be arbitrary identifiers which represent classes.
-
-\paragraph{Expressions:}
-\begin{verbatim}
-Expr \= = ... | Expr `.' ident | new Expr | this
-\end{verbatim}
-
-An expression can now be an object creation, or
-a selection \verb@E.m@ of a member \verb@m@
-from an object-valued expression \verb@E@, or it can be the reserved name \verb@this@.
-
-\paragraph{Definitions and Declarations:}
-\begin{verbatim}
-Def \= = \=FunDef | ValDef | ClassDef | TraitDef | ObjectDef
-ClassDef \> = \>[abstract] class ident [`(' [Parameters] `)']
- \> \>[extends Expr] [`{' {TemplateDef} `}']
-TraitDef \> = \>trait ident [extends Expr] [`{' {TemplateDef} `}']
-ObjectDef \> = \>object ident [extends Expr] [`{' {ObjectDef} `}']
-TemplateDef \> = \>[Modifier] (Def | Dcl)
-ObjectDef \> = \>[Modifier] Def
-Modifier \> = \>private | override
-Dcl \> = \>FunDcl | ValDcl
-FunDcl \> = \>def ident {`(' [Parameters] `)'} `:' Type
-ValDcl \> = \>val ident `:' Type
-\end{verbatim}
-
-A definition can now be a class, trait or object definition such as
-\begin{verbatim}
-class C(params) extends B { defs }
-trait T extends B { defs }
-object O extends B { defs }
-\end{verbatim}
-The definitions \verb@defs@ in a class, trait or object may be
-preceded by modifiers \verb@private@ or \verb@override@.
-
-Abstract classes and traits may also contain declarations. These
-introduce {\em deferred} functions or values with their types, but do
-not give an implementation. Deferred members have to be implemented in
-subclasses before objects of an abstract class or trait can be created.
-
-\chapter{Case Classes and Pattern Matching}
-
-Say, we want to write an interpreter for arithmetic expressions. To
-keep things simple initially, we restrict ourselves to just numbers
-and \verb@+@ operations. Such expressions can be represented as a class hierarchy, with an abstract base class \verb@Expr@ as the root, and two subclasses \verb@Number@ and
-\verb@Sum@. Then, an expression \verb@1 + (3 + 7)@ would be represented as
-\begin{verbatim}
-new Sum(new Number(1), new Sum(new Number(3), new Number(7)))
-\end{verbatim}
-Now, an evaluator of an expression like this needs to know of what
-form it is (either \verb@Sum@ or \verb@Number@) and also needs to
-access the components of the expression. The following
-implementation provides all necessary methods.
-\begin{verbatim}
-abstract class Expr {
- def isNumber: boolean;
- def isSum: boolean;
- def numValue: int;
- def leftOp: Expr;
- def rightOp: Expr;
-}
-\end{verbatim}
-\begin{verbatim}
-class Number(n: int) extends Expr {
- def isNumber: boolean = true;
- def isSum: boolean = false;
- def numValue: int = n;
- def leftOp: Expr = error("Number.leftOp");
- def rightOp: Expr = error("Number.rightOp");
-}
-\end{verbatim}
-\begin{verbatim}
-class Sum(e1: Expr, e2: Expr) extends Expr {
- def isNumber: boolean = false;
- def isSum: boolean = true;
- def numValue: int = error("Sum.numValue");
- def leftOp: Expr = e1;
- def rightOp: Expr = e2;}
-\end{verbatim}
-With these classification and access methods, writing an evaluator function is simple:
-\begin{verbatim}
-def eval(e: Expr): int = {
- if (e.isNumber) e.numValue
- else if (e.isSum) eval(e.leftOp) + eval(e.rightOp)
- else error("unrecognized expression kind")
-}
-\end{verbatim}
-However, defining all these methods in classes \verb@Sum@ and
-\verb@Number@ is rather tedious. Furthermore, the problem becomes worse
-when we want to add new forms of expressions. For instance, consider
-adding a new expression form
-\verb@Prod@ for products. Not only do we have to implement a new class \verb@Prod@, with all previous classification and access methods; we also have to introduce a
-new abstract method \verb@isProduct@ in class \verb@Expr@ and
-implement that method in subclasses \verb@Number@, \verb@Sum@, and
-\verb@Prod@. Having to modify existing code when a system grows is always problematic, since it introduces versioning and maintenance problems.
-
-The promise of object-oriented programming is that such modifications
-should be unnecessary, because they can be avoided by re-using
-existing, unmodified code through inheritance. Indeed, a more
-object-oriented decomposition of our problem solves the problem. The
-idea is to make the ``high-level'' operation \verb@eval@ a method of
-each expression class, instead of implementing it as a function
-outside the expression class hierarchy, as we have done
-before. Because \verb@eval@ is now a member of all expression nodes,
-all classification and access methods become superfluous, and the implementation is simplified considerably:
-\begin{verbatim}
-abstract class Expr {
- def eval: int;
-}
-class Number(n: int) extends Expr {
- def eval: int = n;
-}
-class Sum(e1: Expr, e2: Expr) extends Expr {
- def eval: int = e1.eval + e2.eval;
-}
-\end{verbatim}
-Furthermore, adding a new \verb@Prod@ class does not entail any changes to existing code:
-\begin{verbatim}
-class Prod(e1: Expr, e2: Expr) extends Expr {
- def eval: int = e1.eval * e2.eval;
-}
-\end{verbatim}
-
-The conclusion we can draw from this example is that object-oriented
-decomposition is the technique of choice for constructing systems that
-should be extensible with new types of data. But there is also another
-possible way we might want to extend the expression example. We might
-want to add new {\em operations} on expressions. For instance, we might
-want to add an operation that pretty-prints an expression tree to standard output.
-
-If we have defined all classification and access methods, such an
-operation can easily be written as an external function. Here is an
-implementation:
-\begin{verbatim}
-def print(e: Expr): unit =
- if (e.isNumber) System.out.print(e.numValue)
- else if (e.isSum) {
- System.out.print("(");
- print(e.leftOp);
- System.out.print("+");
- print(e.rightOp);
- System.out.print(")");
- } else error("unrecognized expression kind");
-\end{verbatim}
-However, if we had opted for an object-oriented decomposition of
-expressions, we would need to add a new \verb@print@ method
-to each class:
-\begin{verbatim}
-abstract class Expr {
- def eval: int;
- def print: unit;
-}
-class Number(n: int) extends Expr {
- def eval: int = n;
- def print: unit = System.out.print(n);
-}
-class Sum(e1: Expr, e2: Expr) extends Expr {
- def eval: int = e1.eval + e2.eval;
- def print: unit = {
- System.out.print("(");
- print(e1);
- System.out.print("+");
- print(e2);
- System.out.print(")");
-}
-\end{verbatim}
-Hence, classical object-oriented decomposition requires modification
-of all existing classes when a system is extended with new operations.
-
-As yet another way we might want to extend the interpreter, consider
-expression simplification. For instance, we might want to write a
-function which rewrites expressions of the form
-\verb@a * b + a * c@ to \verb@a * (b + c)@. This operation requires inspection of
-more than a single node of the expression tree at the same
-time. Hence, it cannot be implemented by a method in each expression
-kind, unless that method can also inspect other nodes. So we are
-forced to have classification and access methods in this case. This
-seems to bring us back to square one, with all the problems of
-verbosity and extensibility.
-
-Taking a closer look, one observers that the only purpose of the
-classification and access functions is to {\em reverse} the data
-construction process. They let us determine, first, which sub-class
-of an abstract base class was used and, second, what were the
-constructor arguments. Since this situation is quite common, Scala has
-a way to automate it with case classes.
-
-\paragraph{Case Classes.}
-A {\em case class} is defined like a normal class, except that the definition
-is prefixed with the modifier \verb@case@. For instance, the definitions
-\begin{verbatim}
-abstract class Expr;
-case class Number(n: int) extends Expr;
-case class Sum(e1: Expr, e2: Expr) extends Expr;
-\end{verbatim}
-introduce \verb@Number@ and \verb@Sum@ as case classes.
-The \verb@case@ modifier in front of a class definition has the following effects.
-\begin{enumerate}
-\item Case classes implicitly come with a constructor function, with the same name as the class. In our example, the two functions
-\begin{verbatim}
-def Number(n: int) = new Number(n);
-def Sum(e1: Expr, e2: Expr) = new Sum(e1, e2);
-\end{verbatim}
-would be added. Hence, one can now construct expression trees a bit more concisely, as in
-\begin{verbatim}
-Sum(Sum(Number(1), Number(2)), Number(3))
-\end{verbatim}
-\item Case classes implicity come with implementations of methods
-\verb@toString@, \verb@equals@ and \verb@hashCode@, which override the
-methods with the same name in class \verb@Object@. The implementation
-of these methods takes in each case the structure of a member of a
-case class into account. The \verb@toString@ method represents an
-expression tree the way it was constructed. So,
-\begin{verbatim}
-Sum(Sum(Number(1), Number(2)), Number(3))
-\end{verbatim}
-would be converted to exactly that string, whereas he default
-implementation in class \verb@Object@ would return a string consisting
-of the outermost constructor name \verb@Sum@ and a number. The
-\verb@equals@ methods treats two case members of a case class as equal
-if they have been constructed with the same constructor and with
-arguments which are themselves pairwise equal. This also affects the
-implementation of \verb@==@ and \verb@!=@, which are implemented in
-terms of \verb@equals@ in Scala. So,
-\begin{verbatim}
-Sum(Number(1), Number(2)) == Sum(Number(1), Number(2))
-\end{verbatim}
-will yield \verb@true@. If \verb@Sum@ or \verb@Number@ were not case
-classes, the same expression would be \verb@false@, since the standard
-implementation of \verb@equals@ in class \verb@Object@ always treats
-objects created by different constructor calls as being different.
-The \verb@hashCode@ method follows the same principle as other two
-methods. It computes a hash code from the case class constructor name
-and the hash codes of the constructor arguments, instead of from the object's
-address, which is what the as the default implementation of \verb@hashCode@ does.
-\item
-Case classes implicity come with nullary accessor methods which
-retrieve the constructor arguments.
-In our example, \verb@Number@ would obtain an accessor method
-\begin{verbatim}
-def n: int
-\end{verbatim}
-which returns the constructor parameter \verb@n@, whereas \verb@Sum@ would obtain two accessor methods
-\begin{verbatim}
-def e1: Expr, e2: Expr;
-\end{verbatim}
-Hence, if for a value \verb@s@ of type \verb@Sum@, say, one can now
-write \verb@s.e1@, to access the left operand. However, for a value
-\verb@e@ of type \verb@Expr@, the term \verb@e.e1@ would be illegal
-since \verb@e1@ is defined in \verb@Sum@; it is not a member of the
-base class \verb@Expr@.
-So, how do we determine the constructor and access constructor
-arguments for values whose static type is the base class \verb@Expr@?
-This is solved by the fourth and final particularity of case classes.
-\item
-Case classes allow the constructions of {\em patterns} which refer to
-the case class constructor.
-\end{enumerate}
-
-\paragraph{Pattern Matching.}
-
-Pattern matching is a generalization of C or Java's \verb@switch@
-statement to class hierarchies. Instead of a \verb@switch@ statement,
-there is a standard method \verb@match@, which is defined in Scala's
-root class \verb@Any@, and therefore is available for all objects.
-The \verb@match@ method takes as argument a number of cases.
-For instance, here is an implementation of \verb@eval@ using
-pattern matching.
-\begin{verbatim}
-def eval(e: Expr): int = e match {
- case Number(x) => x
- case Sum(l, r) => eval(l) + eval(r)
-}
-\end{verbatim}
-In this example, there are two cases. Each case associates a pattern
-with an expression. Patterns are matched against the selector
-values \verb@e@. The first pattern in our example,
-\verb@Number(n)@, matches all values of the form \verb@Number(v)@,
-where \verb@v@ is an arbitrary value. In that case, the {\em pattern
-variable} \verb@n@ is bound to the value \verb@v@. Similarly, the
-pattern \verb@Sum(l, r)@ matches all selector values of form
-\verb@Sum(v$_1$, v$_2$)@ and binds the pattern variables \verb@l@ and \verb@r@
-to \verb@v$_1$@ and \verb@v$_2$@, respectively.
-
-In general, patterns are built from
-\begin{itemize}
-\item Case class constructors, e.g. \verb@Number@, \verb@Sum@, whose arguments
- are again patterns,
-\item pattern variables, e.g. \verb@n@, \verb@e1@, \verb@e2@,
-\item the ``wildcard'' pattern \verb@_@,
-\item constants, e.g. \verb@1@, \verb@true@, "abc", \verb@MAXINT@.
-\end{itemize}
-Pattern variables always start with a lower-case letter, so that they
-can be distinguished from constant identifiers, which start with an
-upper case letter. The only exceptions to that rule are the reserved
-words \verb@null@, \verb@true@, \verb@false@, which are treated as constants.
-Each variable name may occur only once in a pattern. For instance,
-\verb@Sum(x, x)@ would be illegal as a pattern, since \verb@x@ occurs
-twice in it.
-
-\paragraph{Meaning of Pattern Matching.}
-A pattern matching expression
-\begin{verbatim}
-e.match { case p$_1$ => e$_1$ ... case p$_n$ => e$_n$ }
-\end{verbatim}
-matches the patterns $p_1 \commadots p_n$ in the order they
-are written against the selector value \verb@e@.
-\begin{itemize}
-\item
-A constructor pattern $C(p_1 \commadots p_n)$ matches all values that
-are of type \verb@C@ (or a subtype thereof) and that have been constructed with
-\verb@C@-arguments matching patterns $p_1 \commadots p_n$.
-\item
-A variable pattern \verb@x@ matches any value and binds the variable
-name to that value.
-\item
-The wildcard pattern `\verb@_@' matches any value but does not bind a name to that value.
-\item A constant pattern \verb@C@ matches a value which is
-equal (in terms of \verb@==@) to \verb@C@.
-\end{itemize}
-The pattern matching expression rewrites to the right-hand-side of the
-first case whose pattern matches the selector value. References to
-pattern variables are replaced by corresponding constructor arguments.
-If none of the patterns matches, the pattern matching expression is
-aborted with a \verb@MatchError@ exception.
-
-\example Our substitution model of program evaluation extends quite naturally to pattern matching, For instance, here is how \verb@eval@ applied to a simple expression is re-written:
-\begin{verbatim}
- \= eval(Sum(Number(1), Number(2)))
-
--> \> $\mbox{\tab\tab\rm(by rewriting the application)}$
-
- \> Sum(Number(1), Number(2)) match {
- \> case Number(n) => n
- \> case Sum(e1, e2) => eval(e1) + eval(e2)
- \> }
-
--> \> $\mbox{\tab\tab\rm(by rewriting the pattern match)}$
-
- \> eval(Number(1)) + eval(Number(2))
-
--> \> $\mbox{\tab\tab\rm(by rewriting the first application)}$
-
- \> Number(1) match {
- \> case Number(n) => n
- \> case Sum(e1, e2) => eval(e1) + eval(e2)
- \> } + eval(Number(2))
-
--> \> $\mbox{\tab\tab\rm(by rewriting the pattern match)}$
-
- \> 1 + eval(Number(2))
-
-->$^*$ \> 1 + 2 -> 3
-\end{verbatim}
-
-\paragraph{Pattern Matching and Methods.} In the previous example, we have used pattern
-matching in a function which was defined outside the class hierarchy
-over which it matches. Of course, it is also possible to define a
-pattern matching function in that class hierarchy itself. For
-instance, we could have defined
-\verb@eval@ is a method of the base class \verb@Expr@, and still have used pattern matching in its implementation:
-\begin{verbatim}
-abstract class Expr {
- def eval: int = this match {
- case Number(n) => n
- case Sum(e1, e2) => e1.eval + e2.eval
- }
-}
-\end{verbatim}
-
-\exercise
-Consider the following three classes representing trees of integers.
-These classes can be seen as an alternative representation of \verb@IntSet@:
-\begin{verbatim}
-trait IntTree;
-case class Empty extends IntTree;
-case class Node(elem: int, left: IntTree, right: IntTree) extends IntTree;
-\end{verbatim}
-Complete the following implementations of function \verb@contains@ and \verb@insert@ for
-\verb@IntTree@'s.
-\begin{verbatim}
-def contains(t: IntTree, v: int): boolean = t match { ...
- ...
-}
-def insert(t: IntTree, v: int): IntTree = t match { ...
- ...
-}
-\end{verbatim}
-
-\subsection*{Tuples}
-
-Sometimes, a function needs to return more than one result. For
-instance, take the function \verb@divmod@ which returns the quotient
-and rest of two given integer arguments. Of course, one can
-define a class to hold the two results of \verb@divmod@, as in:
-\begin{verbatim}
-case class TwoInts(first: int, second: int);
-
-def divmod(x: int, y: int): TwoInts = new TwoInts(x / y, x % y)
-\end{verbatim}
-However, having to define a new class for every possible pair of
-result types is very tedious. It should also be unneccessary because
-all such classes have exactly the same structure. In Scala, the
-repetition can be avoided by defining a {\em generic class}:
-\begin{verbatim}
-case class Pair[+a, +b](first: a, second: b);
-
-def divmod(x: int, y: int): Pair[int, int] = new Pair[Int, Int](x / y, x % y)
-\end{verbatim}
-In this example, \verb@[a, b]@ are {\em type parameters} of class
-\verb@Pair@. In a \verb@Pair@ type, these parameters are replaced by
-concrete types. For instance, \verb@Pair[int, String]@ represents the
-type of pairs with \verb@int@ and \verb@String@ elements.
-
-Type arguments can be omitted in constructors, if the correct type can
-be inferred from the other constructor arguments or the constructor's
-expected result type. In our example, we could have omitted the type
-arguments in the body of \verb@divmod@, because they can be deduced
-from the two value parameters of type \verb@int@:
-\begin{verbatim}
-def divmod(x: int, y: int): Pair[int, int] = new Pair(x / y, x % y)
-\end{verbatim}
-Type parameters are never used in patterns. For instance, here is an
-expression in which \verb@divmod@'s result is decomposed:
-\begin{verbatim}
-divmod(x, y) match {
- case Pair(n, d) => System.out.println("quotient: " + n + ", rest: " + d);
-}
-\end{verbatim}
-The type parameters in class \verb@Pair@ are each prefixed by a
-\verb@+@ sign. This indicates that \verb@Pair@s are {\em
-covariant}. That is, if types \verb@T$_1$@ and \verb@T$_2$@ are
-subtypes of types \verb@S$_1$@ and \verb@S$_2$@, then
-\verb@Pair[T$_1$, T$_2$]@ is a subtype of
-\verb@Pair[S$_1$, S$_2$]@. For instance, \verb@Pair[String, int]@ is a
-subtype of \verb@Pair[Object, long]@. If the \verb@+@-annotation was
-missing, the type constructor would be treated as being
-non-variant. That is, pairs with different element types would never
-be in a subtype relation.
-Besides, \verb@+@, there is also a prefix
-\verb@-@ for contra-variant type constructors.
-The precise rules that
-for variance annotations are given in Chapter~\ref{sec:variance}.
-
-The idea of pairs is generalized in Scala to tuples of greater arity.
-There is a predefined case class \verb@Tuple$_n$@ for every \verb@n@
-from \verb@2@ to \verb@9@ in Scala's standard library. The
-definitions all follow the template
-\begin{verbatim}
-case class Tuple$_n$[+a$_1$, ..., +a$_n$](_1: a$_1$, ..., _n: a$_n$);
-\end{verbatim}
-Class \verb@Pair@ (as well as class \verb@Triple@) are also
-predefined, but not as classes of their own. Instead
-\verb@Pair@ is an alias of \verb@Tuple2@ and \verb@Triple@ is an
-alias of \verb@Tuple3@.
-
-\chapter{Lists}
-
-The list is an important data structure in many Scala programs.
-A list with elements \verb@x$_1$, ..., x$_n$@ is written
-\verb@List(x$_1$, ..., x$_n$)@. Examples are:
-\begin{verbatim}
-val fruit \= = List("apples", "oranges", "pears");
-val nums \> = List(1, 2, 3, 4);
-val diag3 \> = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1));
-val empty \> = List();
-\end{verbatim}
-Lists are similar to arrays in languages such as C or Java, but there
-are also three important differences. First, lists are immutable. That
-is, elements of a list can not be changed by assignment. Second,
-lists have a recursive structure, whereas arrays are flat. Third,
-lists support a much richer set of operations than arrays usually do.
-
-\paragraph{The list type.}
-Like arrays, lists are {\em homogeneous}. That is, the elements of a
-list all have the same type. The type of a list with elements of type
-\verb@T@ is written \verb@List[T]@. (Compare to \verb@[]T@ for the
-type of arrays of type \verb@T@ in C or Java.). Therefore, the
-definitions of list values above can be annotated with types as
-follows.
-\begin{verbatim}
-val fruit \= : List[String] \= = List("apples", "oranges", "pears");
-val nums \> : List[int] \> = List(1, 2, 3, 4);
-val diag3 \> : List[List[int]] \> = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1));
-val empty \> : List[int] \> = List();
-\end{verbatim}
-
-\paragraph{List constructors.}
-All lists are built from two more fundamental constructors, \verb@Nil@
-and \verb@::@ (pronounced ``cons''). \verb@Nil@ represents an empty
-list. The infix operator \verb@::@ expresses list extension. That is,
-\verb@x :: xs@ represents a list whose first element is \verb@x@,
-which is followed by (the elements of) list \verb@xs@. Hence, the
-list values above could also have been defined as follows (in fact
-their previous definition is simply syntactic sugar for the definitions below).
-\begin{verbatim}
-val fruit \= = "apples" :: ("oranges" :: ("pears" :: Nil));
-val nums \> = 1 :: (2 :: (3 :: (4 :: Nil)));
-val diag3 \> = \= (1 :: (0 :: (0 :: Nil))) ::
- \> \> (0 :: (1 :: (0 :: Nil))) ::
- \> \> (0 :: (0 :: (1 :: Nil))) :: Nil;
-val empty \> = Nil;
-\end{verbatim}
-The `\verb@::@' operation associates to the right: \verb@A :: B :: C@ is
-interpreted as \verb@A :: (B :: C)@. Therefore, we can drop the
-parentheses in the definitions above. For instance, we can write
-shorter
-\begin{verbatim}
-val nums = 1 :: 2 :: 3 :: 4 :: Nil;
-\end{verbatim}
-
-\paragraph{Basic operations on lists.}
-All operations on lists can be expressed in terms of the following three:
-
-\begin{tabular}{ll}
-\verb@head@ & returns the first element of a list,\\
-\verb@tail@ & returns the list consisting of all elements except the\\
-first element,
-\verb@isEmpty@ & returns \verb@true@ iff the list is empty
-\end{tabular}
-
-These operations are defined as methods of list objects. So we invoke
-them by selecting from the list that's operated on. Examples:
-\begin{verbatim}
-empty.isEmpty \= = true
-fruit.isEmpty \> = false
-fruit.head \> = "apples"
-fruit.tail.head \> = "oranges"
-diag3.head \> = List(1, 0, 0)
-\end{verbatim}
-Both \verb@head@ and \verb@tail@ are only defined for non-empty lists.
-When selected from an empty list, they cause an error instead.
-
-As an example of how lists can be processed, consider sorting the
-elements of a list of numbers into ascending order. One simple way to
-do so is {\em insertion sort}, which works as follows: To sort a
-non-empty list with first element \verb@x@ and rest \verb@xs@, sort
-the remainder \verb@xs@ and insert the element \verb@x@ at the right
-position in the result. Sorting an empty list will of course yield the
-empty list. Expressed as Scala code:
-\begin{verbatim}
-def isort(xs: List[int]): List[int] =
- if (xs.isEmpty) Nil
- else insert(xs.head, isort(xs.tail))
-\end{verbatim}
-
-\exercise Provide an implementation of the missing function
-\verb@insert@.
-
-\paragraph{List patterns.} In fact, \verb@::@ is
-defined defined as a case class in Scala's standard library. Hence, it
-is possible to decompose lists by pattern matching, using patterns
-composed from the \verb@Nil@ and \verb@::@ constructors. For instance,
-\verb@isort@ can be written alternatively as follows.
-\begin{verbatim}
-def isort(xs: List[int]): List[int] = xs match {
- case List() => List()
- case x :: xs1 => insert(x, isort(xs1))
-}
-\end{verbatim}
-where
-\begin{verbatim}
-def insert(x: int, xs: List[int]): List[int] = xs match {
- case List() => List(x)
- case y :: ys => if (x <= y) x :: xs else y :: insert(x, ys)
-}
-\end{verbatim}
-
-\paragraph{Polymorphic functions.} Consider the problem of writing a
- function \verb@concat@, which takes a list of element lists as
- arguments. The result of \verb@concat@ should be the concatenation of all
- element lists into a single list.
-
-When trying to define such a function, we observe that we need to give
-a type for the list elements:
-\begin{verbatim}
-def concat(xss: List[List[ ?? ]]): List[ ?? ] = ...
-\end{verbatim}
-Clearly, one could replace \verb@??@ by \verb@int@, say, to obtain a
-function \verb@concat@ that works on lists of lists of integers. But then the
-same function could not be applied to other kinds of lists. This is a
-pity, since clearly the same algorithm of list concatenation can work
-for lists of any element type. Parameterization lets us generalize
-from a specific instance of a problem to a more general one. So far,
-we have used parameterization only for values, but it is available
-also for types. To arrive at a general version of \verb@concat@, we
-equip it with a type parameter.
-\begin{verbatim}
-def concat[a](xs: List[List[a]]): List[a] = xs match {
- case List() => xs
- case List() :: yss => concat[a](yss)
- case (x :: xs) :: yss => x :: concat[a](xs :: yss)
-}
-\end{verbatim}
-Type parameters are arbitrary names; they are enclosed in brackets
-instead of parentheses, so that they can be easily distinguished from
-value parameters. Functions like \verb@concat@ that take type
-parameters are called {\em polymorphic}. The term comes from the
-Greek, where it means ``having many forms''.
-
-To apply \verb@concat@, we pass type parameters as well as value
-parameters to it. For instance,
-\begin{verbatim}
-val diag3 = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1));
-concat[int](diag3)
-\end{verbatim}
-yields \verb@List(1, 0, 0, 0, 1, 0, 0, 0, 1)@.
-
-\paragraph{Local Type Inference.}
-Passing type parameters such as \verb@[int]@ all the time can become
-tedious in applications where polymorphic functions are used a
-lot. Quite often, the information in a type parameter is redundant,
-because the correct parameter type can also be determined by
-inspecting the function's value parameters or expected result type.
-Taking \verb@concat[int](diag3)@ function as an example, we know that
-its value parameter is of type \verb@List[List[int]]@, so we can
-deduce that the type parameter must be \verb@int@. Scala has a
-fairly powerful type inferencer which allows one to omit type
-parameters to polymorphic functions and constructors in situations
-like these. In the example above, the \verb@int@ type parameter would
-have been inferred if it was not given explicitly. In fact, the same
-principle applies in the definition of the value \verb@diag3@.
-Here, type parameters have been inferred for the four calls of
-\verb@List@.
-
-\paragraph{Definition of class \verb@List@}
-
-Lists are not built in in Scala; they are defined by an abstract class
-\verb@List@, which comes with two subclasses for \verb@::@ and \verb@Nil@.
-In the following we present a tour through class \verb@List@.
-\begin{verbatim}
-package scala;
-abstract class List[+a] {
-\end{verbatim}
-\verb@List@ is an abstract class, so one cannot define elements by
-calling the empty \verb@List@ constructor (e.g. by
-\verb@new List@). The class has a type parameter \verb@a@. It is
-co-variant in this parameter, which means that
-\verb@List[S] <: List[T]@ for all types \verb@S@ and \verb@T@ such that
-\verb@S <: T@. The class is situated in the package
-\verb@scala@. This is a package containing the most important standard
-classes of Scala. \verb@List@ defines a number of methods, which are
-explained in the following.
-
-First, there are the three basic functions \verb@isEmpty@,
-\verb@head@, \verb@tail@. Their implementation in terms of pattern
-matching is straightforward:
-\begin{verbatim}
-def isEmpty: boolean = match {
- case Nil => true
- case x :: xs => false
-}
-def head: a = match {
- case Nil => error("Nil.head")
- case x :: xs => x
-}
-def tail: List[a] = match {
- case Nil => error("Nil.tail")
- case x :: xs => x
-}
-\end{verbatim}
-
-The next function computes the length of a list.
-\begin{verbatim}
-def length = match {
- case Nil => 0
- case x :: xs => 1 + xs.length
-}
-\end{verbatim}
-
-\exercise Design a tail-recursive version of \verb@length@.
-
-The next two functions are the complements of \verb@head@ and
-\verb@tail@.
-\begin{verbatim}
-def last: a;
-def init: List[a];
-\end{verbatim}
-\verb@xs.last@ returns the last element of list \verb@xs@, whereas
-\verb@xs.init@ returns all elements of \verb@xs@ except the last.
-Both functions have to traverse the entire list, and are thus less
-efficient than their \verb@head@ and \verb@tail@ analogues.
-Here is the implementation of \verb@last@.
-\begin{verbatim}
-def last: a = match {
- case Nil \==> error("Nil.last")
- case x :: Nil \>=> x
- case x :: xs \>=> xs.last
-}
-\end{verbatim}
-The implementation of \verb@init@ is analogous.
-
-The next three functions return a prefix of the list, or a suffix, or
-both.
-\begin{verbatim}
-def take(n: int): List[a] =
- if (n == 0 || isEmpty) Nil else head :: tail.take(n-1);
-
-def drop(n: int): List[a] =
- if (n == 0 || isEmpty) this else tail.drop(n-1);
-
-def split(n: int): Pair[List[a], List[a]] =
- if (n == 0 || isEmpty) Pair(Nil, this)
- else tail.split(n - 1) match { case Pair(xs, ys) => (head :: xs, ys) }
-\end{verbatim}
-\verb@(xs take n)@ returns the first \verb@n@ elements of list
-\verb@xs@, or the whole list, if its length is smaller than \verb@n@.
-\verb@(xs drop n)@ returns all elements of \verb@xs@ except the
-\verb@n@ first ones. Finally, \verb@(xs split n)@ returns a pair
-consisting of the lists resulting from \verb@xs take n@ and
-\verb@xs drop n@, but the call is more efficient than performing the
-two calls separately.
-
-The next function returns an element at a given index in a list.
-It is thus analogous to array subscripting. Indices start at 0.
-\begin{verbatim}
-def at(n: int): a = drop(n).head;
-\end{verbatim}
-
-With \verb@take@ and \verb@drop@, we can extract sublists consisting
-of consecutive elements of the original list. To extract the sublist
-$xs_m \commadots xs_{n-1}$ of a list \verb@xs@, use:
-
-\begin{verbatim}
-xs.drop(m).take(n - m)
-\end{verbatim}
-
-The next function combines two lists into a list of pairs.
-Given two lists
-\begin{verbatim}
-xs = List(x$_1$, ..., x$_n$) $\mbox{\rm, and}$
-ys = List(y$_1$, ..., y$_n$) ,
-\end{verbatim}
-\verb@xs zip ys@ constructs the list \verb@Pair(x$_1$, y$_1$), ..., Pair(x$_n$, y$_n$)@.
-If the two lists have different lengths, the longer one of the two is
-truncated. Here is the definition of \verb@zip@ -- note that it is a
-polymorphic method.
-\begin{verbatim}
-def zip[b](that: List[b]): List[Pair[a,b]] =
- if (this.isEmpty || that.isEmpty) Nil
- else Pair(this.head, that.head) :: (this.tail zip that.tail);
-\end{verbatim}
-
-Like any infix operator, \verb@::@
-is also implemented as a method of an object. In this case, the object
-is the list that is extended. This is possible, because operators
-ending with a `\verb@:@' character are treated specially in Scala.
-All such operators are treated as methods of their right operand. E.g.,
-\begin{verbatim}
- x :: y = y.::(x) \=$\mbox{\rm whereas}$ x + y = x.+(y)
-\end{verbatim}
-Note, however, that operands of a binary operation are in each case
-evaluated from left to right. So, if \verb@D@ and \verb@E@ are
-expressions with possible side-effects, \verb@D :: E@ is translated to
-\verb@{val x = D; E.::(x)}@ in order to maintain the left-to-right
-order of operand evaluation.
-
-Another difference between operators ending in a `\verb@:@' and other
-operators concerns their associativity. Operators ending in
-`\verb@:@' are right-associative, whereas other operators are
-left-associative. E.g.,
-\begin{verbatim}
- x :: y :: z = x :: (y :: z) \=$\mbox{\rm whereas}$ x + y + z = (x + y) + z
-\end{verbatim}
-The definition of \verb@::@ as a method in
-class \verb@List@ is as follows:
-\begin{verbatim}
-def ::[b >: a](x: b): List[b] = new scala.::(x, this);
-\end{verbatim}
-Note that \verb@::@ is defined for all elements \verb@x@ of type
-\verb@B@ and lists of type \verb@List[A]@ such that the type \verb@B@
-of \verb@x@ is a supertype of the list's element type \verb@A@. The result
-is in this case a list of \verb@B@'s. This
-is expressed by the type parameter \verb@b@ with lower bound \verb@a@
-in the signature of \verb@::@.
-
-An operation similar to \verb@::@ is list concatenation, written
-`\verb@:::@'. The result of \verb@(xs ::: ys)@ is a list consisting of
-all elements of \verb@xs@, followed by all elements of \verb@ys@.
-Because it ends in a colon, \verb@:::@ is right-associative and is
-considered as a method of its right-hand operand. Therefore,
-\begin{verbatim}
-xs ::: ys ::: zs \= = xs ::: (ys ::: zs)
- \> = zs.:::(ys).:::(xs)
-\end{verbatim}
-Here is the implementation of the \verb@:::@ method:
-\begin{verbatim}
- def :::[b >: a](prefix: List[b]): List[b] = prefix match {
- case Nil => this
- case p :: ps => this.:::(ps).::(p)
- }
-\end{verbatim}
-
-\paragraph{Example: Reverse.} As another example of how to program with
-lists consider a list reversal. There is a method \verb@reverse@ in
-\verb@List@ to that effect, but let's implement it as a function
-outside the class. Here is a possible implementation of
-\verb@reverse@:
-\begin{verbatim}
-def reverse[a](xs: List[a]): List[a] = xs match {
- case List() => List()
- case x :: xs => reverse(xs) ::: List(x)
-}
-\end{verbatim}
-The implementation is quite simple. However, it is not very efficient.
-Indeed, one concatenation is executed for every element in the
-list. List concatenation takes time proportional to the length
-of its first operand. Therefore, the complexity of \verb@reverse(xs)@ is
-\[
-n + (n - 1) + ... + 1 = n(n+1)/2
-\]
-where $n$ is the length of \verb@xs@. Can \verb@reverse@ be
-implemented more efficiently? We will see later that there is exists
-another implementation which has only linear complexity.
-
-\paragraph{Example: Merge sort.}
-The insertion sort presented earlier in this chapter is simple to
-formulate, but also not very efficient. It's average complexity is
-proportional to the square of the length of the input list. We now
-design a program to sort the elements of a list which is more
-efficient than insertion sort. A good algorithm for this is {\em merge
-sort}, which works as follows.
-
-First, if the list has zero or one elements, it is already sorted, so
-one returns the list unchanged. Longer lists are split into two
-sub-lists, each containing about half the elements of the original
-list. Each sub-list is sorted by a recursive call to the sort
-function, and the resulting two sorted lists are then combined in a
-merge operation.
-
-For a general implementation of merge sort, we still have to specify
-the type of list elements to be sorted, as well as the function to be
-used for the comparison of elements. We obtain a function of maximal
-generality by passing these two items as parameters. This leads to the
-following implementation.
-\begin{verbatim}
-def msort[a](less: (a, a) => boolean)(xs: List[a]): List[a] = {
- val n = xs.length/2;
- if (n == 0) xs
- else {
- def merge(xs1: List[a], xs2: List[a]): List[a] =
- if (xs1.isEmpty) xs2
- else if (xs2.isEmpty) xs1
- else if (less(xs1.head, xs2.head)) xs1.head :: merge(xs1.tail, xs2)
- else xs2.head :: merge(xs1, xs2.tail);
-
- merge(msort(less)(xs take n), msort(less)(xs drop n))
- }
-}
-\end{verbatim}
-The complexity of \verb@msort@ is $O(N;log(N))$, where $N$ is the
-length of the input list. To see why, note that splitting a list in
-two and merging two sorted lists each take time proportional to the
-length of the argument list(s). Each recursive call of \verb@msort@
-halves the number of elements in its input, so there are $O(log(N))$
-consecutive recursive calls until the base case of lists of length 1
-is reached. However, for longer lists each call spawns off two
-further calls. Adding everything up we obtain that at each of the
-$O(log(N))$ call levels, every element of the original lists takes
-part in one split operation and in one merge operation. Hence, every
-call level has a total cost proportional to $O(N)$. Since there are
-$O(log(N))$ call levels, we obtain an overall cost of
-$O(N;log(N))$. That cost does not depend on the initial distribution
-of elements in the list, so the worst case cost is the same as the
-average case cost. This makes merge sort an attractive algorithm for
-sorting lists.
-
-Here is an example how \verb@msort@ is used.
-\begin{verbatim}
-def iless(x: int, y: int) = x < y
-msort(iless)(List(5, 7, 1, 3))
-\end{verbatim}
-The definition of \verb@msort@ is curried, to make it easy to specialize it with particular
-comparison functions. For instance,
-\begin{verbatim}
-
-val intSort = msort(iless)
-val reverseSort = msort(x: int, y: int => x > y)
-\end{verbatim}
-
-\section*{Higher-Order Methods}
-
-\chapter{Computing with Streams}
-
-The previous chapters have introduced variables, assignment and
-stateful objects. We have seen how real-world objects that change
-with time can be modelled by changing the state of variables in a
-computation. Time changes in the real world thus are modelled by time
-changes in program execution. Of course, such time changes are usually
-stretched out or compressed, but their relative order is the same.
-This seems quite natural, but there is a also price to pay: Our simple
-and powerful substitution model for functional computation is no
-longer applicable once we introduce variables and assignment.
-
-Is there another way? Can we model state change in the real world
-using only immutable functions? Taking mathematics as a guide, the
-answer is clearly yes: A time-changing quantity is simply modelled by
-a function \verb@f(t)@ with a time parameter \verb@t@. The same can be
-done in computation. Instead of overwriting a variable with successive
-values, we represent all these values as successive elements in a
-list. So, a mutabel variable \verb@var x: T@ gets replaced by an
-immutable value \verb@val x: List[T]@. In a sense, we trade space for
-time -- the different values of the variable now all exit concurrently
-as different elements of the list. One advantage of the list-based
-view is that we can ``time-travel'', i.e. view several successive
-values of the variable at the same time. Another advantage is that we
-can make use of the powerful library of list processing functions,
-which often simplifies computation. For instance, consider the way
-imperative way to compute the sum of all prime numbers in an interval:
-\begin{verbatim}
-def sumPrimes(start: int, end: int): int = {
- var i = start;
- var acc = 0;
- while (i < end) {
- if (isPrime(i)) acc = acc + i;
- i = i + 1;
- }
- acc
-}
-\end{verbatim}
-Note that the variable \verb@i@ ``steps through'' all values of the interval
-\verb@[start .. end-1]@.
-%\es\bs
-A more functional way is to represent the list of values of variable \verb@i@ directly as \verb@range(start, end)@. Then the function can be rewritten as follows.
-\begin{verbatim}
-def sumPrimes(start: int, end: int) =
- sum(range(start, end) filter isPrime);
-\end{verbatim}
-
-No contest which program is shorter and clearer! However, the
-functional program is also considerably less efficient since it
-constructs a list of all numbers in the interval, and then another one
-for the prime numbers. Even worse from an efficiency point of view is
-the following example:
-
-To find the second prime number between \verb@1000@ and \verb@10000@:
-\begin{verbatim}
- range(1000, 10000) filter isPrime at 1
-\end{verbatim}
-Here, the list of all numbers between \verb@1000@ and \verb@10000@ is
-constructed. But most of that list is never inspected!
-
-However, we can obtain efficient execution for examples like these by
-a trick:
-\begin{quote}
-%\red
- Avoid computing the tail of a sequence unless that tail is actually
- necessary for the computation.
-\end{quote}
-We define a new class for such sequences, which is called \verb@Stream@.
-
-Streams are created using the constant \verb@empty@ and the constructor \verb@cons@,
-which are both defined in module \verb@scala.Stream@. For instance, the following
-expression constructs a stream with elements \verb@1@ and \verb@2@:
-\begin{verbatim}
-Stream.cons(1, Stream.cons(2, Stream.empty))
-\end{verbatim}
-As another example, here is the analogue of \verb@List.range@,
-but returning a stream instead of a list:
-\begin{verbatim}
-def range(start: Int, end: Int): Stream[Int] =
- if (start >= end) Stream.empty
- else Stream.cons(start, range(start + 1, end));
-\end{verbatim}
-(This function is also defined as given above in module
-\verb@Stream@). Even though \verb@Stream.range@ and \verb@List.range@
-look similar, their execution behavior is completely different:
-
-\verb@Stream.range@ immediately returns with a \verb@Stream@ object
-whose first element is \verb@start@. All other elements are computed
-only when they are \emph{demanded} by calling the \verb@tail@ method
-(which might be never at all).
-
-Streams are accessed just as lists. as for lists, the basic access
-methods are \verb@isEmpty@, \verb@head@ and \verb@tail@. For instance,
-we can print all elements of a stream as follows.
-\begin{verbatim}
-def print(xs: Stream[a]): unit =
- if (!xs.isEmpty) { System.out.println(xs.head); print(xs.tail) }
-\end{verbatim}
-Streams also support almost all other methods defined on lists (see
-below for where their methods sets differ). For instance, we can find
-the second prime number between \verb@1000@ and \verb@10000@ by applying methods
-\verb@filter@ and \verb@at@ on an interval stream:
-\begin{verbatim}
- Stream.range(1000, 10000) filter isPrime at 1
-\end{verbatim}
-The difference to the previous list-based implementation is that now
-we do not needlessly construct and test for primality any numbers
-beyond 3.
-
-\paragraph{Consing and appending streams.} Two methods in class \verb@List@
-which are not supported by class \verb@Stream@ are \verb@::@ and
-\verb@:::@. The reason is that these methods are dispatched on their
-right-hand side argument, which means that this argument needs to be
-evaluated before the method is called. For instance, in the case of
-\verb@x :: xs@ on lists, the tail \verb@xs@ needs to be evaluated
-before \verb@::@ can be called and the new list can be constructed.
-This does not work for streams, where we require that the tail of a
-stream should not be evaluated until it is demanded by a \verb@tail@ operation.
-The argument why list-append \verb@:::@ cannot be adapted to streams is analogous.
-
-Intstead of \verb@x :: xs@, one uses \verb@Stream.cons(x, xs)@ for
-constructing a stream with first element \verb@x@ and (unevaluated)
-rest \verb@xs@. Instead of \verb@xs ::: ys@, one uses the operation
-\verb@xs append ys@.
-
-%\redtext
-{Is there another way?}
-
-
-
-\bibliography{examples}
-\end{document}
-
-
-
-\paragrph{Higher Order Functions
-\bsh{Patterns of Computation over Lists}
-
-\bi
-\item The examples show that functions over lists often have similar
- structures
-\item We can identify several patterns of computation like
- \bi
- \item Transform every element of a list in some way.
- \item Extract from a list all elements satisfying a criterion.
- \item Combine the elements of a list using some operator.
- \ei
-\item Functional programming languages enable programmers to write
- general functions which implement patterns like this
-\item These functions are \redtext{\em higher-order functions} which get
- a transformation or an operator as one argument
-\ei
-\es
-
-Pairs, and tuples or greater arity are useful enough to
-
-
-
-
-
-\chapter{Generic Types and Methods}
-
-Classes in Scala can have type parameters. We demonstrate the use of
-type parameters with iterators as an example. An iterator is an object
-which traverses a sequence of values, using two abstract methods.
-\begin{verbatim}
-abstract class Iterator[a] {
- def hasNext: boolean;
- def next: a;
-\end{verbatim}
-Method \verb@next@ returns successive elements. Method \verb@hasNext@
-indicates whether there are still more elements to be returned by
-\verb@next@. The type of the elements returned by an iterator is
-arbitrary. We express this by giving the class \verb@Iterator@ the
-type parameter \verb@a@. Type parameters are written in square
-brackets, in contrast to normal value parameters, which are written in
-parentheses. Iterators also support other methods, which are
-explained later.
-
-Here's an iterator which traverses an interval of integer values.
-\begin{verbatim}
-class RangeIterator(start: int, end: int) extends Iterator[int] {
- private var current = 0;
- def hasNext = current < end;
- def next = {
- val r = current;
- if (current < end) current = current + 1
- else error("end of iterator");
- r
- }
-}
-\end{verbatim}
-The superclass of \verb@RangeIterator@ is \verb@Iterator[int]@,
-i.e. an iterator returning integer numbers.
-
-Note that, unlike the classes we have seen so far,
-\verb@RangeIterator@ has internal state
-
-
-Here is a function that takes an iterator of arbitrary element type
-\verb@a@ and a procedure that maps \verb@a@-values to the trivial type \verb@unit@.
-It applies the given function to every value returned by the iterator.
-\begin{verbatim}
- def forall[a](i: Iterator[a])(f: a => boolean): boolean =
- !hasNext || { val x = next; f(x) && forall(i, f) }
-\end{verbatim}
-\verb@forEach@ can work with any type of iterator,
-since the iterator's element type is passed as a type parameter \verb@a@.
-Functions that take type parameters are called {\em polymorphic}. The term
-comes from Greek, where it means ``having many forms''.
-
-Finally, here is an application which uses \verb@RangeIterator@ and
-\verb@foreach@ to test whether a given number is prime, i.e. whether it can be
-divided only by 1 and itself.
-\begin{verbatim}
-def isPrime(x: int) =
- forall[int](new RangeIterator(2, n)) { x => x % n != 0 }
-\end{verbatim}
-As always, the actual parameters of \verb@forEach@ correspond to its
-formal parameters. First comes the type parameter \verb@int@, which
-determines the element type of the iterator which is passed next.
-
-\paragraph{Local Type Inference.}
-Passing type parameters such as \verb@[int]@ all the time can become
-tedious in applications where polymorphic functions are used a
-lot. Quite often, the information in a type parameter is redundant,
-because the correct parameter type can also be determined by
-inspecting the function's value parameters or expected result type.
-Taking the \verb@isPrime@ function as an example, we know that its
-first value parameter is of type \verb@Iterator[int]@, so we can
-determine the type parameter \verb@int@ from it. Scala contains a
-fairly powerful local type inferencer which allows one to omit type
-parameters to polymorphic functions and constructors in situations
-like these. In the example above, the \verb@int@ type parameter would
-have been inferred if it was not given explicitly.
-
-Here is another
-application which prints all prime numbers between 1 and 10000.
-\begin{verbatim}
-forall(new RangeIterator(1, 10001)){ x => if (isPrime(x)) System.out.println(x) }
-\end{verbatim}
-This time, the type parameter for \verb@forEach@ was omitted (and was
-inferred to be \verb@int@).
-
-Method \verb@append@ constructs an iterator which resumes with the
-given iterator \verb@it@ after the current iterator has finished.
-\begin{verbatim}
- def append(that: Iterator[a]): Iterator[a] = new Iterator[a] {
- def hasNext = outer.hasNext || that.hasNext;
- def next = if (outer.hasNext) outer.next else that.next;
- }
-\end{verbatim}
-The terms \verb@outer.next@ and \verb@outer.hasNext@ in the definition
-of \verb@append@ call the corresponding methods as they are defined in
-the enclosing \verb@Iterator@ class. Generally, an
-\verb@outer@ prefix in a selection indicates an identifier that is
-visible immediately outside the current class or template. If the
-\verb@outer@ prefix would have been missing,
-\verb@hasNext@ and \verb@next@ would have
-called recursively the methods being defined in the iterator
-constructed by \verb@append@, which is not what we want.
-
-Method \verb@filter@ constructs an iterator which returns all elements
-of the original iterator that satisfy a criterion \verb@p@.
-\begin{verbatim}
- def filter(p: a => boolean) = new Iterator[a] {
- private class Cell[T](elem_: T) { def elem = elem_; }
- private var head: Cell[a] = null;
- private var isAhead = false;
- def hasNext: boolean =
- if (isAhead) true
- else if (outer.hasNext) {
- head = Cell(outer.next); isAhead = p(head.elem); hasNext }
- else false;
- def next: a =
- if (hasNext) { isAhead = false; head.elem }
- else error("next on empty iterator");
- }
-\end{verbatim}
-Method \verb@map@ constructs an iterator which returns all elements of
-the original iterator transformed by a given function \verb@f@.
-\begin{verbatim}
- def map[b](f: a => b) = new Iterator[b] {
- def hasNext: boolean = outer.hasNext;
- def next: b = f(outer.next);
- }
-\end{verbatim}
-The return type of the transformation function \verb@f@ is
-arbitrary. This is expressed by a type parameter \verb@b@ in the
-signature of method \verb@map@, which represents the return type.
-We also say, \verb@map@ is a {\em polymorphic} function.
-
-Method \verb@flatMap@ is like method \verb@map@, except that the
-transformation function \verb@f@ now returns an iterator.
-The result of \verb@flatMap@ is the iterator resulting from appending
-together all iterators returned from successive calls of \verb@f@.
-\begin{verbatim}
- private var cur: Iterator[b] = new EmptyIterator[b];
- def hasNext: boolean =
- if (cur.hasNext) true
- else if (outer.hasNext) { cur = f(outer.next); hasNext }
- else false;
- def next: b =
- if (cur.hasNext) cur.next
- else if (outer.hasNext) { cur = f(outer.next); next }
- else error("next on empty iterator");
- }
-\end{verbatim}
-Finally, method \verb@zip@ takes another iterator and
-returns an iterator consisting of pairs of corresponding elements
-returned by the two iterators.
-\begin{verbatim}
- def zip[b](that: Iterator[b]) = new Iterator[(a, b)] {
- def hasNext = outer.hasNext && that.hasNext;
- def next = (outer.next, that.next);
- }
-} //end iterator;
-\end{verbatim}
-Concrete iterators need to provide implementations for the two
-abstract methods \verb@next@ and \verb@hasNext@ in class
-\verb@Iterator@. The simplest iterator is \verb@EmptyIterator@
-which always returns an empty sequence:
-\begin{verbatim}
-class EmptyIterator[a] extends Iterator[a] {
- def hasNext = false;
- def next: a = error("next on empty iterator");
-}
-\end{verbatim}
-A more interesting iterator enumerates all elements of an array.
-This iterator is formulated here as a polymorphic function. It could
-have also been written as a class, like \verb@EmptyIterator@. The
-difference between the two formulation is that classes also define new
-types, whereas functions do not.
-\begin{verbatim}
-def arrayIterator[a](xs: Array[a]) = new Iterator[a] {
- private var i = 0;
- def hasNext: boolean =
- i < xs.length;
- def next: a =
- if (i < xs.length) { val x = xs(i) ; i = i + 1 ; x }
- else error("next on empty iterator");
-}
-\end{verbatim}
-Another iterator enumerates an integer interval:
-\begin{verbatim}
-def range(lo: int, hi: int) = new Iterator[int] {
- private var i = lo;
- def hasNext: boolean =
- i <= hi;
- def next: int =
- if (i <= hi) { i = i + 1 ; i - 1 }
- else error("next on empty iterator");
-}
-\end{verbatim}
-%In fact, enumerating integer intervals is so common that it is
-%supported by a method
-%\begin{verbatim}
-%def to(hi: int): Iterator[int]
-%\end{verbatim}
-%in class \verb@int@. Hence, one could also write \verb@l to h@ instead of
-%\verb@range(l, h)@.
-All iterators seen so far terminate eventually. It is also possible to
-define iterators that go on forever. For instance, the following
-iterator returns successive integers from some start
-value\footnote{Due to the finite representation of type \prog{int},
-numbers will wrap around at $2^31$.}.
-\begin{verbatim}
-def from(start: int) = new Iterator[int] {
- private var last = start - 1;
- def hasNext = true;
- def next = { last = last + 1; last }
-}
-\end{verbatim}
-Here are two examples how iterators are used. First, to print all
-elements of an array \verb@xs: Array[int]@, one can write:
-\begin{verbatim}
- arrayIterator[int](xs) foreach (x => System.out.println(x))
-\end{verbatim}
-Here, \verb@[int]@ is a type argument clause, which matches the type
-parameter clause \verb@[a]@ of function \verb@arrayIterator@. It
-substitutes the formal argument \verb@int@ for the formal argument
-\verb@a@ in the type of the method that follows. Hence,
-\verb@arrayIterator[a]@ is a function that takes an \verb@Array[int]@
-and that returns an \verb@Iterator[int]@.
-
-In this example, the formal type argument \verb@int@ is redundant
-since it could also have been inferred from the value \verb@xs@, which
-is, after all, an array of \verb@int@. The Scala compiler contains a
-fairly powerful type inferencer which infers type arguments for
-methods and constructors from the types of value arguments and the
-expected return type. In our example, the \verb@[int]@ clause can be
-inferred, so that one can abbreviate to:
-\begin{verbatim}
- arrayIterator(xs) foreach (x => System.out.println(x))
-\end{verbatim}
-%As a second example, consider the problem of finding the indices of
-%all the elements in an array of \verb@double@s greater than some
-%\verb@limit@. The indices should be returned as an iterator.
-%This is achieved by the following expression.
-%\begin{verbatim}
-%arrayIterator(xs)
-% .zip(from(0))
-% .filter(x, i => x > limit)
-% .map(x, i => i)
-%\end{verbatim}
-%The first line in this expression iterates through all array elements,
-%the second lines pairs elements with their indices, the third line
-%selects all value/index pairs where the value is greater than
-%\verb@limit@, and the fourth line returns the index part of all
-%selected pairs.
-
-%Note that we have omitted the type arguments for the calls of
-%\verb@arrayIterator@, \verb@zip@ and \verb@map@. These are all
-%implicitly inserted by the type inferencer.
-
-
-
-\es
-\paragraph{Abstract Methods.}
-Classes can also omit some of the definitions of their members. As an
-example, consider the following class \verb@Ord@ which provides the
-comparison operators \verb@<, >, <=, >=@.
-%\begin{verbatim}
-%abstract class Ord {
-% abstract def <(that: this);
-% def <=(that: this) = this < that || this == that;
-% def >(that: this) = that < this;
-% def >=(that: this) = that <= this;
-%}
-%\end{verbatim}
-\begin{verbatim}
-abstract class Ord {
- def <(that: this): boolean;
- def <=(that: this) = this < that || this == that;
- def >(that: this) = that < this;
- def >=(that: this) = that <= this;
-}
-\end{verbatim}
-Since we want to leave open which objects are compared, we are unable
-to give an implementation for the \verb@<@ method. However, once
-\verb@<@ is given, we can define the other three comparison operators
-in terms of \verb@<@ and the equality test \verb@==@ (which is defined
-in class \verb@Object@). This is expressed by having in \verb@Ord@ an
-{\em abstract} method \verb@<@ to which the implementations of the
-other methods refer.
-
-\paragraph{Self References.} The name \verb@this@ refers in this class
-to the current object. The type of \verb@this@ is also called
-\verb@this@ (generally, every name in Scala can have a definition as a
-term and another one as a type). When used as a type, \verb@this@
-refers to the type of the current object. This type is always
-compatible with the class being defined (\verb@Ord@ in this case).
-
-\paragraph{Mixin Composition.}
-We can now define a class of \verb@Rational@ numbers that
-support comparison operators.
-\begin{verbatim}
-final class OrderedRational(n: int, d: int)
- extends Rational(n, d) with Ord {
- override def ==(that: OrderedRational) =
- numer == that.numer && denom == that.denom;
- def <(that: OrderedRational): boolean =
- numer * that.denom < that.numer * denom;
-}
-\end{verbatim}
-Class \verb@OrderedRational@ redefines method \verb@==@, which is
-defined as reference equality in class \verb@Object@. It also
-implements the abstract method \verb@<@ from class \verb@Ord@. In
-addition, it inherits all members of class \verb@Rational@ and all
-non-abstract members of class \verb@Ord@. The implementations of
-\verb@==@ and \verb@<@ replace the definition of \verb@==@ in class
-\verb@Object@ and the abstract declaration of \verb@<@ in class
-\verb@Ord@. The other inherited comparison methods then refer to this
-implementation in their body.
-
-The clause ``\verb@Rational(d, d) with Ord@'' is an instance of {\em
-mixin composition}. It describes a template for an object that is
-compatible with both \verb@Rational@ and \verb@Ord@ and that contains
-all members of either class. \verb@Rational@ is called the {\em
-superclass} of \verb@OrderedRational@ while \verb@Ord@ is called a
-{\em mixin class}. The type of this template is the {\em compound
-type} ``\verb@Rational with Ord@''.
-
-On the surface, mixin composition looks much like multiple
-inheritance. The difference between the two becomes apparent if we
-look at superclasses of inherited classes. With multiple inheritance,
-both \verb@Rational@ and \verb@Ord@ would contribute a superclass
-\verb@Object@ to the template. We therefore have to answer some
-tricky questions, such as whether members of \verb@Object@ are present
-once or twice and whether the initializer of \verb@Object@ is called
-once or twice. Mixin composition avoids these complications. In the
-mixin composition \verb@Rational with Ord@, class
-\verb@Rational@ is treated as actual superclass of class \verb@Ord@.
-A mixin composition \verb@C with M@ is well-formed as long as the
-first operand \verb@C@ conforms to the declared superclass of the
-second operand \verb@M@. This holds in our example, because
-\verb@Rational@ conforms to \verb@Object@. In a sense, mixin composition
-amounts to overriding the superclass of a class.
-
-\paragraph{Final Classes.}
-Note that class \verb@OrderedRational@ was defined
-\verb@final@. This means that no classes extending \verb@OrderedRational@
-may be defined in other parts of the program.
-%Within final classes the
-%type \verb@this@ is an alias of the defined class itself. Therefore,
-%we could define our \verb@<@ method with an argument of type
-%\verb@OrderedRational@ as a well-formed implementation of the abstract class
-%\verb@less(that: this)@ in class \verb@Ord@.
-
-
-\chapter{Generic Types and Methods}
-
-Classes in Scala can have type parameters. We demonstrate the use of
-type parameters with iterators as an example. An iterator is an object
-which traverses a sequence of values, using two abstract methods.
-\begin{verbatim}
-abstract class Iterator[a] {
- def hasNext: boolean;
- def next: a;
-\end{verbatim}
-Method \verb@next@ returns successive elements. Method \verb@hasNext@
-indicates whether there are still more elements to be returned by
-\verb@next@. The type of elements returned by an iterator is
-arbitrary. We express that by giving the class \verb@Iterator@ the
-type parameter \verb@a@. Type parameters are written in square
-brackets, in contrast to normal value parameters, which are written in
-parentheses. Iterators also support other methods, which are
-explained in the following.
-
-Method \verb@foreach@ applies a procedure (i.e. a function
-returning \verb@unit@ to each element returned by the iterator:
-\begin{verbatim}
- def foreach(f: a => unit): unit =
- while (hasNext) { f(next) }
-\end{verbatim}
-
-Method \verb@append@ constructs an iterator which resumes with the
-given iterator \verb@it@ after the current iterator has finished.
-\begin{verbatim}
- def append(that: Iterator[a]): Iterator[a] = new Iterator[a] {
- def hasNext = outer.hasNext || that.hasNext;
- def next = if (outer.hasNext) outer.next else that.next;
- }
-\end{verbatim}
-The terms \verb@outer.next@ and \verb@outer.hasNext@ in the definition
-of \verb@append@ call the corresponding methods as they are defined in
-the enclosing \verb@Iterator@ class. Generally, an
-\verb@outer@ prefix in a selection indicates an identifier that is
-visible immediately outside the current class or template. If the
-\verb@outer@ prefix would have been missing,
-\verb@hasNext@ and \verb@next@ would have
-called recursively the methods being defined in the iterator
-constructed by \verb@append@, which is not what we want.
-
-Method \verb@filter@ constructs an iterator which returns all elements
-of the original iterator that satisfy a criterion \verb@p@.
-\begin{verbatim}
- def filter(p: a => boolean) = new Iterator[a] {
- private class Cell[T](elem_: T) { def elem = elem_; }
- private var head: Cell[a] = null;
- private var isAhead = false;
- def hasNext: boolean =
- if (isAhead) true
- else if (outer.hasNext) {
- head = Cell(outer.next); isAhead = p(head.elem); hasNext }
- else false;
- def next: a =
- if (hasNext) { isAhead = false; head.elem }
- else error("next on empty iterator");
- }
-\end{verbatim}
-Method \verb@map@ constructs an iterator which returns all elements of
-the original iterator transformed by a given function \verb@f@.
-\begin{verbatim}
- def map[b](f: a => b) = new Iterator[b] {
- def hasNext: boolean = outer.hasNext;
- def next: b = f(outer.next);
- }
-\end{verbatim}
-The return type of the transformation function \verb@f@ is
-arbitrary. This is expressed by a type parameter \verb@b@ in the
-signature of method \verb@map@, which represents the return type.
-We also say, \verb@map@ is a {\em polymorphic} function.
-
-Method \verb@flatMap@ is like method \verb@map@, except that the
-transformation function \verb@f@ now returns an iterator.
-The result of \verb@flatMap@ is the iterator resulting from appending
-together all iterators returned from successive calls of \verb@f@.
-\begin{verbatim}
- private var cur: Iterator[b] = new EmptyIterator[b];
- def hasNext: boolean =
- if (cur.hasNext) true
- else if (outer.hasNext) { cur = f(outer.next); hasNext }
- else false;
- def next: b =
- if (cur.hasNext) cur.next
- else if (outer.hasNext) { cur = f(outer.next); next }
- else error("next on empty iterator");
- }
-\end{verbatim}
-Finally, method \verb@zip@ takes another iterator and
-returns an iterator consisting of pairs of corresponding elements
-returned by the two iterators.
-\begin{verbatim}
- def zip[b](that: Iterator[b]) = new Iterator[(a, b)] {
- def hasNext = outer.hasNext && that.hasNext;
- def next = (outer.next, that.next);
- }
-} //end iterator;
-\end{verbatim}
-Concrete iterators need to provide implementations for the two
-abstract methods \verb@next@ and \verb@hasNext@ in class
-\verb@Iterator@. The simplest iterator is \verb@EmptyIterator@
-which always returns an empty sequence:
-\begin{verbatim}
-class EmptyIterator[a] extends Iterator[a] {
- def hasNext = false;
- def next: a = error("next on empty iterator");
-}
-\end{verbatim}
-A more interesting iterator enumerates all elements of an array.
-This iterator is formulated here as a polymorphic function. It could
-have also been written as a class, like \verb@EmptyIterator@. The
-difference between the two formulation is that classes also define new
-types, whereas functions do not.
-\begin{verbatim}
-def arrayIterator[a](xs: Array[a]) = new Iterator[a] {
- private var i = 0;
- def hasNext: boolean =
- i < xs.length;
- def next: a =
- if (i < xs.length) { val x = xs(i) ; i = i + 1 ; x }
- else error("next on empty iterator");
-}
-\end{verbatim}
-Another iterator enumerates an integer interval:
-\begin{verbatim}
-def range(lo: int, hi: int) = new Iterator[int] {
- private var i = lo;
- def hasNext: boolean =
- i <= hi;
- def next: int =
- if (i <= hi) { i = i + 1 ; i - 1 }
- else error("next on empty iterator");
-}
-\end{verbatim}
-%In fact, enumerating integer intervals is so common that it is
-%supported by a method
-%\begin{verbatim}
-%def to(hi: int): Iterator[int]
-%\end{verbatim}
-%in class \verb@int@. Hence, one could also write \verb@l to h@ instead of
-%\verb@range(l, h)@.
-All iterators seen so far terminate eventually. It is also possible to
-define iterators that go on forever. For instance, the following
-iterator returns successive integers from some start
-value\footnote{Due to the finite representation of type \prog{int},
-numbers will wrap around at $2^31$.}.
-\begin{verbatim}
-def from(start: int) = new Iterator[int] {
- private var last = start - 1;
- def hasNext = true;
- def next = { last = last + 1; last }
-}
-\end{verbatim}
-Here are two examples how iterators are used. First, to print all
-elements of an array \verb@xs: Array[int]@, one can write:
-\begin{verbatim}
- arrayIterator[int](xs) foreach (x => System.out.println(x))
-\end{verbatim}
-Here, \verb@[int]@ is a type argument clause, which matches the type
-parameter clause \verb@[a]@ of function \verb@arrayIterator@. It
-substitutes the formal argument \verb@int@ for the formal argument
-\verb@a@ in the type of the method that follows. Hence,
-\verb@arrayIterator[a]@ is a function that takes an \verb@Array[int]@
-and that returns an \verb@Iterator[int]@.
-
-In this example, the formal type argument \verb@int@ is redundant
-since it could also have been inferred from the value \verb@xs@, which
-is, after all, an array of \verb@int@. The Scala compiler contains a
-fairly powerful type inferencer which infers type arguments for
-methods and constructors from the types of value arguments and the
-expected return type. In our example, the \verb@[int]@ clause can be
-inferred, so that one can abbreviate to:
-\begin{verbatim}
- arrayIterator(xs) foreach (x => System.out.println(x))
-\end{verbatim}
-%As a second example, consider the problem of finding the indices of
-%all the elements in an array of \verb@double@s greater than some
-%\verb@limit@. The indices should be returned as an iterator.
-%This is achieved by the following expression.
-%\begin{verbatim}
-%arrayIterator(xs)
-% .zip(from(0))
-% .filter(x, i => x > limit)
-% .map(x, i => i)
-%\end{verbatim}
-%The first line in this expression iterates through all array elements,
-%the second lines pairs elements with their indices, the third line
-%selects all value/index pairs where the value is greater than
-%\verb@limit@, and the fourth line returns the index part of all
-%selected pairs.
-
-%Note that we have omitted the type arguments for the calls of
-%\verb@arrayIterator@, \verb@zip@ and \verb@map@. These are all
-%implicitly inserted by the type inferencer.
-
-\chapter{\label{sec:for-notation}For-Comprehensions}
-
-The last chapter has demonstrated that the use of higher-order
-functions over sequences can lead to very concise programs. But
-sometimes the level of abstraction required by these functions makes a
-program hard to understand.
-
-Here, Scala's \verb@for@ notation can help. For instance, say we are
-given a sequence \verb@persons@ of persons with \verb@name@ and
-\verb@age@ fields. That sequence could be an array, or a list, or an
-iterator, or some other type implementing the sequence abstraction
-(this will be made more precise below). To print the names of all
-persons in the sequence which are aged over 20, one writes:
-\begin{verbatim}
-for { val p <- persons; p.age > 20 } yield p.name
-\end{verbatim}
-This is equivalent to the following expression , which uses
-higher-order functions \verb@filter@ and \verb@map@:
-\begin{verbatim}
-persons filter (p => p.age > 20) map (p => p.name)
-\end{verbatim}
-The for-expression looks a bit like a for-loop in imperative languages,
-except that it constructs a list of the results of all iterations.
-
-Generally, a for-comprehension is of the form
-\begin{verbatim}
-for ( s ) yield e
-\end{verbatim}
-(Instead of parentheses, braces may also be used.)
-Here, \verb@s@ is a sequence of {\em generators} and {\em filters}.
-\begin{itemize}
-\item A {\em generator} is of the form \verb@val x <- e@,
-where \verb@e@ is a list-valued expression. It binds \verb@x@ to
-successive values in the list.
-\item A {\em filter} is an expression \verb@f@ of type \verb@boolean@.
-It omits from consideration all bindings for which \verb@f@ is \verb@false@.
-\end{itemize}
-The sequence must start with a generator.
-If there are several generators in a sequence, later generators vary
-more rapidly than earlier ones.
-
-Here are two examples that show how for-comprehensions are used.
-
-First, given a positive integer \verb@n@, find all pairs of positive
-integers
-\verb@i@, \verb@j@, where \verb@1 <= j < i <= n@ such that \verb@i + j@ is prime.
-\begin{verbatim}
-for \={ \=val i <- range(1, n);
- \> \>val j <- range(1, i-1);
- \> \>isPrime(i+j)
-} yield (i, j)
-\end{verbatim}
-
-As second example, the scalar product of two vectors \verb@xs@ and
-\verb@ys@ can now be written as
-follows.
-\begin{verbatim}
- sum (for { val (x, y) <- xs zip ys } yield x * y)
-\end{verbatim}
-The for-notation is essentially equivalent to common operations of
-database query languages. For instance, say we are given a book
-database \verb@books@, represented as a list of books, where
-\verb@Book@ is defined as follows.
-\begin{verbatim}
-abstract class Book {
- val title: String;
- val authors: List[String]
-}
-\end{verbatim}
-\begin{verbatim}
-val books: List[Book] = [
- new Book {
- val title = "Structure and Interpretation of Computer Programs";
- val authors = ["Abelson, Harald", "Sussman, Gerald J."];
- },
- new Book {
- val title = "Principles of Compiler Design";
- val authors = ["Aho, Alfred", "Ullman, Jeffrey"];
- },
- new Book {
- val title = "Programming in Modula-2";
- val authors = ["Wirth, Niklaus"];
- }
-];
-\end{verbatim}
-Then, to find the titles of all books whose author's last name is ``Ullman'':
-\begin{verbatim}
-for { val b <- books; val a <- b.authors; a startsWith "Ullman"
-} yield b.title
-\end{verbatim}
-(Here, \verb@startsWith@ is a method in \verb@java.lang.String@). Or,
-to find the titles of all books that have the string ``Program'' in
-their title:
-\begin{verbatim}
-for { val b <- books; (b.title indexOf "Program") >= 0
-} yield b.title
-\end{verbatim}
-Or, to find the names of all authors that have written at least two
-books in the database.
-\begin{verbatim}
-for { \=val b1 <- books;
- \>val b2 <- books;
- \>b1 != b2;
- \>val a1 <- b1.authors;
- \>val a2 <- b2.authors;
- \>a1 == a2 } yield a1
-\end{verbatim}
-The last solution is not yet perfect, because authors will appear
-several times in the list of results. We still need to remove
-duplicate authors from result lists. This can be achieved with the
-following function.
-\begin{verbatim}
-def removeDuplicates[a](xs: List[a]): List[a] =
- if (xs.isEmpty) xs
- else xs.head :: removeDuplicates(xs.tail filter (x => x != xs.head));
-\end{verbatim}
-The last expression can be equivalently expressed as follows.
-\begin{verbatim}
-xs.head :: removeDuplicates(for (val x <- xs.tail; x != xs.head) yield x)
-\end{verbatim}
-
-\subsection*{Translation of \prog{for}}
-
-Every for-comprehensions can be expressed in terms of the three
-higher-order functions \verb@map@, \verb@flatMap@ and \verb@filter@.
-Here is the translation scheme, which is also used by the Scala compiler.
-\begin{itemize}
-\item
-A simple for-comprehension
-\begin{verbatim}
-for (val x <- e) yield e'
-\end{verbatim}
-is translated to
-\begin{verbatim}
-e.map(x => e')
-\end{verbatim}
-\item
-A for-comprehension
-\begin{verbatim}
-for (val x <- e; f; s) yield e'
-\end{verbatim}
-where \verb@f@ is a filter and \verb@s@ is a (possibly empty)
-sequence of generators or filters
-is translated to
-\begin{verbatim}
-for (val x <- e.filter(x => f); s) yield e'
-\end{verbatim}
-and then translation continues with the latter expression.
-\item
-A for-comprehension
-\begin{verbatim}
-for (val x <- e; y <- e'; s) yield e''
-\end{verbatim}
-where \verb@s@ is a (possibly empty)
-sequence of generators or filters
-is translated to
-\begin{verbatim}
-e.flatMap(x => for (y <- e'; s) yield e'')
-\end{verbatim}
-and then translation continues with the latter expression.
-\end{itemize}
-For instance, taking our "pairs of integers whose sum is prime" example:
-\begin{verbatim}
-for \= { \= val i <- range(1, n);
- \> \> val j <- range(1, i-1);
- \> \> isPrime(i+j)
-} yield (i, j)
-\end{verbatim}
-Here is what we get when we translate this expression:
-\begin{verbatim}
-range(1, n)
- .flatMap(i =>
- range(1, i-1)
- .filter(j => isPrime(i+j))
- .map(j => (i, j)))
-\end{verbatim}
-
-\exercise
-Define the following function in terms of \verb@for@.
-\begin{verbatim}
-def concat(xss: List[List[a]]): List[a] =
- (xss foldr []) { xs, ys => xs ::: ys }
-\end{verbatim}
-\exercise
-Translate
-\begin{verbatim}
-for { val b <- books; val a <- b.authors; a startsWith "Bird" } yield b.title
-for { val b <- books; (b.title indexOf "Program") >= 0 } yield b.title
-\end{verbatim}
-to higher-order functions.
-
-We have seen that the for-translation only relies on the presence of
-methods \verb@map@,
-\verb@flatMap@, and \verb@filter@.
-This gives programmers the possibility to have for-syntax for
-other types as well -- one only needs to define \verb@map@,
-\verb@flatMap@, and \verb@filter@ for these types.
-That's also why we were able to define \verb@for@ at the same time for
-arrays, iterators, and lists -- all these types have the required
-three methods \verb@map@,\verb@flatMap@, and \verb@filter@ as members.
-Of course, it is also possible for users and library designers to
-define other types with these methods. There are many examples where
-this is useful: Databases, XML trees, optional values. We will see in
-Chapter~\ref{sec:parsers-results} how for-comprehensions can be used in the
-definition of parsers for context-free grammars that construct
-abstract syntax trees.
-
-\chapter{\label{sec:simple-examples}Pattern Matching}
-
-\todo{Complete}
-
-Consider binary trees whose leafs contain integer arguments. This can
-be described by a class for trees, with subclasses for leafs and
-branch nodes:
-\begin{verbatim}
-abstract class Tree;
-case class Branch(left: Tree, right: Tree) extends Tree;
-case class Leaf(x: int) extends Tree;
-\end{verbatim}
-Note that the class \verb@Tree@ is not followed by an extends
-clause or a body. This defines \verb@Tree@ to be an empty
-subclass of \verb@Object@, as if we had written
-\begin{verbatim}
-class Tree extends Object {}
-\end{verbatim}
-Note also that the two subclasses of \verb@Tree@ have a \verb@case@
-modifier. That modifier has two effects. First, it lets us construct
-values of a case class by simply calling the constructor, without
-needing a preceding \verb@new@. Example:
-\begin{verbatim}
-val tree1 = Branch(Branch(Leaf(1), Leaf(2)), Branch(Leaf(3), Leaf(4)))
-\end{verbatim}
-Second, it lets us use constructors for these classes in patterns, as
-is illustrated in the following example.
-\begin{verbatim}
-def sumLeaves(t: Tree): int = t match {
- case Branch(l, r) => sumLeaves(l) + sumLeaves(r)
- case Leaf(x) => x
-}
-\end{verbatim}
-The function \verb@sumLeaves@ sums up all the integer values in the
-leaves of a given tree \verb@t@. It is is implemented by calling the
-\verb@match@ method of \verb@t@ with a {\em choice expression} as
-argument (\verb@match@ is a predefined method in class \verb@Object@).
-The choice expression consists of two cases which both
-relate a pattern with an expression. The pattern of the first case,
-\verb@Branch(l, r)@ matches all instances of class \verb@Branch@
-and binds the {\em pattern variables} \verb@l@ and \verb@r@ to the
-constructor arguments, i.e.\ the left and right subtrees of the
-branch. Pattern variables always start with a lower case letter; to
-avoid ambiguities, constructors in patterns should start with an upper
-case letter.
-
-The effect of the choice expression is to select the first alternative
-whose pattern matches the given select value, and to evaluate the body
-of this alternative in a context where pattern variables are bound to
-corresponding parts of the selector. For instance, the application
-\verb@sumLeaves(tree1)@ would select the first alternative with the
-\verb@Branch(l,r)@ pattern, and would evaluate the expression
-\verb@sumLeaves(l) + sumLeaves(r)@ with bindings
-\begin{verbatim}
-l = Branch(Leaf(1), Leaf(2)), r = Branch(Leaf(3), Leaf(4)).
-\end{verbatim}
-As another example, consider the following class
-\begin{verbatim}
-abstract final class Option[+a];
-case object None extends Option[All];
-case class Some[a](item: a) extends Option[a];
-\end{verbatim}
-...
-
-%\todo{Several simple and intermediate examples needed}.
-
-\begin{verbatim}
-def find[a,b](it: Iterator[(a, b)], x: a): Option[b] = {
- var result: Option[b] = None;
- while (it.hasNext && result == None) {
- val (x1, y) = it.next;
- if (x == x1) result = Some(y)
- }
- result
-}
-find(xs, x) match {
- case Some(y) => System.out.println(y)
- case None => System.out.println("no match")
-}
-\end{verbatim}
-
-\comment{
-
-
-class MaxCounter {
- var maxVal: Option[int] = None;
- def set(x: int) = maxVal match {
- case None => maxVal = Some(x)
- case Some(y) => maxVal = Some(Math.max(x, y))
- }
-}
-\end{verbatim}
-}
-\comment{
-\begin{verbatim}
-class Stream[a] = List[a]
-
-module Stream {
- def concat(xss: Stream[Stream[a]]): Stream[a] = {
- let result: Stream[a] = xss match {
- case [] => []
- case [] :: xss1 => concat(xss1)
- case (x :: xs) :: xss1 => x :: concat(xs :: xss1)
- }
- result
- }
-}
-\end{verbatim}
-}
-\comment{
-\chapter{Implementing Abstract Types: Search Trees}
-
-This chapter presents unbalanced binary search trees, implemented in
-three different styles: algebraic, object-oriented, and imperative.
-In each case, a search tree package is seen as an implementation
-of a class {\em MapStruct}.
-\begin{verbatim}
-abstract class MapStruct[kt, vt] {
- abstract type Map extends kt => vt {
- def apply(key: kt): vt;
- def extend(key: kt, value: vt): Map;
- def remove(key: kt): Map;
- def domain: Stream[kt];
- def range: Stream[vt];
- }
- def empty: Map;
-}
-\end{verbatim}
-The \verb@MapStruct@ class is parameterized with a type of keys
-\verb@kt@ and a type of values \verb@vt@. It
-specifies an abstract type \verb@Map@ and an abstract value
-\verb@empty@, which represents empty maps. Every implementation
-\verb@Map@ needs to conform to that abstract type, which
-extends the function type \verb@kt => vt@
-with four new
-methods. The method \verb@domain@ yields a stream that enumerates the
-map's domain, i.e. the set of keys that are mapped to non-null values.
-The method \verb@range@ yields a stream that enumerates the function's
-range, i.e.\ the values obtained by applying the function to arguments
-in its domain. The method
-\verb@extend@ extends the map with a given key/value binding, whereas
-\verb@remove@ removes a given key from the map's domain. Both
-methods yield a new map value as result, which has the same
-representation as the receiver object.
-
-\begin{figure}[t]
-\begin{verbatim}
-class AlgBinTree[kt extends Ord, vt] extends MapStruct[kt, vt] {
- private case
- Empty extends Map,
- Node(key: kt, value: vt, l: Map, r: Map) extends Map
-
- final class Map extends kt => vt {
- def apply(key: kt): vt = this match {
- case Empty => null
- case Node(k, v, l, r) =>
- if (key < k) l.apply(key)
- else if (key > k) r.apply(key)
- else v
- }
-
- def extend(key: kt, value: vt): Map = this match {
- case Empty => Node(k, v, Empty, Empty)
- case Node(k, v, l, r) =>
- if (key < k) Node(k, v, l.extend(key, value), r)
- else if (key > k) Node(k, v, l, r.extend(key, value))
- else Node(k, value, l, r)
- }
-
- def remove(key: kt): Map = this match {
- case Empty => Empty
- case Node(k, v, l, r) =>
- if (key < k) Node(k, v, l.remove(key), r)
- else if (key > k) Node(k, v, l, r.remove(key))
- else if (l == Empty) r
- else if (r == Empty) l
- else {
- val midKey = r.domain.head
- Node(midKey, r.apply(midKey), l, r.remove(midKey))
- }
- }
-
- def domain: Stream[kt] = this match {
- case Empty => []
- case Node(k, v, l, r) => Stream.concat([l.domain, [k], r.domain])
- }
- def range: Stream[vt] = this match {
- case Empty => []
- case Node(k, v, l, r) => Stream.concat([l.range, [v], r.range])
- }
- }
- def empty: Map = Empty
-}
-\end{verbatim}
-\caption{\label{fig:algbintree}Algebraic implementation of binary
-search trees}
-\end{figure}
-We now present three implementations of \verb@Map@, which are all
-based on binary search trees. The \verb@apply@ method of a map is
-implemented in each case by the usual search function over binary
-trees, which compares a given key with the key stored in the topmost
-tree node, and depending on the result of the comparison, searches the
-left or the right hand sub-tree. The type of keys must implement the
-\verb@Ord@ class, which contains comparison methods
-(see Chapter~\ref{chap:classes} for a definition of class \verb@Ord@).
-
-The first implementation, \verb@AlgBinTree@, is given in
-Figure~\ref{fig:algbintree}. It represents a map with a
-data type \verb@Map@ with two cases, \verb@Empty@ and \verb@Node@.
-
-Every method of \verb@AlgBinTree[kt, vt].Map@ performs a pattern
-match on the value of
-\verb@this@ using the \verb@match@ method which is defined as postfix
-function application in class \verb@Object@ (\sref{sec:class-object}).
-
-The functions \verb@domain@ and \verb@range@ return their results as
-lazily constructed lists. The \verb@Stream@ class is an alias of
-\verb@List@ which should be used to indicate the fact that its values
-are constructed lazily.
-
-\begin{figure}[thb]
-\begin{verbatim}
-class OOBinTree[kt extends Ord, vt] extends MapStruct[kt, vt] {
- abstract class Map extends kt => vt {
- def apply(key: kt): v
- def extend(key: kt, value: vt): Map
- def remove(key: kt): Map
- def domain: Stream[kt]
- def range: Stream[vt]
- }
- module empty extends Map {
- def apply(key: kt) = null
- def extend(key: kt, value: vt) = Node(key, value, empty, empty)
- def remove(key: kt) = empty
- def domain = []
- def range = []
- }
- private class Node(k: kt, v: vt, l: Map, r: Map) extends Map {
- def apply(key: kt): vt =
- if (key < k) l.apply(key)
- else if (key > k) r.apply(key)
- else v
- def extend(key: kt, value: vt): Map =
- if (key < k) Node(k, v, l.extend(key, value), r)
- else if (key > k) Node(k, v, l, r.extend(key, value))
- else Node(k, value, l, r)
- def remove(key: kt): Map =
- if (key < k) Node(k, v, l.remove(key), r)
- else if (key > k) Node(k, v, l, r.remove(key))
- else if (l == empty) r
- else if (r == empty) l
- else {
- val midKey = r.domain.head
- Node(midKey, r(midKey), l, r.remove(midKey))
- }
- def domain: Stream[kt] = Stream.concat([l.domain, [k], r.domain] )
- def range: Stream[vt] = Stream.concat([l.range, [v], r.range])
- }
-}
-\end{verbatim}
-\caption{\label{fig:oobintree}Object-oriented implementation of binary
-search trees}
-\end{figure}
-
-The second implementation of maps is given in
-Figure~\ref{fig:oobintree}. Class \verb@OOBinTree@ implements the
-type \verb@Map@ with a module \verb@empty@ and a class
-\verb@Node@, which define the behavior of empty and non-empty trees,
-respectively.
-
-Note the different nesting structure of \verb@AlgBinTree@ and
-\verb@OOBinTree@. In the former, all methods form part of the base
-class \verb@Map@. The different behavior of empty and non-empty trees
-is expressed using a pattern match on the tree itself. In the
-latter, each subclass of \verb@Map@ defines its own set of
-methods, which override the methods in the base class. The pattern
-matches of the algebraic implementation have been replaced by the
-dynamic binding that comes with method overriding.
-
-Which of the two schemes is preferable depends to a large degree on
-which extensions of the type are anticipated. If the type is later
-extended with a new alternative, it is best to keep methods in each
-alternative, the way it was done in \verb@OOBinTree@. On the other
-hand, if the type is extended with additional methods, then it is
-preferable to keep only one implementation of methods and to rely on
-pattern matching, since this way existing subclasses need not be
-modified.
-
-\begin{figure}
-\begin{verbatim}
-class MutBinTree[kt extends Ord, vt] extends MapStruct[kt, vt] {
- class Map(key: kt, value: vt) extends kt => vt {
- val k = key
- var v = value
- var l = empty, r = empty
-
- def apply(key: kt): vt =
- if (this eq empty) null
- else if (key < k) l.apply(key)
- else if (key > k) r.apply(key)
- else v
-
- def extend(key: kt, value: vt): Map =
- if (this eq empty) Map(key, value)
- else {
- if (key < k) l = l.extend(key, value)
- else if (key > k) r = r.extend(key, value)
- else v = value
- this
- }
-
- def remove(key: kt): Map =
- if (this eq empty) this
- else if (key < k) { l = l.remove(key) ; this }
- else if (key > k) { r = r.remove(key) ; this }
- else if (l eq empty) r
- else if (r eq empty) l
- else {
- var mid = r
- while (!(mid.l eq empty)) { mid = mid.l }
- mid.r = r.remove(mid.k)
- mid.l = l
- mid
- }
-
- def domain: Stream[kt] = Stream.concat([l.domain, [k], r.domain])
- def range: Stream[vt] = Stream.concat([l.range, [v], r.range])
- }
- let empty = new Map(null, null)
-}
-\end{verbatim}
-\caption{\label{fig:impbintree}Side-effecting implementation of binary
-search trees}
-\end{figure}
-
-The two versions of binary trees presented so far are {\em
-persistent}, in the sense that maps are values that cannot be changed
-by side effects. By contrast, in the next implementation of binary
-trees, the implementations of \verb@extend@ and
-\verb@remove@ do have an effect on the state of their receiver
-object. This corresponds to the way binary trees are usually
-implemented in imperative languages. The new implementation can lead
-to some savings in computing time and memory allocation, but care is
-required not to use the original tree after it has been modified by a
-side-effecting operation.
-
-In this implementation, \verb@value@, \verb@l@ and \verb@r@ are
-variables that can be affected by method calls. The
-class \verb@MutBinTree[kt, vt].Map@ takes two instance parameters
-which define the \verb@key@ value and the initial value of the
-\verb@value@ variable. Empty trees are represented by a
-value \verb@empty@, which has \verb@null@ (signifying undefined) in
-both its key and value fields. Note that this value needs to be
-defined lazily using \verb@let@ since its definition involves the
-creation of a
-\verb@Map@ object,
-which accesses \verb@empty@ recursively as part of its initialization.
-All methods test first whether the current tree is empty using the
-reference equality operator \verb@eq@ (\sref{sec:class-object}).
-
-As a program using the \verb@MapStruct@ abstraction, consider a function
-which creates a map from strings to integers and then applies it to a
-key string:
-\begin{verbatim}
-def mapTest(def mapImpl: MapStruct[String, int]): int = {
- val map: mapImpl.Map = mapImpl.empty.extend("ab", 1).extend("bx", 3)
- val x = map("ab") // returns 1
-}
-\end{verbatim}
-The function is parameterized with the particular implementation of
-\verb@MapStruct@. It can be applied to any one of the three implementations
-described above. E.g.:
-\begin{verbatim}
-mapTest(AlgBinTree[String, int])
-mapTest(OOBinTree[String, int])
-mapTest(MutBinTree[String, int])
-\end{verbatim}
-}
-\chapter{Programming with Higher-Order Functions: Combinator Parsing}
-
-In this chapter we describe how to write combinator parsers in
-Scala. Such parsers are constructed from predefined higher-order
-functions, so called parser combinators, that closely model the
-constructions of an EBNF grammar \cite{ebnf}.
-
-As running example, we consider parsers for arithmetic expressions
-described by the following context-free grammar.
-\bda{p{3cm}cp{10cm}}
-letter &::=& /* all letters */ \\
-digit &::=& /* all digits */ \\[0.5em]
-ident &::=& letter \{letter $|$ digit \}\\
-number &::=& digit \{digit\}\\[0.5em]
-
-expr &::=& expr1 \{`+' expr1 $|$ `$-$' expr1\}\\
-expr1 &::=& expr2 \{`*' expr2 $|$ `/' expr2\}\\
-expr2 &::=& ident $|$ number $|$ `(' expr `)'
-\eda
-
-\section{Simple Combinator Parsing}
-
-In this section we will only be concerned with the task of recognizing
-input strings, not with processing them. So we can describe parsers
-by the sets of input strings they accept. There are two
-fundamental operators over parsers:
-\verb@&&&@ expresses the sequential composition of a parser with
-another, while \verb@|||@ expresses an alternative. These operations
-will both be defined as methods of a \verb@Parser@ class. We will
-also define constructors for the following primitive parsers:
-
-\begin{quote}\begin{tabular}{ll}
-\verb@empty@ & The parser that accepts the empty string
-\\
-\verb@fail@ & The parser that accepts no string
-\\
-\verb@chr@ & The parser that accepts any character.
-\\
-\verb@chr(c: char)@
- & The parser that accepts the single-character string ``$c$''.
-\\
-\verb@chrWith(p: char => boolean)@
- & The parser that accepts single-character strings
- ``$c$'' \\
- & for which $p(c)$ is true.
-\end{tabular}\end{quote}
-
-There are also the two higher-order parser combinators \verb@opt@,
-expressing optionality and \verb@rep@, expressing repetition.
-For any parser $p$, \verb@opt($p$)@ yields a parser that
-accepts the strings accepted by $p$ or else the empty string, while
-\verb@rep($p$)@ accepts arbitrary sequences of the strings accepted by
-$p$. In EBNF, \verb@opt($p$)@ corresponds to $[p]$ and \verb@rep($p$)@
-corresponds to $\{p\}$.
-
-The central idea of parser combinators is that parsers can be produced
-by a straightforward rewrite of the grammar, replacing \verb@::=@ with
-\verb@=@, sequencing with
-\verb@&&&@, choice
-\verb@|@ with \verb@|||@, repetition \verb@{...}@ with
-\verb@rep(...)@ and optional occurrence with \verb@[...]@.
-Applying this process to the grammar of arithmetic
-expressions yields:
-\begin{verbatim}
-module ExprParser {
- import Parse;
-
- def letter \= = \= chrWith(c => c.isLetter);
- def digit \= = \> chrWith(c => c.isDigit);
-
- def ident \> = \> letter &&& rep(letter ||| digit);
- def number \> = \> digit &&& rep(digit);
-
- def expr:Parser\> = expr1 &&& rep((chr('+') &&& expr1) ||| (chr('-') &&& expr1));
- def expr1 \> = expr2 &&& rep((chr('*') &&& expr2) ||| (chr('/') &&& expr2));
- def expr2 \> = ident ||| number ||| (chr('(') &&& expr &&& chr(')'));
-}
-\end{verbatim}
-It remains to explain how to implement a library with the combinators
-described above. We will pack combinators and their underlying
-implementation in a module \verb@Parse@. The first question to decide
-is which underlying representation type to use for a parser. We treat
-parsers here as functions that take a list of characters as input
-parameter and that yield a parse result.
-\begin{verbatim}
-module Parse {
-
- type Result = Option[List[char]];
-
- abstract class Parser extends Function1[List[char],Result] {
-\end{verbatim}
-\comment{
-The \verb@Option@ type is predefined as follows.
-\begin{verbatim}
-abstract final class Option[a];
-case class None[a] extends Option[a];
-case class Some[a](x: a) extends Option[a];
-\end{verbatim}
-}
-A parser returns either the constant \verb@None@, which
-signifies that the parser did not recognize a legal input string, or
-it returns a value \verb@Some(in1)@ where \verb@in1@ represents that
-part of the input list that the parser did not consume.
-
-Parsers are instances of functions from \verb@List[char]@ to
-\verb@Parse.Result@, which also implement the combinators
-for sequence and alternative. This is modeled by
-defining \verb@Parser@ as a class that extends type
-\verb@Function1[List[char],Result]@ and that defines an \verb@apply@
-method, as well as methods \verb@&&&@ and \verb@|||@.
-\begin{verbatim}
- abstract def apply(in: List[char]): Result;
-\end{verbatim}
-\begin{verbatim}
- def &&& (def p: Parser) = new Parser {
- def apply(in: List[char]) = outer.apply(in) match {
- case Some(in1) => p(in1)
- case n => n
- }
- }
-
- def ||| (def p: Parser) = new Parser {
- def apply(in: List[char]) = outer.apply(in) match {
- case None => p(in)
- case s => s
- }
- }
- }
-\end{verbatim}
-The implementations of the primitive parsers \verb@empty@, \verb@fail@,
-\verb@chrWith@ and \verb@chr@ are as follows.
-\begin{verbatim}
-
- def empty = new Parser { def apply(in: List[char]) = Some(in) }
-
- def fail = new Parser { def apply(in: List[char]) = None[List[char]] }
-
- def chrWith(p: char => boolean) = new Parser {
- def apply(in: List[char]) = in match {
- case [] => None[List[char]]
- case (c :: in1) => if (p(c)) Some(in1) else None[List[char]]
- }
- }
-
- def chr(c: char): Parser = chrWith(d => d == c);
-\end{verbatim}
-The higher-order parser combinators \verb@opt@ and \verb@rep@ can be
-defined in terms of the combinators for sequence and alternative:
-\begin{verbatim}
- def opt(p: Parser): Parser = p ||| empty;
- def rep(p: Parser): Parser = opt(rep1(p));
- def rep1(p: Parser): Parser = p &&& rep(p);
-} // end Parser
-\end{verbatim}
-This is all that's needed. Parsers such as the one for arithmetic
-expressions given above can now be composed from these building
-blocks. These parsers need not refer to the underlying implementation of
-parsers as functions from input lists to parse results.
-
-The presented combinator parsers use backtracking to change from one
-alternative to another. If one restricts the focus to LL(1) grammars,
-a non-backtracking implementation of parsers is also possible. This
-implementation can then be based on iterators instead of lists.
-
-\section{\label{sec:parsers-results}Parsers that Return Results}
-
-The combinator library of the previous section does not support the
-generation of output from parsing. But usually one does not just want
-to check whether a given string belongs to the defined language, one
-also wants to convert the input string into some internal
-representation such as an abstract syntax tree.
-
-In this section, we modify our parser library to build parsers that
-produce results. We will make use of the for-comprehensions introduced
-in Chapter~\ref{sec:for-notation}. The basic combinator of sequential
-composition, formerly \verb@p &&& q@, now becomes
-\begin{verbatim}
-for (val x <- p; val y <- q) yield e
-\end{verbatim}.
-Here, the names \verb@x@ and \verb@y@ are bound to the results of
-executing the parsers \verb@p@ and \verb@q@. \verb@e@ is an expression
-that uses these results to build the tree returned by the composed
-parser.
-
-Before describing the implementation of the new parser combinators, we
-explain how the new building blocks are used. Say we want to modify
-our arithmetic expression parser so that it returns an abstract syntax
-tree of the parsed expression. The class of syntax trees is given by:
-\begin{verbatim}
-abstract class Tree;
-case class Var(n: String) extends Tree;
-case class Num(n: int) extends Tree;
-case class Binop(op: char, l: Tree, r: Tree) extends Tree;
-\end{verbatim}
-That is, a syntax tree is a named variable, an integer number, or a
-binary operation with two operand trees and a character indicating the
-operation.
-
-As a first step towards parsers that produce syntax trees, we need to
-modify the ``micro-syntax'' parsers \verb@letter@, \verb@digit@,
-\verb@ident@ and \verb@number@ so that they return representations of
-the parsed input:
-\begin{verbatim}
-def letter: Parser[char] = chrWith(c => c.isLetter);
-def digit : Parser[char] = chrWith(c => c.isDigit);
-
-def ident: Parser[String] =
- for (val c <- letter; val cs <- rep(letter ||| digit))
- yield ((c :: cs) foldr "") {c, s => c+ s};
-
-def number: Parser[int] =
- for (val d <- digit; val ds <- rep(digit))
- yield ((d - '0') :_foldl ds) {x, y => x * 10 + (y - '0')};
-\end{verbatim}
-The \verb@letter@ and \verb@digit@ parsers simply return the letter
-that was parsed. The \verb@ident@ and \verb@number@ parsers return the
-string, respectively integer number that was parsed. In both cases,
-sub-parsers are applied in a for-comprehension and their results are
-embedded in the result of the calling parser. The remainder of the
-parser for arithmetic expressions follows the same scheme.
-\begin{verbatim}
-def expr: Parser[Tree] =
- for {
- val e1 <- expr1;
- val es <- rep (
- for {
- val op <- chr('+') ||| chr('-');
- val e <- expr1
- } yield (x => Binop(op, x, e)) : Tree => Tree
- )
- } yield applyAll(es, e1);
-\end{verbatim}
-\begin{verbatim}
-def expr1: Parser[Tree] =
- for {
- val e1 <- expr2;
- val es <- rep (
- for {
- val op <- chr('*') ||| chr('/');
- val e <- expr2
- } yield (x => Binop(op, x, e)) : Tree => Tree
- )
- } yield applyAll(es, e1);
-\end{verbatim}
-\begin{verbatim}
-def expr2: Parser[Tree] = {
- \= ( for { val n <- ident } yield Var(n) : Tree )
- |||\> ( for { val n <- number } yield Num(n) : Tree )
- |||\> ( for { val _ <- chr('('); val e <- expr; val _ <- chr(')') } yield e );
-}
-\end{verbatim}
-Note the treatment of the repetitions in \verb@expr@ and
-\verb@expr1@. The parser for an expression suffix $op;e$ consisting of an
-operator $op$ and an expression $e$ returns a function, which, given a
-left operand expression $d$, constructs a \verb@Binop@ node that
-represents $d;op;e$. The \verb@rep@ parser combinator forms a list of
-all these functions. The final \verb@yield@ part applies all functions
-to the first operand in the sequence, which is represented by
-\verb@e1@. Here \verb@applyAll@ applies the list of functions passed as its first
-argument to its second argument. It is defined as follows.
-\begin{verbatim}
-def applyAll[a](fs: List[a => a], e: a): a =
- (e :_foldl fs) { x, f => f(x) }
-\end{verbatim}
-We now present the parser combinators that support the new
-scheme. Parsers that succeed now return a parse result besides the
-un-consumed input.
-\begin{verbatim}
-module Parse {
-
- type Result[a] = Option[(a, List[char])]
-\end{verbatim}
-Parsers are parameterized with the type of their result. The class
-\verb@Parser[a]@ now defines new methods \verb@map@, \verb@flatMap@
-and \verb@filter@. The \verb@for@ expressions are mapped by the
-compiler to calls of these functions using the scheme described in
-Chapter~\ref{sec:for-notation}.
-
-Here is the complete definition of the new \verb@Parser@ class.
-\begin{verbatim}
- abstract class Parser[a] extends Function1[List[char],Result[a]] {
-
- def apply(in: List[char]): Result[a];
-
- def filter(p: a => boolean) = new Parser[a] {
- def apply(in: List[char]): Result[a] = outer.apply(in) match {
- case Some((x, in1)) => if (p(x)) Some((x, in1)) else None
- case None => None
- }
- }
-
- def map[b](f: a => b) = new Parser[b] {
- def apply(in: List[char]): Result[b] = outer.apply(in) match {
- case Some((x, in1)) => Some((f(x), in1))
- case None => None
- }
- }
-
- def flatMap[b](f: a => Parser[b]) = new Parser[b] {
- def apply(in: List[char]): Result[b] = outer.apply(in) match {
- case Some((x, in1)) => f(x)(in1)
- case None => None
- }
- }
-
- def ||| (def p: Parser[a]) = new Parser[a] {
- def apply(in: List[char]): Result[a] = outer.apply(in) match {
- case None => p(in)
- case s => s
- }
- }
-
- def &&& [b](def p: Parser[b]): Parser[b] =
- for (val _ <- this; val result <- p) yield result;
- }
-\end{verbatim}
-
-The \verb@filter@ method takes as parameter a predicate $p$ which it
-applies to the results of the current parser. If the predicate is
-false, the parser fails by returning \verb@None@; otherwise it returns
-the result of the current parser. The \verb@map@ method takes as
-parameter a function $f$ which it applies to the results of the
-current parser. The \verb@flatMap@ tales as parameter a function
-\verb@f@ which returns a parser. It applies \verb@f@ to the result of
-the current parser and then continues with the resulting parser. The
-\verb@|||@ method is essentially defined as before. The
-\verb@&&&@ method can now be defined in terms of \verb@for@.
-
-% Here is the code for fail, chrWith and chr
-%
-%\begin{verbatim}
-% def fail[a] = new Parser[a] { def apply(in: List[char]) = None[(a,List[char])] }
-%
-% def chrWith(p: char => boolean) = new Parser[char] {
-% def apply(in: List[char]) = in match {
-% case [] => None[(char,List[char])]
-% case (c :: in1) => if (p(c)) Some((c,in1)) else None[(char,List[char])]
-% }
-% }
-%
-% def chr(c: char): Parser[char] = chrWith(d => d == c);
-%\end{verbatim}
-The primitive parser \verb@succeed@ replaces \verb@empty@. It consumes
-no input and returns its parameter as result.
-\begin{verbatim}
- def succeed[a](x: a) = new Parser[a] {
- def apply(in: List[char]) = Some((x, in))
- }
-\end{verbatim}
-The \verb@fail@ parser is as before. The parser combinators
-\verb@rep@ and \verb@opt@ now also return results. \verb@rep@ returns
-a list which contains as elements the results of each iteration of its
-sub-parser. \verb@opt@ returns an
-\verb@Option@ type which indicates whether something was recognized by
-its sub-parser.
-\begin{verbatim}
- def rep[a](p: Parser[a]): Parser[List[a]] =
- rep1(p) ||| succeed([]);
-
- def rep1[a](p: Parser[a]): Parser[List[a]] =
- for (val x <- p; val xs <- rep(p)) yield x :: xs;
-
- def opt[a](p: Parser[a]): Parser[Option [a]] =
- { for (val x <- p) yield (Some(x): Option[a]) } ||| succeed((None: Option[a]));
-} // end Parse
-\end{verbatim}
-
-\chapter{\label{sec:hm}Programming with Patterns: Hindley/Milner Type Inference}
-
-This chapter demonstrates Scala's data types and pattern matching by
-developing a type inference system in the Hindley/Milner style. The
-source language for the type inferencer is lambda calculus with a let
-construct. Abstract syntax trees for the source language are
-represented by the following data type of \verb@Terms@.
-\begin{verbatim}
-abstract class Term;
-case class Var(x: String) extends Term;
-case class Lam(x: String, e: Term) extends Term;
-case class App(f: Term, e: Term) extends Term;
-case class Let(x: String, e: Term, f: Term) extends Term;
-\end{verbatim}
-There are four tree constructors: \verb@Var@ for variables, \verb@Lam@
-for function abstractions, \verb@App@ for function applications, and
-\verb@Let@ for let expressions. Note that these tree constructors are
-defined outside the \verb@Term@ class. It would also be possible
-to define further constructors for this type in other parts of the
-program.
-
-The next data type describes the form of types that are
-computed by the inference system.
-\begin{verbatim}
-module Types {
- abstract final class Type;
- case class Tyvar(a: String) extends Type;
- case class Arrow(t1: Type, t2: Type) extends Type;
- case class Tycon(k: String, ts: List[Type]) extends Type;
- private var n: int = 0;
- def newTyvar: Type = { n = n + 1 ; Tyvar("a" + n) }
-}
-import Types;
-\end{verbatim}
-There are three type constructors: \verb@Tyvar@ for type variables,
-\verb@Arrow@ for function types and \verb@Tycon@ for type
-constructors such as \verb@boolean@ or \verb@List@. Type constructors
-have as component a list of their type parameters. This list is empty
-for type constants such as \verb@boolean@. The data type is packaged
-in a module \verb@Types@. Also contained in that module is a function
-\verb@newTyvar@ which creates a fresh type variable each time it is
-called. The module definition is followed by an import clause
-\verb@import Types@, which makes the non-private members of
-this module available without qualification in the code that follows.
-
-Note that \verb@Type@ is a \verb@final@ class. This means that no
-subclasses or data constructors that extend \verb@Type@ can be formed
-except for the three constructors that follow the class. This makes
-\verb@Type@ into a {\em closed} algebraic data type with a fixed
-number of alternatives. By contrast, type \verb@Term@ is an {\em open}
-algebraic type for which further alternatives can be defined.
-
-The next data type describes type schemes, which consist of a type and
-a list of names of type variables which appear universally quantified
-in the type scheme. For instance, the type scheme $\forall a\forall
-b.a \arrow b$ would be represented in the type checker as:
-\begin{verbatim}
-TypeScheme(["a", "b"], Arrow(Tyvar("a"), Tyvar("b"))) .
-\end{verbatim}
-The data type definition of type schemes does not carry an extends
-clause; this means that type schemes extend directly class
-\verb@Object@.
-Even though there is only one possible way to construct a type scheme,
-a \verb@case class@ representation was chosen since it offers a convenient
-way to decompose a type scheme into its parts using pattern matching.
-\begin{verbatim}
-case class TypeScheme(ls: List[String], t: Type) {
- def newInstance: Type = {
- val instSubst =
- ((EmptySubst: Subst) :_foldl ls) { s, a => s.extend(Tyvar(a), newTyvar) }
- instSubst(t)
- }
-}
-\end{verbatim}
-Type scheme objects come with a method \verb@newInstance@, which
-returns the type contained in the scheme after all universally type
-variables have been renamed to fresh variables.
-
-The next class describes substitutions. A substitution is an
-idempotent function from type variables to types. It maps a finite
-number of given type variables to given types, and leaves all other
-type variables unchanged. The meaning of a substitution is extended
-point-wise to a mapping from types to types.
-
-\begin{verbatim}
-abstract class Subst extends Function1[Type,Type] {
- def lookup(x: Tyvar): Type;
- def apply(t: Type): Type = t match {
- case Tyvar(a) => val u = lookup(Tyvar(a)); if (t == u) t else apply(u);
- case Arrow(t1, t2) => Arrow(apply(t1), apply(t2))
- case Tycon(k, ts) => Tycon(k, ts map apply)
- }
- def extend(x: Tyvar, t: Type) = new Subst {
- def lookup(y: Tyvar): Type = if (x == y) t else outer.lookup(y);
- }
-}
-case class EmptySubst extends Subst { def lookup(t: Tyvar): Type = t }
-\end{verbatim}
-We represent substitutions as functions, of type
-\verb@Type => Type@. To be an instance of this type, a
-substitution \verb@s@ has to implement an \verb@apply@ method that takes a
-\verb@Type@ as argument and yields another \verb@Type@ as result. A function
-application \verb@s(t)@ is then interpreted as \verb@s.apply(t)@.
-
-The \verb@lookup@ method is abstract in class \verb@Subst@. Concrete
-substitutions are defined by the case class \verb@EmptySubst@ and the
-method \verb@extend@ in class \verb@Subst@.
-
-The next class gives a naive implementation of sets using lists as the
-implementation type. It implements methods \verb@contains@ for
-membership tests as well as \verb@union@ and \verb@diff@ for set union
-and difference. Alternatively, one could have used a more efficient
-implementation of sets in some standard library.
-\begin{verbatim}
-class ListSet[a](xs: List[a]) {
- val elems: List[a] = xs;
-
- def contains(y: a): boolean = xs match {
- case [] => false
- case x :: xs1 => (x == y) || (xs1 contains y)
- }
-
- def union(ys: ListSet[a]): ListSet[a] = xs match {
- case [] => ys
- case x :: xs1 =>
- if (ys contains x) ListSet(xs1) union ys
- else ListSet(x :: (ListSet(xs1) union ys).elems)
- }
-
- def diff(ys: ListSet[a]): ListSet[a] = xs match {
- case [] => ListSet([])
- case x :: xs1 =>
- if (ys contains x) ListSet(xs1) diff ys
- else ListSet(x :: (ListSet(xs1) diff ys).elems)
- }
-}
-\end{verbatim}
-
-We now present the type checker module. The type checker
-computes a type for a given term in a given environment. Environments
-associate variable names with type schemes. They are represented by a
-type alias \verb@Env@ in module \verb@TypeChecker@:
-\begin{verbatim}
-module TypeChecker {
-
- /** Type environments are lists of bindings that associate a
- * name with a type scheme.
- */
- type Env = List[(String, TypeScheme)];
-\end{verbatim}
-There is also an exception \verb@TypeError@, which is thrown when type
-checking fails. Exceptions are modeled as case classes that inherit
-from the predefined \verb@Exception@ class.
-\begin{verbatim}
- case class TypeError(msg: String) extends Exception(msg);
-\end{verbatim}
-The \verb@Exception@ class defines a \verb@throw@ method which causes
-the exception to be thrown.
-
-The \verb@TypeChecker@ module contains several utility
-functions. Function
-\verb@tyvars@ yields the set of free type variables of a type,
-of a type scheme, of a list of types, or of an environment. Its
-implementation is as four overloaded functions, one for each type of
-argument.
-\begin{verbatim}
- def tyvars(t: Type): ListSet[String] = t match {
- case Tyvar(a) => new ListSet([a])
- case Arrow(t1, t2) => tyvars(t1) union tyvars(t2)
- case Tycon(k, ts) => tyvars(ts)
- }
- def tyvars(ts: TypeScheme): ListSet[String] = ts match {
- case TypeScheme(as, t) => tyvars(t) diff new ListSet(as)
- }
- def tyvars(ts: List[Type]): ListSet[String] = ts match {
- case [] => new ListSet[String]([])
- case t :: ts1 => tyvars(t) union tyvars(ts1)
- }
- def tyvars(env: Env): ListSet[String] = env match {
- case [] => new ListSet[String]([])
- case (x, t) :: env1 => tyvars(t) union tyvars(env1)
- }
-\end{verbatim}
-The next utility function, \verb@lookup@, returns the type scheme
-associated with a given variable name in the given environment, or
-returns \verb@null@ if no binding for the variable exists in the environment.
-\begin{verbatim}
- def lookup(env: Env, x: String): TypeScheme = env match {
- case [] => null
- case (y, t) :: env1 => if (x == y) t else lookup(env1, x)
- }
-\end{verbatim}
-The next utility function, \verb@gen@, returns the type scheme that
-results from generalizing a given type in a given environment. This
-means that all type variables that occur in the type but not in the
-environment are universally quantified.
-\begin{verbatim}
- def gen(env: Env, t: Type): TypeScheme =
- TypeScheme((tyvars(t) diff tyvars(env)).elems, t);
-\end{verbatim}
-The next utility function, \verb@mgu@, computes the most general
-unifier of two given types $t$ and $u$ under a pre-existing
-substitution $s$. That is, it returns the most general
-substitution $s'$ which extends $s$, and which makes $s'(t)$ and
-$s'(u)$ equal types. The function throws a \verb@TypeError@ exception
-if no such substitution exists. This can happen because the two types
-have different type constructors at corresponding places, or because
-a type variable is unified with a type that contains the type variable
-itself.
-\begin{verbatim}
- def mgu(t: Type, u: Type)(s: Subst): Subst = (s(t), s(u)) match {
- case (Tyvar( a), Tyvar(b)) if a == b =>
- s
- case (Tyvar(a), _) =>
- if (tyvars(u) contains a)
- TypeError("unification failure: occurs check").throw
- else s.extend(Tyvar(a), u)
- case (_, Tyvar(a)) =>
- mgu(u, t)(s)
- case (Arrow(t1, t2), Arrow(u1, u2)) =>
- mgu(t1, u1)(mgu(t2, u2)(s))
- case (Tycon(k1, ts), Tycon(k2, us)) if k1 == k2 =>
- (s :_foldl ((ts zip us) map (case (t,u) => mgu(t,u)))) { s, f => f(s) }
- case _ => TypeError("unification failure").throw
- }
-\end{verbatim}
-The main task of the type checker is implemented by function
-\verb@tp@. This function takes as first parameters an environment $env$, a
-term $e$ and a proto-type $t$. As a second parameter it takes a
-pre-existing substitution $s$. The function yields a substitution
-$s'$ that extends $s$ and that
-turns $s'(env) \ts e: s'(t)$ into a derivable type judgment according
-to the derivation rules of the Hindley/Milner type system \cite{hindley-milner}. A
-\verb@TypeError@ exception is thrown if no such substitution exists.
-\begin{verbatim}
- def tp(env: Env, e: Term, t: Type)(s: Subst): Subst = e match {
- case Var(x) => {
- val u = lookup(env, x);
- if (u == null) TypeError("undefined: x").throw
- else mgu(u.newInstance, t)(s)
- }
- case Lam(x, e1) => {
- val a = newTyvar, b = newTyvar;
- val s1 = mgu(t, Arrow(a, b))(s);
- val env1 = (x, TypeScheme([], a)) :: env;
- tp(env1, e1, b)(s1)
- }
- case App(e1, e2) => {
- val a = newTyvar;
- val s1 = tp(env, e1, Arrow(a, t))(s);
- tp(env, e2, a)(s1)
- }
- case Let(x, e1, e2) => {
- val a = newTyvar;
- val s1 = tp(env, e1, a)(s);
- tp((x, gen(env, s1(a))) :: env, e2, t)(s1)
- }
- }
-\end{verbatim}
-The next function, \verb@typeOf@ is a simplified facade for
-\verb@tp@. It computes the type of a given term $e$ in a given
-environment $env$. It does so by creating a fresh type variable \verb$a$,
-computing a typing substitution that makes \verb@env $\ts$ e: a@ into
-a derivable type judgment, and finally by returning the result of
-applying the substitution to $a$.
-\begin{verbatim}
- def typeOf(env: Env, e: Term): Type = {
- val a = newTyvar;
- tp(env, e, a)(EmptySubst)(a)
- }
-}
-\end{verbatim}
-This concludes the presentation of the type inference system.
-To apply the system, it is convenient to have a predefined environment
-that contains bindings for commonly used constants. The module
-\verb@Predefined@ defines an environment \verb@env@ that contains
-bindings for booleans, numbers and lists together with some primitive
-operations over these types. It also defines a fixed point operator
-\verb@fix@, which can be used to represent recursion.
-\begin{verbatim}
-module Predefined {
- val booleanType = Tycon("Boolean", []);
- val intType = Tycon("Int", []);
- def listType(t: Type) = Tycon("List", [t]);
-
- private def gen(t: Type): TypeScheme = TypeChecker.gen([], t);
- private val a = newTyvar;
- val env = [
- ("true", gen(booleanType)),
- ("false", gen(booleanType)),
- ("$\mbox{\prog{if}}$", gen(Arrow(booleanType, Arrow(a, Arrow(a, a))))),
- ("zero", gen(intType)),
- ("succ", gen(Arrow(intType, intType))),
- ("$\mbox{\prog{nil}}$", gen(listType(a))),
- ("cons", gen(Arrow(a, Arrow(listType(a), listType(a))))),
- ("isEmpty", gen(Arrow(listType(a), booleanType))),
- ("head", gen(Arrow(listType(a), a))),
- ("tail", gen(Arrow(listType(a), listType(a)))),
- ("fix", gen(Arrow(Arrow(a, a), a)))
- ];
-}
-\end{verbatim}
-Here's an example how the type inferencer is used.
-Let's define a function \verb@showType@ which returns the type of
-a given term computed in the predefined environment
-\verb@Predefined.env@:
-\begin{verbatim}
-> def showType(e: Term) = TypeChecker.typeOf(Predefined.env, e);
-\end{verbatim}
-Then the application
-\begin{verbatim}
-> showType(Lam("x", App(App(Var("cons"), Var("x")), Var("$\mbox{\prog{nil}}$"))));
-\end{verbatim}
-would give the response
-\begin{verbatim}
-> TypeScheme([a0], Arrow(Tyvar(a0), Tycon("List", [Tyvar(a0)])));
-\end{verbatim}
-
-\exercise
-Add \verb@toString@ methods to the data constructors of class
-\verb@Type@ and \verb@TypeScheme@ which represent types in a more
-natural way.
-
-\chapter{Abstractions for Concurrency}\label{sec:ex-concurrency}
-
-This section reviews common concurrent programming patterns and shows
-how they can be implemented in Scala.
-
-\section{Signals and Monitors}
-
-\example
-The {\em monitor} provides the basic means for mutual exclusion
-of processes in Scala. It is defined as follows.
-\begin{verbatim}
-class Monitor {
- def synchronized [a] (def e: a): a;
-}
-\end{verbatim}
-The \verb@synchronized@ method in class \verb@Monitor@ executes its
-argument computation \verb@e@ in mutual exclusive mode -- at any one
-time, only one thread can execute a \verb@synchronized@ argument of a
-given monitor.
-
-Threads can suspend inside a monitor by waiting on a signal. The
-\verb@Signal@ class offers two methods \verb@send@ and
-\verb@wait@. Threads that call the \verb@wait@ method wait until a
-\verb@send@ method of the same signal is called subsequently by some
-other thread. Calls to \verb@send@ with no threads waiting for the
-signal are ignored. Here is the specification of the \verb@Signal@
-class.
-\begin{verbatim}
-class Signal {
- def wait: unit;
- def wait(msec: long): unit;
- def notify: unit;
- def notifyAll: unit;
-}
-\end{verbatim}
-A signal also implements a timed form of \verb@wait@, which blocks
-only as long as no signal was received or the specified amount of time
-(given in milliseconds) has elapsed. Furthermore, there is a
-\verb@notifyAll@ method which unblocks all threads which wait for the
-signal. \verb@Signal@ and \verb@Monitor@ are primitive classes in
-Scala which are implemented in terms of the underlying runtime system.
-
-As an example of how monitors and signals are used, here is is an
-implementation of a bounded buffer class.
-\begin{verbatim}
-class BoundedBuffer[a](N: int) extends Monitor {
- var in = 0, out = 0, n = 0;
- val elems = new Array[a](N);
- val nonEmpty = new Signal;
- val nonFull = new Signal;
-\end{verbatim}
-\begin{verbatim}
- def put(x: a) = synchronized {
- if (n == N) nonFull.wait;
- elems(in) = x ; in = (in + 1) % N ; n = n + 1;
- if (n == 1) nonEmpty.send;
- }
-\end{verbatim}
-\begin{verbatim}
- def get: a = synchronized {
- if (n == 0) nonEmpty.wait
- val x = elems(out) ; out = (out + 1) % N ; n = n - 1;
- if (n == N - 1) nonFull.send;
- x
- }
-}
-\end{verbatim}
-And here is a program using a bounded buffer to communicate between a
-producer and a consumer process.
-\begin{verbatim}
-val buf = new BoundedBuffer[String](10)
-fork { while (true) { val s = produceString ; buf.put(s) } }
-fork { while (true) { val s = buf.get ; consumeString(s) } }
-\end{verbatim}
-The \verb@fork@ method spawns a new thread which executes the
-expression given in the parameter. It can be defined as follows.
-\begin{verbatim}
-def fork(def e: unit) = {
- val p = new Thread { def run = e; }
- p.run
-}
-\end{verbatim}
-
-\comment{
-\section{Logic Variable}
-
-A logic variable (or lvar for short) offers operations \verb@:=@
-and \verb@value@ to define the variable and to retrieve its value.
-Variables can be \verb@define@d only once. A call to \verb@value@
-blocks until the variable has been defined.
-
-Logic variables can be implemented as follows.
-
-\begin{verbatim}
-class LVar[a] extends Monitor {
- private val defined = new Signal
- private var isDefined: boolean = false
- private var v: a
- def value = synchronized {
- if (!isDefined) defined.wait
- v
- }
- def :=(x: a) = synchronized {
- v = x ; isDefined = true ; defined.send
- }
-}
-\end{verbatim}
-}
-
-\section{SyncVars}
-
-A synchronized variable (or syncvar for short) offers \verb@get@ and
-\verb@put@ operations to read and set the variable. \verb@get@ operations
-block until the variable has been defined. An \verb@unset@ operation
-resets the variable to undefined state.
-
-Synchronized variables can be implemented as follows.
-\begin{verbatim}
-class SyncVar[a] extends Monitor {
- private val defined = new Signal;
- private var isDefined: boolean = false;
- private var value: a;
- def get = synchronized {
- if (!isDefined) defined.wait;
- value
- }
- def set(x: a) = synchronized {
- value = x ; isDefined = true ; defined.send;
- }
- def isSet: boolean =
- isDefined;
- def unset = synchronized {
- isDefined = false;
- }
-}
-\end{verbatim}
-
-\section{Futures}
-\label{sec:futures}
-
-A {\em future} is a value which is computed in parallel to some other
-client thread, to be used by the client thread at some future time.
-Futures are used in order to make good use of parallel processing
-resources. A typical usage is:
-
-\begin{verbatim}
-val x = future(someLengthyComputation);
-anotherLengthyComputation;
-val y = f(x()) + g(x());
-\end{verbatim}
-
-Futures can be implemented in Scala as follows.
-
-\begin{verbatim}
-def future[a](def p: a): unit => a = {
- val result = new SyncVar[a];
- fork { result.set(p) }
- (=> result.get)
-}
-\end{verbatim}
-
-The \verb@future@ method gets as parameter a computation \verb@p@ to
-be performed. The type of the computation is arbitrary; it is
-represented by \verb@future@'s type parameter \verb@a@. The
-\verb@future@ method defines a guard \verb@result@, which takes a
-parameter representing the result of the computation. It then forks
-off a new thread that computes the result and invokes the
-\verb@result@ guard when it is finished. In parallel to this thread,
-the function returns an anonymous function of type \verb@a@.
-When called, this functions waits on the result guard to be
-invoked, and, once this happens returns the result argument.
-At the same time, the function reinvokes the \verb@result@ guard with
-the same argument, so that future invocations of the function can
-return the result immediately.
-
-\section{Parallel Computations}
-
-The next example presents a function \verb@par@ which takes a pair of
-computations as parameters and which returns the results of the computations
-in another pair. The two computations are performed in parallel.
-
-\begin{verbatim}
-def par[a, b](def xp: a, def yp: b): (a, b) = {
- val y = new SyncVar[a];
- fork { y.set(yp) }
- (xp, y)
-}
-\end{verbatim}
-
-The next example presents a function \verb@replicate@ which performs a
-number of replicates of a computation in parallel. Each
-replication instance is passed an integer number which identifies it.
-
-\begin{verbatim}
-def replicate(start: int, end: int)(def p: int => unit): unit = {
- if (start == end) {
- } else if (start + 1 == end) {
- p(start)
- } else {
- val mid = (start + end) / 2;
- par ( replicate(start, mid)(p), replicate(mid, end)(p) )
- }
-}
-\end{verbatim}
-
-The next example shows how to use \verb@replicate@ to perform parallel
-computations on all elements of an array.
-
-\begin{verbatim}
-def parMap[a,b](f: a => b, xs: Array[a]): Array[b] = {
- val results = new Array[b](xs.length);
- replicate(0, xs.length) { i => results(i) = f(xs(i)) }
- results
-}
-\end{verbatim}
-
-\section{Semaphores}
-
-A common mechanism for process synchronization is a {\em lock} (or:
-{\em semaphore}). A lock offers two atomic actions: \prog{acquire} and
-\prog{release}. Here's the implementation of a lock in Scala:
-
-\begin{verbatim}
-class Lock extends Monitor with Signal {
- var available = true;
- def acquire = {
- if (!available) wait;
- available = false
- }
- def release = {
- available = true;
- notify
- }
-}
-\end{verbatim}
-
-\section{Readers/Writers}
-
-A more complex form of synchronization distinguishes between {\em
-readers} which access a common resource without modifying it and {\em
-writers} which can both access and modify it. To synchronize readers
-and writers we need to implement operations \prog{startRead}, \prog{startWrite},
-\prog{endRead}, \prog{endWrite}, such that:
-\begin{itemize}
-\item there can be multiple concurrent readers,
-\item there can only be one writer at one time,
-\item pending write requests have priority over pending read requests,
-but don't preempt ongoing read operations.
-\end{itemize}
-The following implementation of a readers/writers lock is based on the
-{\em message space} concept (see Section~\ref{sec:messagespace}).
-
-\begin{verbatim}
-class ReadersWriters {
- val m = new MessageSpace;
- private case class Writers(n: int), Readers(n: int);
- Writers(0); Readers(0);
- def startRead = m receive {
- case Writers(n) if n == 0 => m receive {
- case Readers(n) => Writers(0) ; Readers(n+1);
- }
- }
- def startWrite = m receive {
- case Writers(n) =>
- Writers(n+1);
- m receive { case Readers(n) if n == 0 => }
- }
-\end{verbatim}
-\begin{verbatim}
- def endRead = receive {
- case Readers(n) => Readers(n-1)
- }
- def endWrite = receive {
- case Writers(n) => Writers(n-1) ; if (n == 0) Readers(0)
- }
-}
-\end{verbatim}
-
-\section{Asynchronous Channels}
-
-A fundamental way of interprocess communication is the asynchronous
-channel. Its implementation makes use the following class for linked
-lists:
-\begin{verbatim}
-class LinkedList[a](x: a) {
- val elem: a = x;
- var next: LinkedList[a] = null;
-}
-\end{verbatim}
-To facilitate insertion and deletion of elements into linked lists,
-every reference into a linked list points to the node which precedes
-the node which conceptually forms the top of the list.
-Empty linked lists start with a dummy node, whose successor is \verb@null@.
-
-The channel class uses a linked list to store data that has been sent
-but not read yet. In the opposite direction, a signal \verb@moreData@ is
-used to wake up reader threads that wait for data.
-\begin{verbatim}
-class Channel[a] {
- private val written = new LinkedList[a](null);
- private var lastWritten = written;
- private val moreData = new Signal;
-
- def write(x: a) = {
- lastWritten.next = new LinkedList(x);
- lastWritten = lastWritten.next;
- moreData.notify;
- }
-
- def read: a = {
- if (written.next == null) moreData.wait;
- written = written.next;
- written.elem;
- }
-}
-\end{verbatim}
-
-\section{Synchronous Channels}
-
-Here's an implementation of synchronous channels, where the sender of
-a message blocks until that message has been received. Synchronous
-channels only need a single variable to store messages in transit, but
-three signals are used to coordinate reader and writer processes.
-\begin{verbatim}
-class SyncChannel[a] {
- val data = new SyncVar[a];
-
- def write(x: a): unit = synchronized {
- val empty = new Signal, full = new Signal, idle = new Signal;
- if (data.isSet) idle.wait;
- data.put(x);
- full.send;
- empty.wait;
- data.unset;
- idle.send;
- }
-
- def read: a = synchronized {
- if (!(data.isSet)) full.wait;
- x = data.get;
- empty.send;
- x
- }
-}
-\end{verbatim}
-
-\section{Workers}
-
-Here's an implementation of a {\em compute server} in Scala. The
-server implements a \verb@future@ method which evaluates a given
-expression in parallel with its caller. Unlike the implementation in
-Section~\ref{sec:futures} the server computes futures only with a
-predefined number of threads. A possible implementation of the server
-could run each thread on a separate processor, and could hence avoid
-the overhead inherent in context-switching several threads on a single
-processor.
-
-\begin{verbatim}
-class ComputeServer(n: int) {
- private abstract class Job {
- abstract type t;
- def task: t;
- def return(x: t): unit;
- }
-
- private val openJobs = new Channel[Job]
-
- private def processor: unit = {
- while (true) {
- val job = openJobs.read;
- job.return(job.task)
- }
- }
-\end{verbatim}
-\begin{verbatim}
- def future[a](def p: a): () => a = {
- val reply = new SyncVar[a];
- openJobs.write(
- new Job {
- type t = a;
- def task = p;
- def return(x: a) = reply.set(x);
- }
- )
- (=> reply.get)
- }
-
- replicate(n){processor};
-}
-\end{verbatim}
-
-Expressions to be computed (i.e. arguments
-to calls of \verb@future@) are written to the \verb@openJobs@
-channel. A {\em job} is an object with
-\begin{itemize}
-\item
-An abstract type \verb@t@ which describes the result of the compute
-job.
-\item
-A parameterless \verb@task@ method of type \verb@t@ which denotes
-the expression to be computed.
-\item
-A \verb@return@ method which consumes the result once it is
-computed.
-\end{itemize}
-The compute server creates $n$ \verb@processor@ processes as part of
-its initialization. Every such process repeatedly consumes an open
-job, evaluates the job's \verb@task@ method and passes the result on
-to the job's
-\verb@return@ method. The polymorphic \verb@future@ method creates
-a new job where the \verb@return@ method is implemented by a guard
-named \verb@reply@ and inserts this job into the set of open jobs by
-calling the \verb@isOpen@ guard. It then waits until the corresponding
-\verb@reply@ guard is called.
-
-The example demonstrates the use of abstract types. The abstract type
-\verb@t@ keeps track of the result type of a job, which can vary
-between different jobs. Without abstract types it would be impossible
-to implement the same class to the user in a statically type-safe
-way, without relying on dynamic type tests and type casts.
-
-\section{Message Spaces}
-\label{sec:messagespace}
-
-Message spaces are high-level, flexible constructs for process
-synchronization and communication. A {\em message} in this context is
-an arbitrary object. There is a special message \verb@TIMEOUT@ which
-is used to signal a time-out.
-\begin{verbatim}
-case class TIMEOUT;
-\end{verbatim}
-Message spaces implement the following signature.
-\begin{verbatim}
-class MessageSpace {
- def send(msg: Any): unit;
- def receive[a](f: PartialFunction[Any, a]): a;
- def receiveWithin[a](msec: long)(f: PartialFunction[Any, a]): a;
-}
-\end{verbatim}
-The state of a message space consists of a multi-set of messages.
-Messages are added to the space using the \verb@send@ method. Messages
-are removed using the \verb@receive@ method, which is passed a message
-processor \verb@f@ as argument, which is a partial function from
-messages to some arbitrary result type. Typically, this function is
-implemented as a pattern matching expression. The \verb@receive@
-method blocks until there is a message in the space for which its
-message processor is defined. The matching message is then removed
-from the space and the blocked thread is restarted by applying the
-message processor to the message. Both sent messages and receivers are
-ordered in time. A receiver $r$ is applied to a matching message $m$
-only if there is no other (message, receiver) pair which precedes $(m,
-r)$ in the partial ordering on pairs that orders each component in
-time.
-
-As a simple example of how message spaces are used, consider a
-one-place buffer:
-\begin{verbatim}
-class OnePlaceBuffer {
- private val m = new MessageSpace; \=// An internal message space
- private case class Empty, Full(x: int); \>// Types of messages we deal with
-
- m send Empty; \>// Initialization
-
- def write(x: int): unit =
- m receive { case Empty => m send Full(x) }
-
- def read: int =
- m receive { case Full(x) => m send Empty ; x }
-}
-\end{verbatim}
-Here's how the message space class can be implemented:
-\begin{verbatim}
-class MessageSpace {
-
- private abstract class Receiver extends Signal {
- def isDefined(msg: Any): boolean;
- var msg = null;
- }
-\end{verbatim}
-We define an internal class for receivers with a test method
-\verb@isDefined@, which indicates whether the receiver is
-defined for a given message. The receiver inherits from class
-\verb@Signal@ a \verb@notify@ method which is used to wake up a
-receiver thread. When the receiver thread is woken up, the message it
-needs to be applied to is stored in the \verb@msg@ variable of
-\verb@Receiver@.
-\begin{verbatim}
- private val sent = new LinkedList[Any](null) ;
- private var lastSent = sent;
- private var receivers = new LinkedList[Receiver](null);
- private var lastReceiver = receivers;
-\end{verbatim}
-The message space class maintains two linked lists,
-one for sent but unconsumed messages, the other for waiting receivers.
-\begin{verbatim}
- def send(msg: Any): unit = synchronized {
- var r = receivers, r1 = r.next;
- while (r1 != null && !r1.elem.isDefined(msg)) {
- r = r1; r1 = r1.next;
- }
- if (r1 != null) {
- r.next = r1.next; r1.elem.msg = msg; r1.elem.notify;
- } else {
- l = new LinkedList(msg); lastSent.next = l; lastSent = l;
- }
- }
-\end{verbatim}
-The \verb@send@ method first checks whether a waiting receiver is
-
-applicable to the sent message. If yes, the receiver is notified.
-Otherwise, the message is appended to the linked list of sent messages.
-\begin{verbatim}
- def receive[a](f: PartialFunction[Any, a]): a = {
- val msg: Any = synchronized {
- var s = sent, s1 = s.next;
- while (s1 != null && !f.isDefined(s1.elem)) {
- s = s1; s1 = s1.next
- }
- if (s1 != null) {
- s.next = s1.next; s1.elem
- } else {
- val r = new LinkedList(
- new Receiver {
- def isDefined(msg: Any) = f.isDefined(msg);
- });
- lastReceiver.next = r; lastReceiver = r;
- r.elem.wait;
- r.elem.msg
- }
- }
- f(msg)
- }
-\end{verbatim}
-The \verb@receive@ method first checks whether the message processor function
-\verb@f@ can be applied to a message that has already been sent but that
-was not yet consumed. If yes, the thread continues immediately by
-applying \verb@f@ to the message. Otherwise, a new receiver is created
-and linked into the \verb@receivers@ list, and the thread waits for a
-notification on this receiver. Once the thread is woken up again, it
-continues by applying \verb@f@ to the message that was stored in the receiver.
-
-The message space class also offers a method \verb@receiveWithin@
-which blocks for only a specified maximal amount of time. If no
-message is received within the specified time interval (given in
-milliseconds), the message processor argument $f$ will be unblocked
-with the special \verb@TIMEOUT@ message. The implementation of
-\verb@receiveWithin@ is quite similar to \verb@receive@:
-\begin{verbatim}
- def receiveWithin[a](msec: long)(f: PartialFunction[Any, a]): a = {
- val msg: Any = synchronized {
- var s = sent, s1 = s.next;
- while (s1 != null && !f.isDefined(s1.elem)) {
- s = s1; s1 = s1.next ;
- }
- if (s1 != null) {
- s.next = s1.next; s1.elem
- } else {
- val r = new LinkedList(
- new Receiver {
- def isDefined(msg: Any) = f.isDefined(msg);
- }
- )
- lastReceiver.next = r; lastReceiver = r;
- r.elem.wait(msec);
- if (r.elem.msg == null) r.elem.msg = TIMEOUT;
- r.elem.msg
- }
- }
- f(msg)
- }
-} // end MessageSpace
-\end{verbatim}
-The only differences are the timed call to \verb@wait@, and the
-statement following it.
-
-\section{Actors}
-\label{sec:actors}
-
-Chapter~\ref{sec:ex-auction} sketched as a program example the
-implementation of an electronic auction service. This service was
-based on high-level actor processes, that work by inspecting messages
-in their mailbox using pattern matching. An actor is simply a thread
-whose communication primitives are those of a message space.
-Actors are therefore defined by a mixin composition of threads and message spaces.
-\begin{verbatim}
-abstract class Actor extends Thread with MessageSpace;
-\end{verbatim}
-
-\comment{
-As an extended example of an application that uses actors, we come
-back to the auction server example of Section~\ref{sec:ex-auction}.
-The following code implements:
-
-\begin{figure}[thb]
-\begin{verbatim}
-class AuctionMessage;
-case class
- \=Offer(bid: int, client: Process), \=// make a bid
- \>Inquire(client: Process) extends AuctionMessage \>// inquire status
-
-class AuctionReply;
-case class
- \=Status(asked; int, expiration: Date), \>// asked sum, expiration date
- \>BestOffer, \>// yours is the best offer
- \>BeatenOffer(maxBid: int), \>// offer beaten by maxBid
- \>AuctionConcluded(seller: Process, client: Process), \>// auction concluded
- \>AuctionFailed \>// failed with no bids
- \>AuctionOver extends AuctionReply \>// bidding is closed
-\end{verbatim}
-\end{figure}
-
-\begin{verbatim}
-class Auction(seller: Process, minBid: int, closing: Date)
- extends Process {
-
- val timeToShutdown = 36000000 // msec
- val delta = 10 // bid increment
-\end{verbatim}
-\begin{verbatim}
- def run = {
- var askedBid = minBid
- var maxBidder: Process = null
- while (true) {
- receiveWithin ((closing - Date.currentDate).msec) {
- case Offer(bid, client) => {
- if (bid >= askedBid) {
- if (maxBidder != null && maxBidder != client) {
- maxBidder send BeatenOffer(bid)
- }
- maxBidder = client
- askedBid = bid + delta
- client send BestOffer
- } else client send BeatenOffer(maxBid)
- }
-\end{verbatim}
-\begin{verbatim}
- case Inquire(client) => {
- client send Status(askedBid, closing)
- }
-\end{verbatim}
-\begin{verbatim}
- case TIMEOUT => {
- if (maxBidder != null) {
- val reply = AuctionConcluded(seller, maxBidder)
- maxBidder send reply
- seller send reply
- } else seller send AuctionFailed
- receiveWithin (timeToShutdown) {
- case Offer(_, client) => client send AuctionOver ; discardAndContinue
- case _ => discardAndContinue
- case TIMEOUT => stop
- }
- }
-\end{verbatim}
-\begin{verbatim}
- case _ => discardAndContinue
- }
- }
- }
-\end{verbatim}
-\begin{verbatim}
- def houseKeeping: int = {
- val Limit = 100
- var nWaiting: int = 0
- receiveWithin(0) {
- case _ =>
- nWaiting = nWaiting + 1
- if (nWaiting > Limit) {
- receiveWithin(0) {
- case Offer(_, _) => continue
- case TIMEOUT =>
- case _ => discardAndContinue
- }
- } else continue
- case TIMEOUT =>
- }
- }
-}
-\end{verbatim}
-\begin{verbatim}
-class Bidder (auction: Process, minBid: int, maxBid: int)
- extends Process {
- val MaxTries = 3
- val Unknown = -1
-
- var nextBid = Unknown
-\end{verbatim}
-\begin{verbatim}
- def getAuctionStatus = {
- var nTries = 0
- while (nextBid == Unknown && nTries < MaxTries) {
- auction send Inquiry(this)
- nTries = nTries + 1
- receiveWithin(waitTime) {
- case Status(bid, _) => bid match {
- case None => nextBid = minBid
- case Some(curBid) => nextBid = curBid + Delta
- }
- case TIMEOUT =>
- case _ => continue
- }
- }
- status
- }
-\end{verbatim}
-\begin{verbatim}
- def bid: unit = {
- if (nextBid < maxBid) {
- auction send Offer(nextBid, this)
- receive {
- case BestOffer =>
- receive {
- case BeatenOffer(bestBid) =>
- nextBid = bestBid + Delta
- bid
- case AuctionConcluded(seller, client) =>
- transferPayment(seller, nextBid)
- case _ => continue
- }
-
- case BeatenOffer(bestBid) =>
- nextBid = nextBid + Delta
- bid
-
- case AuctionOver =>
-
- case _ => continue
- }
- }
- }
-\end{verbatim}
-\begin{verbatim}
- def run = {
- getAuctionStatus
- if (nextBid != Unknown) bid
- }
-
- def transferPayment(seller: Process, amount: int)
-}
-\end{verbatim}
-}
-%\todo{We also need some XML examples.}
-\end{document}
-
-
-
- case ([], _) => ys
- case (_, []) => xs
- case (x :: xs1, y :: ys1) =>
- if (x < y) x :: merge(xs1, ys) else y :: merge(xs, ys1)
-}
-
-def split (xs: List[a]): (List[a], List[a]) = xs match {
- case [] => ([], [])
- case [x] => (x, [])
- case y :: z :: xs1 => val (ys, zs) = split(xs1) ; (y :: ys, z :: zs)
-}
-
-def sort(xs: List[a]): List[a] = {
- val (ys, zs) = split(xs)
- merge(sort(ys), sort(zs))
-}
-
-
-def sort(a:Array[String]): Array[String] = {
- val pivot = a(a.length / 2)
- sort(a.filter(x => x < pivot)) ++
- a.filter(x => x == pivot) ++
- sort(a.filter(x => x > pivot))
-}
-
-def sort(a:Array[String]): Array[String] = {
-
- def swap (i: int, j: int): unit = {
- val t = a(i) ; a(i) = a(j) ; a(j) = t
- }
-
- def sort1(l: int, r: int): unit = {
- val pivot = a((l + r) / 2)
- var i = l, j = r
- while (i <= r) {
- while (i < r && a(i) < pivot) { i = i + 1 }
- while (j > l && a(j) > pivot) { j = j - 1 }
- if (i <= j) {
- swap(i, j)
- i = i + 1
- j = j - 1
- }
- }
- if (l < j) sort1(l, j)
- if (j < r) sort1(i, r)
- }
-
- sort1(0, a.length - 1)
-}
-
-class Array[a] {
-
- def copy(to: Array[a], src: int, dst: int, len: int): unit
- val length: int
- val apply(i: int): a
- val update(i: int, x: a): unit
-
- def filter (p: a => boolean): Array[a] = {
- val temp = new Array[a](a.length)
- var i = 0, j = 0
- for (i < a.length, i = i + 1) {
- val x = a(i)
- if (p(x)) { temp(j) = x; j = j + 1 }
- }
- val res = new Array[a](j)
- temp.copy(res, 0, 0, j)
- }
-
- def ++ (that: Array[a]): Array[a] = {
- val a = new Array[a](this.length + that.length)
- this.copy(a, 0, 0, this.length)
- that.copy(a, 0, this.length, that.length)
- }
-
-static
-
- def concat [a] (as: List[Array[a]]) = {
- val l = (as map (a => a.length)).sum
- val dst = new Array[a](l)
- var j = 0
- as forall {a => { a.copy(dst, j, a.length) ; j = j + a.length }}
- dst
- }
-
-}
-
-module ABT extends AlgBinTree[kt, vt]
-ABT.Map
diff --git a/doc/reference/rationale-chapter.verb.tex b/doc/reference/rationale-chapter.verb.tex
deleted file mode 100644
index 5187663f1e..0000000000
--- a/doc/reference/rationale-chapter.verb.tex
+++ /dev/null
@@ -1,125 +0,0 @@
-%% $Id$
-
-There are hundreds of programming languages in active use, and many more are
-being designed each year. It is therefore very hard to justify the development
-of yet another language. Nevertheless, this is what I attempt to do here. My
-argument rests on two claims:
-\begin{itemize}
-\item[] {\em Claim 1:} The raise in importance of web services and
-other distributed software is a fundamental paradigm
-shift in programming. It is comparable in scale to the shift 20 years ago
-from character-oriented to graphical user interfaces.
-\item[] {\em Claim 2:} That paradigm shift will provide demand
-for new programming languages, just as graphical user interfaces
-promoted the adoption of object-oriented languages.
-\end{itemize}
-To back up the first claim, one observes that web services and other
-distributed software increasingly tend to communicate using structured or
-semi-structured data. A typical example is the use of XML to describe data
-managed by applications as well as the messages between applications. This
-tends to affect the role of a program in a fundamental way. Previously,
-programs could be seen as objects that reacted to method calls and in turn
-called methods of other objects. Some of these method calls might originate
-from users while others might originate from other computers via remote
-invocations. These method calls have simple unstructured parameters or object
-references as arguments. Web services, on the other hand, communicate with
-each other by transmitting asynchronous messages that carry structured
-documents, usually in XML format. Programs then conceptually become {\em tree
-transformers} that consume incoming message documents and produce outgoing
-ones.
-
-To back up the second claim, one notes that today's object-oriented languages
-are not very good tools for analyzing and transforming the trees which
-conceptually model XML data. Because these trees usually contain data but no
-methods, they have to be decomposed and constructed from the ``outside'', that is
-from code which is external to the tree definition itself. In an
-object-oriented language, the ways of doing so are limited. The most common
-solution is to represent trees in a generic way, where all tree nodes are
-values of a common type. This approach is used in DOM, for instance. It
-facilitates the implementation of generic traversal functions, but forces
-applications to operate on a very low conceptual level, which often loses
-important semantic distinctions that are present in the XML data. A
-semantically more precise alternative would be to use different internal types
-to model different kinds of nodes. But then tree decompositions require the use
-of run-time type tests and type casts to adapt the treatment to the kind of
-node encountered. Such type tests and type casts are generally not considered
-good object-oriented style. They are rarely efficient, nor easy to use. By
-contrast, tree transformation is the natural domain of functional
-languages. Their algebraic data types, pattern matching and higher-order
-functions make these languages ideal for the task. It's no wonder, then, that
-specialized languages for transforming XML data such as XSLT are
-functional.
-
-Web services can be constructed using such a transformation language
-together with some middleware framework such as Corba to handle
-distribution and an object-oriented language for the ``application
-logic''. The downside of this approach is that the necessary amount
-of cross-language glue can make applications cumbersome to write,
-verify, and maintain. Better productivity and trustworthiness is
-achievable using a single notation and conceptual framework that would
-express object-oriented, concurrent, as well as functional aspects of
-an application. Hence, a case for so called ``multi-paradigm''
-languages can be made. But one needs to be careful not to simply
-replace cross-language glue by awkward interfaces between different
-paradigms within the language itself. The benefits of integration are
-realized fully only if the common language achieves a meaningful
-unification of concepts rather than being merely an agglutination of
-different programming paradigms. This is what we try to achieve with
-Scala\footnote{Scala stands for ``Scalable Language''.}.
-
-Scala is both an an object-oriented and functional language. It is a
-pure object-oriented language in the sense that every value is an
-object. Types and behavior of objects are described by
-classes. Classes can be composed using mixin composition. Scala is
-designed to interact well with mainstream object-oriented languages,
-in particular Java and C\#.
-
-Scala is also a functional language in the sense that every function
-is a value. Nesting of function definitions and higher-order functions
-are naturally supported. Scala also supports a general notion of
-pattern matching which can model the algebraic types used in many
-functional languages. Furthermore, this notion of pattern matching
-naturally extends to the processing of XML data.
-
-The design of Scala is driven by the desire to unify object-oriented
-and functional elements. Here are three examples how this is achieved:
-\begin{itemize}
-\item
-Since every function is a value and every value is an object, it
-follows that every function in Scala is an object. Indeed, there is a
-root class for functions which is specialized in the Scala standard
-library to data structures such as arrays and hash tables.
-\item
-Data structures in many functional languages are defined using
-algebraic data types. They are decomposed using pattern matching.
-Object-oriented languages, on the other hand, describe data with class
-hierarchies. Algebraic data types are usually closed, in that the
-range of alternatives of a type is fixed when the type is defined. By
-contrast, class hierarchies can be extended by adding new leaf
-classes. Scala adopts the object-oriented class hierarchy scheme for
-data definitions, but allows pattern matching against values coming
-from a whole class hierarchy, not just values of a single type.
-This can express both closed and extensible data types, and also
-provides a convenient way to exploit run-time type information in
-cases where static typing is too restrictive.
-\item
-Module systems of functional languages such as SML or Caml excel in
-abstraction; they allow very precise control over visibility of names
-and types, including the ability to partially abstract over types. By
-contrast, object-oriented languages excel in composition; they offer
-several composition mechanisms lacking in module systems, including
-inheritance and unlimited recursion between objects and classes.
-Scala unifies the notions of object and module, of module signature
-and interface, as well as of functor and class. This combines the
-abstraction facilities of functional module systems with the
-composition constructs of object-oriented languages. The unification
-is made possible by means of a new type system based on path-dependent
-types \cite{odersky-et-al:fool10}.
-\end{itemize}
-
-%The rest of this report is structured as follows. Chapters
-%\ref{sec:simple-examples} to \ref{sec:concurrency} give an informal overview of
-%Scala by means of a sequence of program examples. The remaining
-%chapters contain the language definition. The definition is formulated
-%in prose but tries to be precise.
-
diff --git a/doc/reference/rationale.verb.tex b/doc/reference/rationale.verb.tex
deleted file mode 100644
index 371e6efe19..0000000000
--- a/doc/reference/rationale.verb.tex
+++ /dev/null
@@ -1,21 +0,0 @@
-%% $Id$
-
-\documentclass[11pt]{article}
-
-\usepackage{fleqn,a4wide,modefs,math,prooftree,scaladefs,vquote}
-
-\title{Scala Rationale \\ Why a New programming Language for Web Services?}
-
-\author{
-Martin Odersky
-}
-
-\sloppy
-\begin{document}
-\maketitle
-
-%\todo{`:' as synononym for $\EXTENDS$?}
-
-
-\input{rationale-chapter}
-\end{document} \ No newline at end of file
diff --git a/doc/reference/reference.verb.tex b/doc/reference/reference.verb.tex
deleted file mode 100644
index dff170c2d7..0000000000
--- a/doc/reference/reference.verb.tex
+++ /dev/null
@@ -1,5025 +0,0 @@
-% $Id$
-
-\documentclass[11pt]{report}
-
-\usepackage{fleqn,a4,modefs,math,prooftree,scaladefs,vquote}
-
-\newcommand{\ifqualified}[1]{}
-\newcommand{\iflet}[1]{}
-\newcommand{\ifundefvar}[1]{}
-\newcommand{\iffinaltype}[1]{}
-\newcommand{\ifpackaging}[1]{}
-\newcommand{\ifnewfor}[1]{}
-\renewcommand{\todo}[1]{{$\clubsuit$\bf todo: #1$\spadesuit$}}
-\newcommand{\notyet}{\footnote{not yet implemented.}}
-\title{Report on the Programming Language Scala}
-
-\date{\today}
-
-\author{
-Martin Odersky \\
-Philippe Altherr \\
-Vincent Cremet \\
-Burak Emir \\
-St\'ephane Micheloud \\
-Nikolay Mihaylov \\
-Michel Schinz \\
-Erik Stenman \\
-Matthias Zenger
-\\ \
-\\
-EPFL}
-
-
-\sloppy
-\begin{document}
-\maketitle
-
-%\todo{`:' as synonym for $\EXTENDS$?}
-
-\chapter{Rationale}
-
-\input{rationale-chapter}
-
-\comment{
-\chapter{Change Log}
-
-5 August 2001: Changed from join patterns in function definitions to
-when clauses.
-
-5 August 2001: Introduced guard part in case expressions.
-
-5 August 2001: Dropped overload modifier.
-
-5 August 2001: Dropped \verb@=>@ as an alternative for \verb@=@ in
-definitions.
-
-5 August 2001: Dropped \verb@nil@ type.
-
-5 August Replaced \verb@&@ operator for parallel composition by
-\verb@fork@ function.
-
-5 August 2001: Added chapter on Concurrency (\sref{sec:concurrency}).
-
-7 August 2001: Made explicit in the grammar that block-local
-definitions do not have modifiers.
-
-7 August 2001: Introduced permitted but redundant modifier `private'
-for guards.
-
-9 August 2001: Replaced qualified identifiers in class definitions by
-modifiers \verb@new@ and \verb@override@.
-
-9 August 2001: Tightened rules for member access, so that superclass
-ordering is irrelevant. See definition of qualified expansion in
-\sref{sec:names}.
-
-9 August 2001: Guarded choice now always picks tectually first enabled
-guard, rather than an arbitrary one.
-
-16 August 2001: Unary postfix operators now have lower precedence than
-unary infix.
-
-16 August 2001: Use `=' instead of `:=' for assignment.
-
-16 August 2001: Changed scope rules so that scope of a definition
-always extends to the whole enclosing block or template, plus an
-anti forward-dependency rule for value definitions.
-
-16 August 2001: Changed Grammar to allow repeated data definitions
-only with extends clauses of simple type, so that parameter names
-cannot be used.
-
-16 August 2001: Changed Grammar to drop NxStat, etc (the context-free language
-is not affected by the change).
-
-23 August 2001: Eliminated unboxed types.
-
-23 August 2001: Eliminated recursive value definitions; changed rules
- for pattern value definitions.
-
-26 August 2001: Clarified indentation rules.
-
-26 August 2001: Adapted meaning of \verb@null@ to value types.
-
-26 August 2001: Apply local type inference in class instance expressions.
-
-23 Sep 2001: Changed $\arrow$ in closures to $\Arrow$.
-
-23 Sep 2001: Changed record types to refinements.
-
-25 Oct 2001: Simplified and generalized class and module
-design. Classes and modules can now appear anywhere; modules are no
-longer parameterized.
-
-25 Oct 2001: Dropped aspects (for the time being).
-
-29 Oct 2001:
- Tuple and function types are now shorthands for predefined
- classes. Tuples are no longer covariant.
-
-29 Oct 2001:
- Introduced $n$-ary functions and changed syntax for function types.
-
-29 Oct 2001:
- Dropped static part of classes. Classes now define a constructor
- function of the same name.
-
-29 Oct 2001:
- Generalized rules for overloading slightly.
-
-29 Oct 2001:
- Dropped modifiers for guards.
-
-29 Oct 2001:
- Disambiguated syntax for pattern matching cases with guards.
-class P[+a, +b] {
- val fst: a, snd: b
-}
-
-2 Nov 2001: Changed private and protected to their meaning in Java.
-
-2 Nov 2001: Introduced packagings.
-
-5 Nov 2001: Dropped value parameters in class aliases.
-
-14 Nov 2001: Fixed rule for subtyping of overloaded
-function. Tightened scope of value parameters.
-
-15 Nov 2001: Changed `with' to `if' as pattern guard and simplified
-pattern syntax.
-
-15 Nov 2001: Changed `data' to `case class'.
-
-20 Nov 2001: Case classes need no longer be `final'.
-
-30 Nov 2001: Introduced `qualified' classes, with unqualified classes
-being the default.
-
-4 Dec 2001: Introduced interfaces (\sref{sec:interfaces})
-
-4 Dec 2001: Changed rules which members are inherited (\sref{sec:members}).
-
-4 Dec 2001: Changed rules for compound types with refinements to match
-those for templates (\sref{sec:compound-types}).
-
-6 Dec 2001: Dropped modifiers `virtual' and `new'.
-
-6 Dec 2001: `new' is again mandatory in instance creation expressions.
-
-10 Dec 2001: Dropped concurrency constructs in language.
-
-11 Dec 2001: Changed name from `Funnel' to `Scala'.
-
-18 Dec 2001: Slight change of syntax for anonymous functions.
-
-29 Dec 2001: Case classes define accessors for parameters
-
-6 Feb 2002: Import clauses defined only for stable identifiers.
-
-6 Feb 2002: Dropped restriction that classes may not have
-inherited abstract members.
-
-6 Feb 2002: Reclassified `new' as Expr4
-
-6 Feb 2002: Dropped interface keyword
-
-6 Feb 2002: Changed syntax of `if'.
-
-6 Feb 2002: Introduced constructor types.
-
-6 Feb 2002: Eliminated class aliases.
-
-6 Feb 2002: Replaced user-defined value definitions by comprehensions.
-
-6 Feb 2002: Tightened conditions on well-formed base class sequence.
-
-6 Feb 2002: Changed root class hierarchy.
-
-7 Feb 2002: Tightened rules on forward references.
-
-7 Feb 2002: Only prefix operators are now `-', `+', `!'. They are
-translated to method calls of their operand.
-}
-
-class List[a <: AnyRef](x: a, xs: List[a]) {
- def head = x;
- def tail = xs;
- def this(x: a) = { ... ; this(x, Nil); ... }
- def this() = this(null, Nil);
-}
-
-
-
-
-% 16 Jul 2003 Regular pattern matching (Chapter 8)
-
-\subsection*{Status of This Document}
-
-The present document defines slightly more than what is implemented in
-the current compiler. But I have tried to mark all omissions that
-still exist.
-
-\part{Language Definition}
-
-\chapter{Lexical Syntax}
-
-This chapter defines the syntax of Scala tokens. Tokens are
-constructed from symbols in the following character sets:
-\begin{enumerate}
-\item Whitespace characters.
-\item Lower case letters \verb@`a' | ... | `z'@ and
-upper case letters \verb@`A' | ... | `Z' | `$\Dollar$' | `_'@.
-\item Digits \verb@`0' | ... | `9'@.
-\item Parentheses \verb@`(' | `)' | `[' | `]' | `{' | `}'@.
-\item Delimiter characters \verb@`\' | `'' | `"' | `.' | `;' | `,'@.
-\item Operator characters. These include all printable ASCII characters
-which are in none of the sets above.
-\end{enumerate}
-
-These sets are extended in the usual way to unicode\notyet (i.e.\ as in Java).
-Unicode encodings \verb@`\uXXXX'@ are also as in Java.
-
-\section{Identifiers}
-
-\syntax\begin{verbatim}
-op \=::= \= special {special} [`_' [id]]
-varid \>::= \> lower {letter $|$ digit} [`_' [id]]
-id \>::= \> upper {letter $|$ digit} [`_' [id]]
- \> | \> varid
- \> | \> op
-\end{verbatim}
-
-There are two ways to form an identifier. First, an identifier can
-start with a letter which can be followed by an arbitrary sequence of
-letters and digits. Second, an identifier can be start with a special
-character followed by an arbitrary sequence of special characters.
-In both cases, the identifier prefix may be immediately followed
-by an underscore `\verb@_@' character and another string of characters
-that by themselves make up an identifier. As usual, a longest match
-rule applies. For instance, the string
-
-\begin{verbatim}
-big_bob++=z3
-\end{verbatim}
-
-decomposes into the three identifiers \verb@big_bob@, \verb@++=@, and
-\verb@z3@. The rules for pattern matching further distinguish between
-{\em variable identifiers}, which start with a lower case letter, and
-{\em constant identifiers}, which do not.
-
-
-The `\verb@\$@' character is reserved for compiler-synthesized identifiers.
-User programs are not allowed to define identifiers which contain `\verb@\$@'
-characters.
-
-The following names are reserved words instead of being members of the
-syntactic class \verb@id@ of lexical identifiers.
-
-\begin{verbatim}
-abstract case catch class def
-do else extends false final
-finally for if import new
-null object override package private
-protected return sealed super this
-trait try true type val
-var while with yield
-_ : = => <- <: >: # @
-\end{verbatim}
-
-The unicode operator `\verb@=>@' has the ascii equivalent
-`$=>$', which is also reserved\notyet.
-
-\example
-Here are examples of identifiers:
-\begin{verbatim}
- x \=Object \=maxIndex \=p2p \=empty_?
- + \> +_field
-\end{verbatim}
-
-\section{Braces and Semicolons}
-
-A semicolon `\verb@;@' is implicitly inserted after every closing brace
-if there is a new line character between closing brace and the next
-regular token after it, except if that token cannot legally start a
-statement.
-
-The tokens which cannot legally start a statement
-are the following delimiters and reserved words:
-\begin{verbatim}
-else extends with yield do
-, . ; : = => <- <: >: # @ ) ] }
-\end{verbatim}
-
-\section{Literals}
-
-There are literals for integer numbers (of types \verb@Int@ and \verb@Long@),
-floating point numbers (of types \verb@Float@ and \verb@Double@), characters, and
-strings. The syntax of these literals is in each case as in Java.
-
-\syntax\begin{verbatim}
-literal \=::= \= intLit
- \> | \> floatLit
- \> | \> charLit
- \> | \> stringLit
- \> | \> symbolLit
-intLit \>::= \> ``as in Java''
-floatLit \>::= \> ``as in Java''
-charLit \>::= \> ``as in Java''
-stringLit \>::= \> ``as in Java''
-symbolLit ::= `\'` id
-\end{verbatim}
-
-A symbol literal has the form \verb@'x@ where \verb@x@ is an identifier.
-Such a symbol literal is a shorthand for the application
-\begin{verbatim}
-scala.Symbol("x")
-\end{verbatim}
-of the facotry method for the standard case class \verb@Symbol@ to the string "x".
-
-\section{Whitespace and Comments}
-
-Tokens may be separated by whitespace characters (ascii codes 0 to 32)
-and/or comments. Comments come in two forms:
-
-A single-line comment is a sequence of characters which starts with
-\verb@//@ and extends to the end of the line.
-
-A multi-line comment is a sequence of characters between \verb@/*@ and
-\verb@*/@. Multi-line comments may be nested.
-
-
-\chapter{\label{sec:names}Identifiers, Names and Scopes}
-
-Names in Scala identify types, values, functions, and classes which
-are collectively called {\em entities}. Names are introduced by
-definitions, declarations (\sref{sec:defs}) or import clauses
-(\sref{sec:import}), which are collectively called {\em binders}.
-
-There are two different name spaces, one for types (\sref{sec:types})
-and one for terms (\sref{sec:exprs}). The same name may designate a
-type and a term, depending on the context where the name is used.
-
-A definition or declaration has a {\em scope} in which the entity
-defined by a single name can be accessed using a simple name. Scopes
-are nested, and a definition or declaration in some inner scope {\em
-shadows} a definition in an outer scope that contributes to the same
-name space. Furthermore, a definition or declaration shadows bindings
-introduced by a preceding import clause, even if the import clause is
-in the same block. Import clauses, on the other hand, only shadow
-bindings introduced by other import clauses in outer blocks.
-
-A reference to an unqualified (type- or term-) identifier $x$ is bound
-by the unique binder, which
-\begin{itemize}
-\item defines an entity with name $x$ in the same namespace as the
-identifier, and
-\item shadows all other binders that define entities with name $x$ in that namespace.
-\end{itemize}
-It is an error if no such binder exists. If $x$ is bound by an import
-clause, then the simple name $x$ is taken to be equivalent to the
-qualified name to which $x$ is mapped by the import clause. If $x$ is bound by a definition or declaration,
-then $x$ refers to the entity introduced by that
-binder. In that case, the type of $x$ is the type of the referenced
-entity.
-
-\example Consider the following nested definitions and imports:
-
-\begin{verbatim}
-object m1 {
- object m2 { val x: int = 1; val y: int = 2 }
- object m3 { val x: boolean = true; val y: String = "" }
- val x: int = 3;
- { import m2._; \= // shadows nothing
- \> // reference to `x' is ambiguous here
- val x: String = "abc"; \> // shadows preceding import and val
- \> // `x' refers to latest val definition
- { import m3._ \> // shadows only preceding import m2
- \> // reference to `x' is ambiguous here
- \> // `y' refers to latest import clause
- }
- }
-}
-\end{verbatim}
-
-A reference to a qualified (type- or term-) identifier $e.x$ refers to
-the member of the type $T$ of $e$ which has the name $x$ in the same
-namespace as the identifier. It is an error if $T$ is not an object type
-(\sref{def:object-type}). The type of $e.x$ is the member type of the
-referenced entity in $T$.
-
-\chapter{\label{sec:types}Types}
-
-\syntax\begin{verbatim}
- Type \=::= \= Type1 `=>' Type
- \> |\> `(' [Types] `)' `=>' Type
- \> |\> Type1
- Type1 \>::= \> SimpleType {with SimpleType} [Refinement]
- SimpleType \>::= \> StableId
- \> |\> SimpleType `#' id
- \> |\> Path `.' type
- \> |\> SimpleType TypeArgs
- \> |\> `(' Type ')'
- Types \>::= \> Type {`,' Type}
-\end{verbatim}
-
-We distinguish between first-order types and type constructors, which
-take type parameters and yield types. A subset of first-order types
-called {\em value types} represents sets of (first-class) values.
-Value types are either {\em concrete} or {\em abstract}. Every
-concrete value type can be represented as a {\em class type}, i.e.\ a
-type designator (\sref{sec:type-desig}) that refers to a
-class\footnote{We assume that objects and packages also
-implicitly define a class (of the same name as the object or package,
-but inaccessible to user programs).} (\sref{sec:classes}),
-or as a {\em compound type} (\sref{sec:compound-types})
-consisting of class types and possibly
-also a refinement (\sref{sec:refinements}) that further constrains the
-types of its members.
-
-A shorthands exists for denoting function types
-(\sref{sec:function-types}). Abstract value types are introduced by
-type parameters and abstract type bindings (\sref{sec:typedcl}).
-Parentheses in types are used for grouping.
-
-Non-value types capture properties of
-identifiers that are not values
-(\sref{sec:synthetic-types}). There is no syntax to express these
-types directly in Scala.
-
-\section{Paths}\label{sec:paths}
-
-\syntax\begin{verbatim}
- StableId \=::= \= id
- \> |\> Path `.' id
- \> |\> [id '.'] super [`[' id `]'] `.' id
- Path \>::=\> StableId
- \> |\> [id `.'] this
-\end{verbatim}
-
-Paths are not types themselves, but they can be a part of named types
-and in that way form a central role in Scala's type system.
-
-A path is one of the following.
-\begin{itemize}
-\item
-The empty path $\epsilon$ (which cannot be written explicitly in user programs).
-\item
-\verb@C.this@, where \verb@C@ references a class.
-The path \verb@this@ is taken as a shorthand for \verb@C.this@ where
-\verb@C@ is the class directly enclosing the reference.
-\item
-\verb@p.x@ where \verb@p@ is a path and \verb@x@ is a stable member of \verb@p@.
-{\em Stable members} are members introduced by value or object
-definitions, as well as packages.
-\item
-\verb@C.super.x@ or \verb@C.super[M].x@
-where \verb@C@ references a class and \verb@x@ references a
-stable member of the super class or designated mixin class \verb@M@ of \verb@C@.
-The prefix \verb@super@ is taken as a shorthand for \verb@C.super@ where
-\verb@C@ is the class directly enclosing the reference.
-\end{itemize}
-A {\em stable identifier} is a path which ends in an identifier.
-
-\section{Value Types}
-
-\subsection{Singleton Types}
-\label{sec:singleton-type}
-
-\syntax\begin{verbatim}
- SimpleType ::= Path `.' type
-\end{verbatim}
-
-A singleton type is of the form \verb@p.type@, where \verb@p@ is a
-path. The type denotes the set of values consisting of
-exactly the value denoted by \verb@p@.
-
-\subsection{Type Projection}
-\label{sec:type-project}
-
-\syntax\begin{verbatim}
-SimpleType ::= SimpleType `#' id
-\end{verbatim}
-
-A type projection \verb@T#x@ references the type member named
-\verb@x@ of type \verb@T@. \verb@T@ must be either a singleton type,
-or a non-abstract class type, or a Java class type (in either of the
-last two cases, it is guaranteed that \verb@T@ has no abstract type
-members).
-
-\subsection{Type Designators}
-\label{sec:type-desig}
-
-\syntax\begin{verbatim}
- SimpleType ::= StableId
-\end{verbatim}
-
-A type designator refers to a named value type. It can be simple or
-qualified. All such type designators are shorthands for type projections.
-
-Specifically, the unqualified type name $t$ where $t$ is bound in some
-class, object, or package $C$ is taken as a shorthand for
-\verb@C.this.type#t@. If $t$ is not bound in a class, object, or
-package, then \verb@t@ is taken as a shorthand for
-\verb@$\epsilon$.type#t@.
-
-A qualified type designator has the form \verb@p.t@ where \verb@p@ is
-a path (\sref{}) and $t$ is a type name. Such a type designator is
-equivalent to the type projection \verb@p.type#x@.
-
-\example
-Some type designators and their expansions are listed below. We assume
-a local type parameter \verb@t@, a value \verb@mytable@
-with a type member \verb@Node@ and the standard class \verb@scala.Int@,
-\begin{verbatim}
- t \=$\epsilon$.type#t
- Int \>scala.type#Int
- scala.Int \>scala.type#Int
- mytable.Node \>mytable.type#Node
-\end{verbatim}
-
-\subsection{Parameterized Types}
-\label{sec:param-types}
-
-\syntax\begin{verbatim}
- SimpleType \=::= \= SimpleType TypeArgs
- TypeArgs \>::= \> `[' Types `]'
-\end{verbatim}
-
-A parameterized type $T[U_1, ..., U_n]$ consists of a type designator
-$T$ and type parameters $U_1 \commadots U_n$ where $n \geq 1$. $T$
-must refer to a type constructor which takes $n$ type parameters $a_1,
-..., a_n$ with lower bounds $L_1, ..., L_n$ and upper bounds $U_1,
-..., U_n$.
-
-The parameterized type is well-formed if each actual type parameter
-{\em conforms to its bounds}, i.e.\ $L_i\sigma <: T_i <: U_i\sigma$ where $\sigma$
-is the substitution $[a_1 := T_1, ..., a_n := T_n]$.
-
-\example\label{ex:param-types}
-Given the partial type definitions:
-
-\begin{verbatim}
- class TreeMap[a <: Ord[a], b] { ... }
- class List[a] { ... }
- class I extends Ord[I] { ... }
-\end{verbatim}
-
-the following parameterized types are well formed:
-
-\begin{verbatim}
- HashMap[I, String]
- List[I]
- List[List[Boolean]]
-\end{verbatim}
-
-\example Given the type definitions of \ref{ex:param-types},
-the following types are ill-formed:
-
-\begin{verbatim}
- HashMap[I] \=// illegal: wrong number of parameters
- HashMap[List[I], Boolean] \>// illegal: type parameter not within bound
-\end{verbatim}
-
-\subsection{Compound Types}
-\label{sec:compound-types}
-
-\syntax\begin{verbatim}
- Type \=::= \= SimpleType {with SimpleType} [Refinement]
- Refinement \>::=\> `{' [RefineStat {`;' RefineStat}] `}'
- RefineStat \>::=\> Dcl
- \> |\> type TypeDef {`,' TypeDef}
- \> |\>
-\end{verbatim}
-
-A compound type \verb@T$_1$ with ... with T$_n$ {R}@ represents
-objects with members as given in the component types $T_1 \commadots
-T_n$ and the refinement \verb@{R}@. Each component type $T_i$ must be a
-class type and the base class sequence generated by types $T_1
-\commadots T_n$ must be well-formed (\sref{sec:basetypes-wf}). A
-refinement \verb@{R}@ contains declarations and type
-definitions. Each declaration or definition in a refinement must
-override a declaration or definition in one of the component types
-$T_1 \commadots T_n$. The usual rules for overriding (\sref{})
-apply. If no refinement is given, the empty refinement is implicitly
-added, i.e. \verb@T$_1$ with ... with T$_n$@ is a shorthand for
-\verb@T$_1$ with ... with T$_n$ {}@.
-
-\subsection{Function Types}
-\label{sec:function-types}
-
-\syntax\begin{verbatim}
- SimpleType \=::= \= Type1 `=>' Type
- \> |\> `(' [Types] `)' `=>' Type
-\end{verbatim}
-The type \verb@(T$_1$, ..., T$_n$) => U@ represents the set of function
-values that take arguments of types $T_1 \commadots T_n$ and yield
-results of type $U$. In the case of exactly one argument type
-\verb@S => T@ is a shorthand for \verb@(S) => T@. Function types
-associate to the right, e.g.\ \verb@(S) => (T) => U@ is the same as
-\verb@(S) => ((T) => U)@.
-
-Function types are shorthands for class types that define \verb@apply@
-functions. Specifically, the $n$-ary function type $(T_1 \commadots
-T_n)U$ is a shorthand for the class type
-\verb@Function$\,n$[$T_1 \commadots T_n$,U]@. Such class
-types are defined in the Scala library for \verb@n@ between 0 and 9 as follows.
-\begin{verbatim}
-package scala;
-trait Function$\,n$[-T$_1$, ..., -T$_n$, +R] {
- def apply(x$_1$: T$_1$, ..., x$_n$: T$_n$): R;
- override def toString() = "<function>";
-}
-\end{verbatim}
-Hence, function types are covariant in their result type, and
-contravariant in their argument types.
-
-\section{Non-Value Types}
-\label{sec:synthetic-types}
-
-The types explained in the following do not denote sets of values, nor
-do they appear explicitely in programs. They are introduced in this
-report as the internal types of defined identifiers.
-
-\subsection{Method Types}
-\label{sec:method-types}
-
-A method type is denoted internally as $(Ts)U$, where $(Ts)$ is a
-sequence of types $(T_1 \commadots T_n)$ for some $n \geq 0$
-and $U$ is a (value or method) type. This type represents named
-methods that take arguments of types $T_1 \commadots T_n$
-and that return a result of type $U$.
-
-Method types associate to the right: $(Ts_1)(Ts_2)U$ is treated as
-$(Ts_1)((Ts_2)U)$.
-
-A special case are types of methods without any parameters. They are
-written here $[]T$, following the syntax for polymorphic method types
-(\sref{sec:poly-types}). Parameterless methods name expressions that
-are re-evaluated each time the parameterless method name is
-referenced.
-
-Method types do not exist as types of values. If a method name is used
-as a value, its type is implicitly converted to a corresponding
-function type (\sref{sec:impl-conv}).
-
-\example The declarations
-\begin{verbatim}
-def a: Int
-def b (x: Int): Boolean
-def c (x: Int) (y: String, z: String): String
-\end{verbatim}
-produce the typings
-\begin{verbatim}
-a: [] Int
-b: (Int) Boolean
-c: (Int) (String, String) String
-\end{verbatim}
-
-\subsection{Polymorphic Method Types}
-\label{sec:poly-types}
-
-A polymorphic method type is denoted internally as \verb@[tps]T@ where
-\verb@[tps]@ is a type parameter section
-\verb@[a$_1$ <: L$_1$ >: U$_1$, ..., a$_n$ <: L$_n$ >: U$_n$] T@
-for some $n \geq 0$ and \verb@T@ is a
-(value or method) type. This type represents named methods that
-take type arguments \verb@S$_1$, ..., S$_n$@ which
-conform (\sref{sec:param-types}) to the lower bounds
-\verb@S$_1$, ..., S$_n$@ and the upper bounds
-\verb@U$_1$, ..., U$_n$@ and that yield results of type \verb@T@.
-
-\example The declarations
-\begin{verbatim}
-def empty[a]: List[a]
-def union[a <: Comparable[a]] (x: Set[a], xs: Set[a]): Set[a]
-\end{verbatim}
-produce the typings
-\begin{verbatim}
-empty \=: [a >: All <: Any] List[a]
-union \>: [a >: All <: Comparable[a]] (x: Set[a], xs: Set[a]) Set[a] .
-\end{verbatim}
-
-\subsection{Overloaded Types}
-\label{sec:overloaded-types}
-\newcommand{\overload}{\la\mbox{\sf and}\ra}
-
-
-More than one values or methods are defined in the same scope with the
-same name, we model
-
-An overloaded type consisting of type alternatives $T_1 \commadots
-T_n$ $(n \geq 2)$ is denoted internally $T_1 \overload \ldots
-\overload T_n$.
-
-\example The definitions
-\begin{verbatim}
-def println: unit;
-def println(s: string): unit = ...;
-def println(x: float): unit = ...;
-def println(x: float, width: int): unit = ...;
-def println[a](x: a)(tostring: a => String): unit = ...
-\end{verbatim}
-define a single function \verb@println@ which has an overloaded
-type.
-\begin{verbatim}
-println: \= [] unit $\overload$
- \> (String) unit $\overload$
- \> (float) unit $\overload$
- \> (float, int) unit $\overload$
- \> [a] (a) (a => String) unit
-\end{verbatim}
-
-\example The definitions
-\begin{verbatim}
-def f(x: T): T = ...;
-val f = 0
-\end{verbatim}
-define a function \verb@f@ which has type \verb@(x: T)T $\overload$ Int@.
-
-\section{Base Classes and Member Definitions}
-\label{sec:base-classes}
-
-Types, bounds and base classes of class members depend on the way the
-members are referenced. Central here are three notions, namely:
-\begin{enumerate}
-\item the notion of the base class sequence of a type $T$,
-\item the notion of a type $T$ seen as a member of some class $C$ from some
- prefix type $S$,
-\item the notion of a member binding of some type $T$.
-\end{enumerate}
-These notions are defined mutually recursively as follows.
-
-1. The {\em base class sequence} of a type is a sequence of class types,
-given as follows.
-\begin{itemize}
-\item
-The base classes of a class type \verb@C@ are the base classes of class
-\verb@C@.
-\item
-The base classes of an aliased type are the base classes of its alias.
-\item
-The base classes of an abstract type are the base classes of its upper bound.
-\item
-The base classes of a parameterized type \verb@C[T$_1$, ..., T$_n$]@ are the base classes
-of type \verb@C@, where every occurrence of a type parameter $a_i$
-of \verb@C@ has been replaced by the corresponding parameter type $T_i$.
-\item
-The base classes of a singleton type \verb@p.type@ are the base classes of
-the type of \verb@p@.
-\item
-The base classes of a compound type
-\verb@T$_1$ with ... with T$_n$ with {R}@ is the concatenation of the
-base classes of all \verb@T$_i$@'s, except that later base classes replace
-earlier base classes which are instances of the same class.
-\end{itemize}
-
-2. The notion of a type \verb@T@
-{\em seen as a member of some class \verb@C@ from some prefix type
-\verb@S@} makes sense only if the prefix type \verb@S@
-has a type instance of class \verb@C@ as a base class, say
-\verb@S'#C[T$_1$, ..., T$_n$]@. Then we define as follows.
-\begin{itemize}
- \item
- If \verb@S = $\epsilon$.type@, then $T$ seen as a member of $C$ from $S$ is $T$ itself.
- \item Otherwise, if \verb@T@ is the $i$'th type parameter of some class \verb@D@, then
- \begin{itemize}
- \item
- If \verb@S@ has a base class \verb@D[U$_1$, ..., U$_n$]@, for some type parameters
- \verb@[U$_1$, ..., U$_n$]@, then \verb@T@ seen as a member of $C$ from $S$ is $U_i$.
- \item
- Otherwise, if $C$ is defined in a class $C'$, then
- \verb@T@ seen as a member of $C$ from $S$ is the same as $T$ seen as
- a member of $C'$ from $S'$.
- \item
- Otherwise, if $C$ is not defined in another class, then
- \verb@T@ seen as a member of $C$ from $S$ is $T$ itself.
- \end{itemize}
-\item
- Otherwise,
- if \verb@T@ is the singleton type \verb@D.this.type@ for some class \verb@D@
- then
- \begin{itemize}
- \item
- If \verb@D@ is a subclass of \verb@C@ and
- \verb@S@ has a type instance of class $D$ among its base classes.
- then \verb@T@ seen as a member of $C$ from $S$ is $S$.
- \item
- Otherwise, if $C$ is defined in a class $C'$, then
- \verb@T@ seen as a member of $C$ from $S$ is the same as $T$ seen as
- a member of $C'$ from $S'$.
- \item
- Otherwise, if $C$ is not defined in another class, then
- \verb@T@ seen as a member of $C$ from $S$ is $T$ itself.
- \end{itemize}
-\item
- If $T$ is some other type, then the described mapping is performed
- to all its type components.
-\end{itemize}
-
-If \verb@T@ is a possibly parameterized class type, where $T$'s class
-is defined in some other class $D$, and \verb@S@ is some prefix type,
-then we use ``\verb@T@ seen from \verb@S@'' as a shorthand for
-``\verb@T@ seen as a member of $D$ from $S$.
-
-3. The {\em member bindings} of a type $T$ are all bindings $d$ such that
-there exists a type instance of some class $C$ among the base classes of $T$
-and there exists a definition or declaration $d'$ in $C$
-such that $d$ results from $d'$ by replacing every
-type $T'$ in $d'$ by $T'$ seen as a member of $C$ from $T$.
-
-The {\em definition} of a type projection \verb@S#t@ is the member
-binding $d$ of the type \verb@t@ in \verb@S@. In that case, we also say
-that \verb@S#t@ {\em is defined by} \verb@d@.
-
-\section{Relations between types}
-
-We define two relations between types.
-\begin{quote}\begin{tabular}{l@{\tab}l@{\tab}l}
-\em Type equivalence & $T \equiv U$ & $T$ and $U$ are interchangeable
-in all contexts.
-\\
-\em Conformance & $T \conforms U$ & Type $T$ conforms to type $U$.
-\end{tabular}\end{quote}
-
-\subsection{Type Equivalence}
-\label{sec:type-equiv}
-
-Equivalence $(\equiv)$ between types is the smallest congruence\footnote{ A
-congruence is an equivalence relation which is closed under formation
-of contexts} such that the following holds:
-\begin{itemize}
-\item
-If $t$ is defined by a type alias \verb@type t = T@, then $t$ is
-equivalent to $T$.
-\item
-If a path $p$ has a singleton type \verb@q.type@, then
-\verb@p.type $\equiv$ q.type@.
-\item
-If \verb@O@ is defined by an object definition, and \verb@p@ is a path
-consisting only of package or object selectors and ending in \verb@O@, then
-\verb@O.this.type $\equiv$ p.type@.
-\item
-Two compound types are equivalent if their component types are
-pairwise equivalent and their refinements are equivalent. Two
-refinements are equivalent if they bind the same names and the
-modifiers, types and bounds of every declared entity are equivalent in
-both refinements.
-\item
-Two method types are equivalent if they have equivalent result
-types, both have the same number of parameters, and corresponding
-parameters have equivalent types as well as the same \verb@def@ or
-\verb@*@ modifiers. Note that the names of parameters do not matter
-for method type equivalence.
-\item
-Two polymorphic types are equivalent if they have the same number of
-type parameters, and, after renaming one set of type parameters by
-another, the result types as well as lower and upper bounds of
-corresponding type parameters are equivalent.
-\item
-Two overloaded types are equivalent if for every alternative type in
-either type there exists an equivalent alternative type in the other.
-\end{itemize}
-
-\subsection{Conformance}
-\label{sec:subtyping}
-
-The conformance relation $(\conforms)$ is the smallest
-transitive relation that satisfies the following conditions.
-\begin{itemize}
-\item Conformance includes equivalence. If $T \equiv U$ then $T \conforms U$.
-\item For every value type $T$, \verb@scala.All <: T <: scala.Any@.
-\item For every value type \verb@T <: scala.AnyRef@ one has \verb@scala.AllRef <: T@.
-\item A type variable or abstract type $t$ conforms to its upper bound and
- its lower bound conforms to $t$.
-\item A class type or parameterized type $c$ conforms to any of its basetypes, $b$.
-\item A type projection \verb@T#t@ conforms to \verb@U#t@ if
- \verb@T@ conforms to \verb@U@.
-\item A parameterized type \verb@T[T$_1$, ..., T$_n$]@ conforms to
- \verb@T[U$_1$, ..., U$_n$]@ if
- the following three conditions hold for $i = 1 \commadots n$.
- \begin{itemize}
- \item
- If the $i$'th type parameter of $T$ is declared covariant, then $T_i <: U_i$.
- \item
- If the $i$'th type parameter of $T$ is declared contravariant, then $U_i <: T_i$.
- \item
- If the $i$'th type parameter of $T$ is declared neither covariant
- nor contravariant, then $U_i \equiv T_i$.
- \end{itemize}
-\item A compound type \verb@T$_1$ with ... with T$_n$ {R}@ conforms to
- each of its component types \verb@T$_i$@.
-\item If $T \conforms U_i$ for $i = 1 \commadots n$ and for every
- binding of a type or value $x$ in $R$ there exists a member binding of
- $x$ in $T$ which is more specific, then $T$ conforms to
- the compound type \verb@T$_1$ with ... with T$_n$ {R}@.
-\item If
- $T'_i$ conforms to $T_i$ for $i = 1 \commadots n$ and $U$ conforms to $U'$
- then the method type $(T_1 \commadots T_n) U$ conforms to
- $(T'_1 \commadots T'_n) U'$.
-\item If, assuming
-$L'_1 \conforms a_1 \conforms U'_1 \commadots L'_n \conforms a_n \conforms U'_n$
-one has $L_i \conforms L'_i$ and $U'_i \conforms U_i$
-for $i = 1 \commadots n$, as well as $T \conforms T'$ then the polymorphic type
-$[a_1 >: L_1 <: U_1 \commadots a_n >: L_n <: U_n] T$ conforms to the polymorphic type
-$[a_1 >: L'_1 <: U'_1 \commadots a_n >: L'_n <: U'_n] T'$.
-\item
-An overloaded type $T_1 \overload \ldots \overload T_n$ conforms to each of its alternative types $T_i$.
-\item
-A type $S$ conforms to the overloaded type $T_1 \overload \ldots \overload T_n$
-if $S$ conforms to each alternative type $T_i$.
-\end{itemize}
-
-A declaration or definition in some compound type of class type $C$
-is {\em more specific} than another
-declaration of the same name in some compound type or class type $C'$.
-\begin{itemize}
-\item
-A value declaration \verb@val x: T@ or value definition
-\verb@val x: T = e@ is more specific than a value declaration
-\verb@val x: T'@ if $T <: T'$.
-\item
-A type alias
-$\TYPE;t=T$ is more specific than a type alias $\TYPE;t=T'$ if
-$T \equiv T'$.
-\item
-A type declaration \verb@type t >: L <: U@ is more specific that
-a type declaration \verb@type t >: L' <: U'@ if \verb@L' <: L@ and \verb@U <: U'@.
-\item
-A type or class definition of some type $t$ is more specific than an abstract
-type declaration \verb@type t >: L <: U@ if
-\verb@L <: t <: U@.
-\end{itemize}
-
-The \verb@<:@ relation forms a partial order between types. The {\em
-least upper bound} or the {\em greatest lower bound} of a set of types
-is understood to be relative to that order.
-
-\section{Type Erasure}
-\label{sec:erasure}
-
-A type is called {\em generic} if it contains type arguments or type variables.
-{\em Type erasure} is a mapping from (possibly generic) types to
-non-generic types. We write $|T|$ for the erasure of type $T$.
-The erasure mapping is defined as follows.
-\begin{itemize}
-\item The erasure of a type variable is the erasure of its upper bound.
-\item The erasure of a parameterized type $T[T_1 \commadots T_n]$ is $|T|$.
-\item The erasure of a singleton type \verb@p.type@ is the
- erasure of the type of \verb@p@.
-\item The erasure of a type projection \verb@T#x@ is \verb@|T|#x@.
-\item The erasure of a compound type $T_1;\WITH;\ldots;\WITH;T_n\{R\}$ is $|T_1|$.
-\item The erasure of every other type is the type itself.
-\end{itemize}
-
-\section{Implicit Conversions}
-\label{sec:impl-conv}
-
-If $S \conforms T$, then values of type $S$ are implicitly {\em
-converted} to values type of $T$ in situations where a value of type
-$T$ is required. A conversion between two number types in \verb@int@,
-\verb@long@, \verb@float@, \verb@double@ creates a value of the target
-type representing the same number as the source. When used in an
-expression, a value of type \verb@byte@, \verb@char@, \verb@short@ is
-always implicitly converted to a value of type \verb@int@.
-
-The following implicit conversions are applied to expressions of
-method type that are used as values, rather than being applied to some
-arguments.
-\begin{itemize}
-\item
-A parameterless method $m$ of type $[] T$
-is converted to type $T$ by evaluating the expression to which $m$ is bound.
-\item
-An expression $e$ of polymorphic type
-\verb@[a$_1$ >: L$_1$ <: U$_1$, ..., a$_n$ >: L$_n$ <: U$_n$]T@
-which does not appear as the function part of
-a type application is converted to type \verb@T@
-by determining with local type inference
-(\sref{sec:local-type-inf}) instance types \verb@T$_1$, ..., T$_n$@
-for the type variables \verb@a$_1$, ..., a$_n$@ and
-implicitly embedding \verb@e@ in the type application
-\verb@e[U$_1$, ..., U$_n$]@ (\sref{sec:type-app}).
-\item
-An expression \verb@e@ of monomorphic method type
-$(Ts_1) \ldots (Ts_n) U$ of arity $n > 0$
-which does not appear as the function part of an application is
-converted to a function type by implicitly embedding $e$ in
-the following term, where $x$ is a fresh variable and each $ps_i$ is a
-parameter section consisting of parameters with fresh names of types $Ts_i$.
-
-\begin{verbatim}
-(val $x$ = $e$ ; $(ps_1) \ldots \Arrow \ldots \Arrow (ps_n) \Arrow x;(ps_1);\ldots;(ps_n)$)
-\end{verbatim}
-This conversion is not applicable to functions with call-by-name
-parameters (\sref{sec:parameters}) of type $[]T$, because its result
-would violate the well-formedness rules for anonymous functions
-(\sref{sec:closures}). Hence, methods with call-by-name
-parameters always need to be applied to arguments immediately.
-\end{itemize}
-
-\chapter{Basic Declarations and Definitions}
-\label{sec:defs}
-
-\syntax\begin{verbatim}
- Dcl \=::=\= val ValDcl {`,' ValDcl}
- \> |\> var VarDcl {`,' VarDcl}
- \> |\> def FunDcl {`,' FunDcl}
- \> |\> type TypeDcl {`,' TypeDcl}
- Def \>::=\> val PatDef {`,' PatDef}
- \> |\> var VarDef {`,' VarDef}
- \> |\> def FunDef {`,' FunDef}
- \> |\> type TypeDef {`,' TypeDef}
- \> |\> ClsDef
-\end{verbatim}
-
-A {\em declaration} introduces names and assigns them types. It can
-appear as one of the statements of a class definition
-(\sref{sec:templates}) or as part of a refinement in a compound
-type (\sref{sec:refinements}).
-
-A {\em definition} introduces names that denote terms or types. It can
-form part of an object or class definition or it can be local to a
-block. Both declarations and definitions produce {\em bindings} that
-associate type names with type definitions or bounds, and that
-associate term names with types.
-
-The scope of a name introduced by a declaration or definition is the
-whole statement sequence containing the binding. However, there is a
-restriction on forward references: In a statement sequence $s_1 \ldots
-s_n$, if a simple name in $s_i$ refers to an entity defined by $s_j$
-where $j \geq i$, then every non-empty statement between and including
-$s_i$ and $s_j$ must be an import clause,
-or a function, type, class, or object definition.
-
-\comment{
-Every basic definition may introduce several defined names, separated
-by commas. These are expanded according to the following scheme:
-\bda{lcl}
-\VAL;x, y: T = e && \VAL; x: T = e \\
- && \VAL; y: T = x \\[0.5em]
-
-\LET;x, y: T = e && \LET; x: T = e \\
- && \VAL; y: T = x \\[0.5em]
-
-\DEF;x, y (ps): T = e &\tab\mbox{expands to}\tab& \DEF; x(ps): T = e \\
- && \DEF; y(ps): T = x(ps)\\[0.5em]
-
-\VAR;x, y: T := e && \VAR;x: T := e\\
- && \VAR;y: T := x\\[0.5em]
-
-\TYPE;t,u = T && \TYPE; t = T\\
- && \TYPE; u = t\\[0.5em]
-\eda
-}
-
-All definitions have a ``repeated form'' where the initial
-definition keyword is followed by several constituent definitions
-which are separated by commas. A repeated definition is
-always interpreted as a sequence formed from the
-constituent definitions. E.g.\ the function definition
-\verb@def f(x) = x, g(y) = y@ expands to
-\verb@def f(x) = x; def g(y) = y@ and
-the type definition
-\verb@type T$_1$, T$_2$ <: B$_2$@ expands to
-\verb@type T$_1$; type T$_2$ <: B$_2$@.
-
-\section{Value Declarations and Definitions}
-\label{sec:valdef}
-
-\syntax\begin{verbatim}
- Dcl \=::= \= val ValDcl {`,' ValDcl}
- ValDcl \>::= \> id `:' Type
- Def \>::= \> val PatDef {`,' PatDef}
- PatDef \>::= \> Pattern `=' Expr
-\end{verbatim}
-
-A value declaration \verb@val x: T@ introduces \verb@x@ as a name of a value of
-type \verb@T@.
-
-A value definition \verb@val x: T = e@ defines $x$ as a name of the
-value that results from the evaluation of $e$. The type $T$ may be
-omitted, in which case the type of expression $e$ is assumed.
-If a type $T$ is given, then $e$ is expected to conform to it.
-
-Evaluation of the value definition implies evaluation of its
-right-hand side $e$. The effect of the value definition is to bind
-$x$ to the value of $e$ converted to type $T$.
-
-Value definitions can alternatively have a pattern
-(\sref{sec:patterns}) as left-hand side. If $p$ is some pattern other
-than a simple name or a name followed by a colon and a type, then the
-value definition \verb@val p = e@ is expanded as follows:
-
-1. If the pattern $p$ has bound variables $x_1 \commadots x_n$, where $n > 1$:
-\begin{verbatim}
-val $\Dollar$x = e.match {case p => scala.Tuple$\,n$(x$_1$, ..., x$_n$)}
-val x$_1$ = $\Dollar$x._1
-...
-val x$_n$ = $\Dollar$x._n .
-\end{verbatim}
-Here, \verb@$\Dollar$x@ is a fresh name. The class
-\verb@Tuple$\,n$@ is defined for $n = 2,...,9$ in package
-\verb@scala@.
-
-2. If $p$ has a unique bound variable $x$:
-\begin{verbatim}
-val x = e.match { case p => x }
-\end{verbatim}
-
-3. If $p$ has no bound variables:
-\begin{verbatim}
-e.match { case p => ()}
-\end{verbatim}
-
-\example
-The following are examples of value definitions
-\begin{verbatim}
-val pi = 3.1415;
-val pi: double = 3.1415; \=// equivalent to first definition
-val Some(x) = f(); \>// a pattern definition
-val x :: xs = mylist; \>// an infix pattern definition
-\end{verbatim}
-
-The last two definitions have the following expansions.
-\begin{verbatim}
-val x = f().match { case Some(x) => x }
-
-val x$\Dollar$ = mylist.match { case x :: xs => scala.Tuple2(x, xs) }
-val x = x$\Dollar$._1;
-val xs = x$\Dollar$._2;
-
-\end{verbatim}
-
-\section{Variable Declarations and Definitions}
-\label{sec:vardef}
-
-\syntax\begin{verbatim}
- Dcl \=::= \= var VarDcl {`,' VarDcl}
- Def \>::= \> var ValDef {`,' ValDef}
- VarDcl \>::=\> id `:' Type
- VarDef \>::=\> id [`:' Type] `=' Expr
- \> |\> id `:' Type `=' `_'
-\end{verbatim}
-
-A variable declaration \verb@var x: T@ is equivalent to declarations
-of a {\em getter function} \verb@x@ and a {\em setter function}
-\verb@x_=@, defined as follows:
-
-\begin{verbatim}
- def x: T;
- def x_= (y: T): unit
-\end{verbatim}
-
-An implementation of a class containing variable declarations
-may define these variables using variable definitions, or it may
-define setter and getter functions directly.
-
-A variable definition \verb@var x: T = e@ introduces a mutable
-variable with type \verb@T@ and initial value as given by the
-expression \verb@e@. The type $T$ can be omitted,
-in which case the type of $e$ is assumed. If $T$ is given, then \verb@e@
-is expected to conform to it.
-
-A variable definition \verb@var x: T = _@ introduces a mutable
-variable with type \verb@T@ and a default initial value.
-The default value depends on the type \verb@T@ as follows:
-\begin{quote}\begin{tabular}{ll}
-\verb@0@ & if $T$ is \verb@int@ or one of its subrange types, \\
-\verb@0L@ & if $T$ is \verb@long@,\\
-\verb@0.0f@ & if $T$ is \verb@float@,\\
-\verb@0.0d@ & if $T$ is \verb@double@,\\
-\verb@false@ & if $T$ is \verb@boolean@,\\
-\verb@()@ & if $T$ is \verb@unit@, \\
-\verb@null@ & for all other types $T$.
-\end{tabular}\end{quote}
-
-When they occur as members of a template, both forms of variable
-definition also introduce a getter function \verb@x@ which returns the
-value currently assigned to the variable, as well as a setter function
-\verb@x_=@ which changes the value currently assigned to the variable.
-The functions have the same signatures as for a variable declaration.
-The getter and setter functions, are then members of the template
-instead of the variable accessed by them.
-
-\example The following example shows how {\em properties} can be
-simulated in Scala. It defines a class \verb@TimeOfDayVar@ of time
-values with updatable integer fields representing hours, minutes, and
-seconds. Its implementation contains tests that allow only legal
-values to be assigned to these fields. The user code, on the other
-hand, accesses these fields just like normal variables.
-
-\begin{verbatim}
-class TimeOfDayVar {
- private var h: int = 0, m: int = 0, s: int = 0;
- def hours \== h;
- def hours_= (h: int) \>= \=if (0 <= h && h < 24) this.h = h
- \> \>else new DateError().throw;
- def minutes \>= m
- def minutes_= (m: int) \>= if (0 <= m && m < 60) this.m = m
- \> \>else new DateError().throw;
- def seconds \>= s
- def seconds_= (s: int) \>= if (0 <= s && s < 60) this.s = s
- \> \>else new DateError().throw;
-}
-val t = new TimeOfDayVar;
-d.hours = 8; d.minutes = 30; d.seconds = 0;
-d.hours = 25; \=// throws a DateError exception
-\end{verbatim}
-
-\section{Type Declarations and Type Aliases}
-\label{sec:typedcl}
-\label{sec:typealias}
-
-\syntax\begin{verbatim}
- Dcl \=::= \= type TypeDcl {`,' TypeDcl}
- TypeDcl \>::= \> id [>: Type] [<: Type]
- Def \>::= \> type TypeDef {`,' TypeDef}
- TypeDef \>::= \> id [TypeParamClause] `=' Type
-\end{verbatim}
-
-A {\em type declaration} \verb@type t >: L <: U@ declares \verb@t@ to
-be an abstract type with lower bound type \verb@L@ and upper bound
-type \verb@U@. If such a declaration appears as a member declaration
-of a type, implementations of the type may implement \verb@t@ with any
-type \verb@T@ for which \verb@L <: T <: U@. Either or both bounds may
-be omitted. If the lower bound \verb@L@ is missing, the bottom type
-\verb@scala.All@ is assumed. If the upper bound \verb@U@ is missing,
-the top type \verb@scala.Any@ is assumed.
-
-A {\em type alias} \verb@type t = T@ defines \verb@t@ to be an alias
-name for the type \verb@T@. The left hand side of a type alias may
-have a type parameter clause, e.g. \verb@type t[tps] = T@. The scope
-of a type parameter extends over the right hand side \verb@T@ and the
-type parameter clause \verb@tps@ itself.
-
-The scope rules for definitions (\sref{sec:defs}) and type parameters
-(\sref{sec:funsigs}) make it possible that a type name appears in its
-own bound or in its right-hand side. However, it is a static error if
-a type alias refers recursively to the defined type constructor itself.
-That is, the type \verb@T@ in a type alias \verb@type t[tps] = T@ may not refer
-directly or indirectly to the name \verb@t@. It is also an error if
-an abstract type is directly or indirectly its own bound.
-
-\example The following are legal type declarations and definitions:
-\begin{verbatim}
-type IntList = List[Integer];
-type T <: Comparable[T];
-type Two[a] = Tuple2[a, a];
-\end{verbatim}
-
-The following are illegal:
-\begin{verbatim}
-type Abs = Comparable[Abs]; \=// recursive type alias
-
-type S <: T; \>// S, T are bounded by themselves.
-type T <: S;
-
-type T <: Object with T; \>// T is abstract, may not be part of
- \>// compound type
-
-type T >: Comparable[T.That]; \>// Cannot select from T.
- \>// T is a type, not a value
-\end{verbatim}
-
-If a type alias \verb@type t[tps] = S@ refers to a class type
-\verb@S@, the name \verb@t@ can also be used as a constructor for
-objects of type \verb@S@.
-
-\example The \verb@Predef@ module contains a definition which establishes \verb@Pair@
-as an alias of the parameterized class \verb@Tuple2@:
-\begin{verbatim}
-type Pair[+a, +b] = Tuple2[a, b];
-\end{verbatim}
-As a consequence, for any two types \verb@S@ and \verb@T@, the type
-\verb@Pair[S, T]@ is equivalent to the type \verb@Tuple2[S, T]@.
-\verb@Pair@ can also be used as a constructor instead of \verb@Tuple2@, as in
-\begin{verbatim}
-new Pair[Int, Int](1, 2) .
-\end{verbatim}
-
-\section{Type Parameters}
-
-\syntax\begin{verbatim}
- TypeParamClause \=::=\= `[' TypeParam {`,' TypeParam} `]'
- TypeParam \>::=\> [`+' | `-'] TypeDcl
-\end{verbatim}
-
-\newcommand{\plusminus}{\oplus}
-
-Type parameters appear in type definitions, class definitions, and
-function definitions. The most general form of a type parameter is
-\verb@$\plusminus$ t >: L <: U@. Here, \verb@L@, and \verb@U@ are lower
-and upper bounds that constrain possible type arguments for the
-parameter. $\plusminus$ is a {\em variance}, i.e.\ an optional prefix
-of either \verb@+@, or \verb@-@.
-
-The names of all type parameters in a type parameter clause must be
-pairwise different. The scope of a type parameter includes in each
-case the whole type parameter clause. Therefore it is possible that a
-type parameter appears as part of its own bounds or the bounds of
-other type parameters in the same clause. However, a type parameter
-may not be bounded directly or indirectly by itself.
-
-\example Here are some well-formed type parameter clauses:
-\begin{verbatim}
-[s, t]
-[ex <: Throwable]
-[a <: Ord[b], b <: a]
-[a, b, c >: a <: b]
-\end{verbatim}
-The following type parameter clauses since some type parameter is bounded by itself.
-\begin{verbatim}
-[a >: a]
-[a <: b, b <: c, c <: a]
-\end{verbatim}
-
-Variance annotations indicate how type instances with the given type
-parameters vary with respect to subtyping (\sref{sec:subtyping}). A
-`\verb@+@' variance indicates a covariant dependency, a `\verb@-@'
-variance indicates a contravariant dependency, and a missing variance
-indication indicates an invariant dependency.
-
-A variance annotation constrains the way the annotated type variable
-may appear in the type or class which binds the type parameter. In a
-type definition \verb@type t[tps] = S@, type parameters labeled
-`\verb@+@' must only appear in covariant position in \verb@S@ whereas
-type parameters labeled `\verb@-@' must only appear in contravariant
-position. Analogously, for a class definition
-\verb@class c[tps](ps): s extends t@, type parameters labeled
-`\verb@+@' must only appear in covariant position in the self type
-\verb@s@ and the type of the template \verb@t@, whereas type
-parameters labeled `\verb@-@' must only appear in contravariant
-position.
-
-The variance position of a type parameter of a type is defined as
-follows. Let the opposite of covariance be contravariance, and the
-opposite of invariance be itself. The top-level of a type is always
-in covariant position. The variance position changes at the following
-constructs.
-\begin{itemize}
-\item
-The variance position of method parameter is the opposite of the
-variance position of the enclosing parameter clause.
-\item
-The variance position of a type parameter is the opposite of the
-variance position of the enclosing type parameter clause.
-\item
-The variance position of the lower bound of a type declaration or type parameter
-is the opposite of the variance position of the type declaration or parameter.
-\item
-The right hand side \verb@S@ of a type alias \verb@type t[tps] = S@
-is always in invariant position.
-\item
-The type of a mutable variable is always in invariant position.
-\item
-The prefix \verb@S@ of a type selection \verb@S#T@ is always in invariant position.
-\item
-For a type argument \verb@T@ of a type \verb@S[... T ... ]@: If the
-corresponding type parameter is invariant, then \verb@T@ is in
-invariant position. If the corresponding type parameter is
-contravariant, the variance position of \verb@T@ is the opposite of
-the variance position of the enclosing type \verb@S[... T ... ]@.
-\end{itemize}
-
-\example The following variance annotation is legal.
-\begin{verbatim}
-class P[a, b] {
- val fst: a, snd: b
-}\end{verbatim}
-With this variance annotation, elements
-of type \verb@P@ subtype covariantly with respect to their arguments.
-For instance, \verb@P[IOExeption, String] <: P[Throwable, Object]@.
-
-If we make the elements of \verb@P@ mutable,
-the variance annotation becomes illegal.
-\begin{verbatim}
-class Q[+a, +b] {
- var fst: a, snd: b // **** error: illegal variance: `a', `b' occur in invariant position.
-}
-\end{verbatim}
-
-\example The following variance annotation is illegal, since \verb@a@ appears
-in contravariant position in the parameter of \verb@append@:
-
-\begin{verbatim}
-trait Vector[+a] {
- def append(x: Vector[a]): Vector[a]; // **** error: illegal variance: `a' occurs in contravariant position.
-}
-\end{verbatim}
-The problem can be avoided by generalizing the type of \verb@append@
-by means of a lower bound:
-
-\begin{verbatim}
-trait Vector[+a] {
- def append[b >: a](x: Vector[b]): Vector[b];
-}
-\end{verbatim}
-
-\example Here is a case where a contravariant type parameter is useful.
-
-\begin{verbatim}
-trait OutputChannel[-a] {
- def write(x: a): unit
-}
-\end{verbatim}
-With that annotation, we have
-\verb@OutputChannel[Object] <: OutputChannel[String]@. That is, a
-channel on which one can write any object can substitute for a channel
-on which one can write only strings.
-
-\section{Function Declarations and Definitions}
-\label{sec:defdef}
-\label{sec:funsigs}
-
-\syntax\begin{verbatim}
-Dcl \=::= \= def FunDcl {`,' FunDcl}
-FunDcl \>::= \> id [FunTypeParamClause] {ParamClause} `:' Type
-Def \>::= \> def FunDef {`,' FunDef}
-FunDef \>::= \> id [FunTypeParamClause] {ParamClause} [`:' Type]
- \> \> `=' Expr
-FunTypeParamClause \>::=\> `[' TypeDcl {`,' TypeDcl} `]'
-ParamClause \>::=\> `(' [Param {`,' Param}] `)'
-Param \>::= \> [def] id `:' Type [*]
-\end{verbatim}
-
-A function declaration has the form \verb@def f psig: T@, where
-\verb@f@ is the function's name, \verb@psig@ is its parameter
-signature and \verb@T@ is its result type. A function definition
-\verb@f psig:T = e@ also includes a {\em function body} \verb@e@,
-i.e.\ an expression which defines the function's result. A parameter
-signature consists of an optional type parameter clause \verb@[tps]@,
-followed by zero or more value parameter clauses
-\verb@(ps$_1$) ... (ps$_n$)@. Such a declaration or definition
-introduces a value with a (possibly polymorphic) method type whose
-parameter types and result type are as given.
-
-A type parameter clause \verb@tps@ consists of one or more type
-declarations (\sref{sec:typedcl}), which introduce type parameters,
-possibly with bounds. The scope of a type parameter includes
-the whole signature, including any of the type parameter bounds as
-well as the function body, if it is present.
-
-A value parameter clause \verb@ps@ consists of zero or more formal
-parameter bindings such as \verb@x: T@, which bind value
-parameters and associate them with their types. The scope of a formal
-value parameter name \verb@x@ is the function body, if one is
-given. Both type parameter names and value parameter names must be
-pairwise distinct.
-
-Value parameters may be prefixed by \verb@def@, e.g.\
-\verb@def x:T@. The type of such a parameter is then the
-parameterless method type \verb@[]T@. This indicates that the
-corresponding argument is not evaluated at the point of function
-application, but instead is evaluated at each use within the
-function. That is, the argument is evaluated using {\em call-by-name}.
-
-\example The declaration
-\begin{verbatim}
-def whileLoop (def cond: Boolean) (def stat: Unit): Unit
-\end{verbatim}
-produces the typing
-\begin{verbatim}
-whileLoop: (cond: [] Boolean) (stat: [] Unit) Unit
-\end{verbatim}
-which indicates that both parameters of \verb@while@ are evaluated using
-call-by-name.
-
-The type of the function body must conform to the function's declared
-result type, if one is given. If the function definition is not
-recursive, the result type may be omitted, in which case it is
-determined from the type of the function body.
-
-\section{Overloaded Definitions}
-\label{sec:overloaded-defs}
-\todo{change}
-
-An overloaded definition is a set of \verb@n > 1@ value or function
-definitions in the same statement sequence that define the same name,
-binding it to types \verb@T_1, ..., T_n@, respectively. The
-individual definitions are called {\em alternatives}. Alternatives
-always need to specify the type of the defined entity completely. All
-alternatives must have the same modifiers. It is an error if the types
-of two alternatives \verb@T$_i$@ and \verb@T$_j$@ have the same
-erasure (\sref{sec:erasure}). An overloaded definition defines a
-single entity, of type \verb@T_1 $\overload$ ... $\overload$ T_n@
-(\sref{sec:overloaded-types}).
-
-\todo{Say something about bridge methods.}
-%This must be a well-formed
-%overloaded type
-
-\section{Import Clauses}
-\label{sec:import}
-
-\syntax\begin{verbatim}
- Import \=::=\= import ImportExpr {`,' ImportExpr}
- ImportExpr \>::=\> StableId `.' (id | `_' | ImportSelectors)
- ImportSelectors \>::=\> `{' {ImportSelector `,'} (ImportSelector | `_') `}'
- ImportSelector \>::=\> id [`=>' id | `=>' `_']
-\end{verbatim}
-
-An import clause has the form \verb@import p.I@ where \verb@p@ is a stable
-identifier (\sref{sec:paths}) and \verb@I@ is an import expression.
-The import expression determines a set of names of members of \verb@p@
-which are made available without qualification. The most general form
-of an import expression is a list of {\em import selectors}
-\begin{verbatim}
-{ x$_1$ => y$_1$, ..., x$_n$ => y$_n$, _ }
-\end{verbatim}
-for $n \geq 0$, where the final wildcard `\verb@_@' may be absent. It
-makes available each member \verb@p.x$_i$@ under the unqualified name
-\verb@y$_i$@. I.e.\ every import selector \verb@x$_i$ => y$_i$@ renames
-\verb@p.x$_i$@ to
-\verb@y$_i$@. If a final wildcard is present, all members \verb@z@ of
-\verb@p@ other than \verb@x$_1$, ..., x$_n$@ are also made available
-under their own unqualified names.
-
-Import selectors work in the same way for type and term members. For
-instance, an import clause \verb@import p.{x => y}@ renames the term
-name \verb@p.x@ to the term name \verb@y@ and the type name \verb@p.x@
-to the type name \verb@y@. At least one of these two names must
-reference a member of \verb@p@.
-
-If the target in an import selector is a wildcard, the import selector
-hides access to the source member. For instance, the import selector
-\verb@x => _@ ``renames'' \verb@x@ to the wildcard symbol (which is
-unaccessible as a name in user programs), and thereby effectively
-prevents unqualified access to \verb@x@. This is useful if there is a
-final wildcard in the same import selector list, which imports all
-members not mentioned in previous import selectors.
-
-Several shorthands exist. An import selector may be just a simple name
-\verb@x@. In this case, \verb@x@ is imported without renaming, so the
-import selector is equivalent to \verb@x => x@. Furthermore, it is
-possible to replace the whole import selector list by a single
-identifier or wildcard. The import clause \verb@import p.x@ is
-equivalent to \verb@import p.{x}@, i.e.\ it makes available without
-qualification the member \verb@x@ of \verb@p@. The import clause
-\verb@import p._@ is equivalent to
-\verb@import p.{_}@,
-i.e.\ it makes available without qualification all members of \verb@p@
-(this is analogous to \verb@import p.*@ in Java).
-
-An import clause with multiple import expressions
-\verb@import p$_1$.I$_1$, ..., p$_n$.I$_n$@ is interpreted as a
-sequence of import clauses
-\verb@import p$_1$.I$_1$; ..., import p$_n$.I$_n$@.
-
-\example Consider the object definition:
-\begin{verbatim}
-object M {
- def z = 0, one = 1;
- def add(x: Int, y: Int): Int = x + y
-}
-\end{verbatim}
-Then the block
-\begin{verbatim}
-{ import M.{one, z => zero, _}; add(zero, one) }
-\end{verbatim}
-is equivalent to the block
-\begin{verbatim}
-{ M.add(M.z, M.one) } .
-\end{verbatim}
-
-\chapter{Classes and Objects}
-\label{sec:globaldefs}
-
-\syntax\begin{verbatim}
- ClsDef \=::=\= ([case] class | trait) ClassDef {`,' ClassDef}
- \> |\> [case] object ObjectDef {`,' ObjectDef}
-\end{verbatim}
-
-Classes (\sref{sec:classes}) and objects
-(\sref{sec:modules}) are both defined in terms of {\em templates}.
-
-\section{Templates}
-\label{sec:templates}
-
-\syntax\begin{verbatim}
- Template \=::=\= Constr {`with' Constr} [TemplateBody]
- TemplateBody \>::=\> `{' [TemplateStat {`;' TemplateStat}] `}'
-\end{verbatim}
-
-A template defines the type signature, behavior and initial state of a
-class of objects or of a single object. Templates form part of
-instance creation expressions, class definitions, and object
-definitions. A template
-\verb@sc with mc$_1$ with ... with mc$_n$ {stats}@ consists of a
-constructor invocation \verb@sc@ which defines the template's {\em
-superclass}, constructor invocations \verb@mc$_1$, ..., mc$_n$@
-$(n \geq 0)$, which define the template's {\em mixin classes}, and a
-statement sequence \verb@stats@ which contains additional member
-definitions for the template. Superclass and mixin classes together
-are called the {\em parent classes} of a template. The superclass of
-a template must be a subtype of the superclass of each mixin class.
-The {\em least proper supertype} of a template is the class type or
-compound type (\sref{sec:compound-types}) consisting of the its parent classes.
-
-Member definitions define new members or overwrite members in the
-parent classes. If the template forms part of a class definition,
-the statement part \verb@stats@ may also contain declarations of abstract members.
-%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.
-
-\todo{Make all references to Java generic}
-
-\paragraph{Inheriting from Java Types} A template may have a Java class as
-its superclass and Java interfaces as its mixin classes. On the other
-hand, it is not permitted to have a Java class as a mixin class, or a
-Java interface as a superclass.
-
-\subsection{Constructor Invocations}
-\label{sec:constr-invoke}
-\syntax\begin{verbatim}
- Constr \=::= \= StableId [TypeArgs] [`(' [Exprs] `)']
-\end{verbatim}
-
-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
-\verb@x.c(args)@, where \verb@x@ is a stable identifier
-(\sref{sec:stable-ids}), \verb@c@ is a type name which either
-designates a class or defines an alias type for one, and \verb@(args)@
-is an argument list, which matches one of the constructors of that
-class. The prefix `\verb@x.@' can be omitted.
-%The class \verb@c@ must conform to \verb@scala.AnyRef@,
-%i.e.\ it may not be a value type.
-The argument list \verb@(args)@ can also be omitted, in which case an
-empty argument list \verb@()@ is implicitly added.
-
-\subsection{Base Classes}
-\label{sec:base-classes}
-
-For every template, class type and constructor invocation we define two
-sequences of class types: the {\em base classes} and {\em mixin base
-classes}. Their definitions are as follows.
-
-The {\em mixin base classes} of a template
-\verb@sc with mc$_1$ with ... with mc$_n$ {stats}@ are obtained by
-concatenating, for each $i = 1 \commadots n$, the mixin base classes
-of the mixin \verb@mc_i@. The mixin base classes of a class type \verb@C@ are
-the mixin base classes of the template represented by \verb@C@, followed by
-\verb@C@ itself. The mixin base classes of a constructor invocation of type
-\verb@T@ are the mixin base classes of class \verb@T@.
-
-The {\em base classes} of a template consist of the base classes of
-its superclass, followed by the template's mixin base classes. The
-base classes of class \verb@scala.Any@ consist of just the
-class itself. The base classes of some other class type \verb@C@ are the
-base classes of the template represented by \verb@C@, followed by \verb@C@
-itself. The base classes of a constructor invocation of type \verb@T@
-are the base classes of \verb@T@.
-
-The notions of mixin base classes and base classes are extended from
-classes to arbitrary types following the definitions of
-\sref{sec:base-classes}.
-
-If two types in the base class sequence of a template refer to the
-same class definition, then that definition must define a trait
-(\sref{sec:traits}), and the type that comes later in the sequence must
-conform to the type that comes first.
-(\sref{sec:case-classes}).
-
-\subsection{Evaluation}
-
-The evaluation of a template or constructor invocation depends on
-whether the template defines an object or is a superclass of a
-constructed object, or whether it is used as a mixin for a defined
-object. In the second case, the evaluation of a template used as a
-mixin depends on an {\em actual superclass}, which is known at the
-point where the template is used in a definition of an object, but not
-at the point where it is defined. The actual superclass is used in the
-determination of the meaning of \verb@super@ (\sref{sec:this-super}).
-
-We therefore define two notions of template evaluation: (Plain)
-evaluation (as a defining template or superclass) and mixin evaluation
-with a given superclass \verb@sc@. These notions are defined for templates
-and constructor invocations as follows.
-
-A {\em mixin evaluation with superclass \verb@sc@} of a template
-\verb@sc' with mc$_1$ with mc$_n$ with {stats}@ consists of mixin
-evaluations with superclass \verb@sc@ of the mixin constructor invocations
-\verb@mc$_1$, ..., mc$_n$@ in the order they are given, followed by an
-evaluation of the statement sequence \verb@stats@. Within \verb@stats@ the
-actual superclass refers to \verb@sc@. A mixin evaluation with superclass
-\verb@sc@ of a class constructor invocation \verb@ci@ consists of an evaluation
-of the constructor function and its arguments in the order they are
-given, followed by a mixin evaluation with superclass \verb@sc@ of the
-template represented by the constructor invocation.
-
-An {\em evaluation} of a template
-\verb@sc with mc$_1$ with mc$_n$ with (stats)@ consists of an evaluation of
-the superclass constructor invocation \verb@sc@,
-followed by a mixin evaluation with superclass \verb@sc@ of the template. An
-evaluation of a class constructor invocation \verb@ci@ consists of an
-evaluation of the constructor function and its arguments in
-the order they are given, followed by an evaluation of the template
-represented by the constructor invocation.
-
-\subsection{Template Members}
-
-\label{sec:members}
-
-The object resulting from evaluation of a template has directly bound
-members and inherited members. Members can be abstract or concrete.
-These are defined as follows.
-\begin{enumerate}
-\item
-A {\em directly bound} member is an entity introduced by a member
-definition or declaration in the template's statement sequence. The
-member is called {\em abstract} if it is introduced by a declaration,
-{\em concrete} otherwise.
-\item
-A {\em concrete inherited} member is a non-private, concrete member of
-one of the template's base classes \verb@B@, except if a member with the
-same \ifqualified{qualified} name is already directly bound in the template, or is
-directly bound in a base class of the template which is a subclass of
-\verb@B@, or is a directly bound, non-private, concrete member of a base
-class which succeeds \verb@B@ in the base class sequence of the template.
-\item
-An {\em abstract inherited} member is a non-private, abstract member
-of one of the template's base classes \verb@B@, except if a member with the
-same \ifqualified{qualified} name is already directly bound in the template, or is a
-concrete inherited member, or is a directly bound, non-private member
-of a base class which succeeds \verb@b@ in the base class sequence of the
-template.
-\end{enumerate}
-
-If two mixin classes of a template each have a concrete member
-with the same name, then the template itself must also declare or
-define a member with the same name.
-
-\comment{
-The type of a member \verb@m@ is determined as follows: If \verb@m@ is defined
-in \verb@stats@, then its type is the type as given in the member's
-declaration or definition. Otherwise, if \verb@m@ is inherited from the
-base class \verb@B[T1, .... T_n]@, \verb@B@'s class declaration has formal
-parameters \verb@[a_1, ..., a_n]@, and \verb@M@'s type in \verb@B@ is \verb@U@, then
-\verb@M@'s type in \verb@C@ is \verb@U[a_1 := T_1, ..., 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 \verb@override $Q$@\nyi{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 \verb@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 \verb@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 \verb@override@ modifier is given or implied, then if $M$ is
-labeled \verb@qualified@, the qualified name is $M\qex x$. If $M$ is
-not labeled \verb@qualified@, the qualified name is $\epsilon\qex x$.
-\end{enumerate}
-}
-}
-
-\example Consider the class definitions
-
-\begin{verbatim}
-class A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 }
-abstract class B { def f: Int = 4 ; def g: Int }
-abstract class C extends A with B { def h: Int }
-\end{verbatim}
-
-Then class \verb@C@ has a directly bound abstract member \verb@h@. It
-inherits member \verb@f@ from class \verb@B@ and member \verb@g@ from
-class \verb@A@.
-
-\ifqualified{
-\example\label{ex:compound-b}
-Consider the definitions:
-\begin{verbatim}
-qualified class Root extends Any with { def r1: Root, r2: Int }
-qualified class A extends Root with { def r1: A, a: String }
-qualified class B extends A with { def r1: B, b: Double }
-\end{verbatim}
-Then \verb@A with B@ has members
-\verb@Root::r1@ of type \verb@B@, \verb@Root::r2@ of type \verb@Int@,
-\verb@A::a:@ of type \verb@String@, and \verb@B::b@ of type \verb@Double@,
-in addition to the members inherited from class \verb@Any@.
-}
-
-\subsection{Overriding}
-\label{sec:overriding}
-
-A template member \verb@M@ that has the same \ifqualified{qualified}
-name as a non-private member \verb@M'@ of a base class (and that
-belongs to the same namespace) is said to {\em override} that member.
-In this case the binding of the overriding member \verb@M@ must be
-more specific (\sref{sec:subtyping}) than the binding of the
-overridden member \verb@M'@. Furthermore, the overridden definition
-may not be a class definition. Method definitions may only override
-other method definitions (or the methods implicitly defined by a
-variable definition). They may not override value let definitions.
-Finally, the following restrictions on modifiers apply to \verb@M@ and
-\verb@M'@:
-\begin{itemize}
-\item
-\verb@M'@ must not be labeled \verb@final@.
-\item
-\verb@M@ must not be labeled \verb@private@.
-\item
-If \verb@M@ is labeled \verb@protected@, then \verb@M'@ must also be
-labeled \verb@protected@.
-\item
-If \verb@M'@ is not an abstract member, then
-\verb@M@ must be labeled \verb@override@.
-\end{itemize}
-
-\example\label{ex:compound-a}
-Consider the definitions:
-\begin{verbatim}
-trait Root with { type T <: Root }
-trait A extends Root with { type T <: A }
-trait B extends Root with { type T <: B }
-trait C extends A with B;
-\end{verbatim}
-Then the trait definition \verb@C@ is not well-formed because the
-binding of \verb@T@ in \verb@C@ is
-\verb@type T extends B@,
-which fails to be more specific than the binding of same name in type
-\verb@A@. The problem can be solved by adding an overriding
-definition of type \verb@T@ in class \verb@C@:
-\begin{verbatim}
-class C extends A with B { type T <: C }
-\end{verbatim}
-
-\subsection{Modifiers}
-\label{sec:modifiers}
-
-\syntax\begin{verbatim}
- Modifier \=::=\= LocalModifier
- \> |\> private
- \> |\> protected
- \> |\> override
- LocalModifier \>::=\> abstract
- \> |\> final
- \> |\> sealed
-\end{verbatim}
-
-Member definitions may be preceded by modifiers which affect the
-\ifqualified{qualified names, }accessibility and usage of the
-identifiers bound by them. If several modifiers are given, their
-order does not matter, but the same modifier may not occur repeatedly.
-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 \verb@private@ modifier can be used with any definition in a
-template. Private members can be accessed only from within the template
-that defines them.
-%Furthermore, accesses are not permitted in
-%packagings (\sref{sec:topdefs}) other than the one containing the
-%definition.
-Private members are not inherited by subclasses and they
-may not override definitions in parent classes.
-\verb@private@ may not be applied to abstract members, and it
-may not be combined in one modifier list with
-\verb@protected@, \verb@final@ or \verb@override@.
-\item
-The \verb@protected@ modifier applies to class member definitions.
-Protected members can be accessed from within the template of the defining
-class as well as in all templates that have the defining class as a base class.
-%Furthermore, accesses from the template of the defining class are not
-%permitted in packagings other than the one
-%containing the definition.
-A protected identifier \verb@x@ may be used as
-a member name in a selection \verb@r.x@ only if \verb@r@ is one of the reserved
-words \verb@this@ and
-\verb@super@, or if \verb@r@'s type conforms to a type-instance of the class
-which contains the access.
-\item
-The \verb@override@ modifier applies to class member definitions. It
-is mandatory for member definitions that override some other
-non-abstract member definition in a super- or mixin-class. If an
-\verb@override@ modifier is given, there must be at least one
-overridden member definition. Furthermore, the overridden definition
-must be concrete (\sref{sec:members}), unless the class containing the
-overriding member is abstract.
-\item
-The \verb@abstract@ modifier is used in class definitions. It is
-mandatory if the class has abstract members, or if the class has
-members labeled \verb@override@ which override only abstract members
-in a parent class. Classes with \verb@abstract@ members
-cannot be instantiated (\sref{sec:inst-creation}) with a constructor
-invocation unless followed by mixin constructors or statements which
-override all abstract members of the class.
-\item
-The \verb@final@ modifier applies to class member definitions and to
-class definitions. A \verb@final@ class member definition may not be
-overridden in subclasses. A \verb@final@ class may not be inherited by
-a template. \verb@final@ is redundant for object definitions. Members
-of final classes or objects are implicitly also final, so the
-\verb@final@ modifier is redundant for them, too. \verb@final@ may
-not be applied to abstract members, and it may not be combined in one
-modifier list with \verb@private@ or \verb@sealed@.
-\item
-The \verb@sealed@ modifier applies to class definitions. A
-\verb@sealed@ class may not be inherited, except if either
-\begin{itemize}
-\item
-the inheriting template is nested within the definition of the sealed
-class itself, or
-\item
-the inheriting template belongs to a class or object definition which
-forms part of the same statement sequence as the definition of the
-sealed class.
-\end{itemize}
-\end{itemize}
-
-\example A useful idiom to prevent clients of a class from
-constructing new instances of that class is to declare the class
-\verb@abstract@ and \verb@sealed@:
-
-\begin{verbatim}
-object m {
- abstract sealed class C (x: Int) {
- def nextC = C(x + 1) with {}
- }
- val empty = new C(0) {}
-}
-\end{verbatim}
-For instance, in the code above clients can create instances of class
-\verb@m.C@ only by calling the \verb@nextC@ method of an existing \verb@m.C@
-object; it is not possible for clients to create objects of class
-\verb@m.C@ directly. Indeed the following two lines are both in error:
-
-\begin{verbatim}
- m.C(0) \=// **** error: C is abstract, so it cannot be instantiated.
- m.C(0) {} \>// **** error: illegal inheritance from sealed class.
-\end{verbatim}
-
-\section{Class Definitions}
-\label{sec:classes}
-
-\syntax\begin{verbatim}
- ClsDef \=::=\= class ClassDef {`,' ClassDef}
- ClassDef \>::=\> id [TypeParamClause] [ParamClause] [`:' SimpleType]
- \> \> ClassTemplate
- ClassTemplate \>::=\> extends Template
- \> |\> TemplateBody
- \> |\>
-\end{verbatim}
-
-The most general form of class definition is
-\verb@class c[tps](ps): s extends t@.
-Here,
-\begin{itemize}
-\item[]
-\verb@c@ is the name of the class to be defined.
-\item[] \verb@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 \verb@[tps]@ may be omitted. A class with a type
-parameter section is called {\em polymorphic}, otherwise it is called
-{\em monomorphic}.
-\item[]
-\verb@ps@ is a formal parameter clause for the {\em primary
-constructor} of the class. The scope of a formal parameter includes
-the template \verb@t@. However, the formal parameter may not form
-part of the types of any of the parent classes or members of \verb@t@.
-It is illegal to define two formal parameters with the same name.
-The formal parameter section \verb@(ps)@ may be omitted in which case
-an empty parameter section \verb@()@ is assumed.
-\item[]
-\verb@s@ is the {\em self type} of the class. Inside the
-class, the type of \verb@this@ is assumed to be \verb@s@. The self
-type must conform to the self types of all classes which are inherited
-by the template \verb@t@. The self type declaration `\verb@: s@' may be
-omitted, in which case the self type of the class is assumed to be
-equal to \verb@c[tps]@.
-\item[]
-\verb@t@ is a
-template (\sref{sec:templates}) of the form
-\verb@sc with mc$_1$ with ... with mc$_n$ { stats }@
-which defines the base classes, behavior and initial state of objects of
-the class. The extends clause \verb@extends sc with ... with mc$_n$@
-can be omitted, in which case
-\verb@extends scala.Object@ is assumed. The class body
-\verb@{stats}@ may also be omitted, in which case the empty body
-\verb@{}@ is assumed.
-\end{itemize}
-This class definition defines a type \verb@c[tps]@ and a constructor
-which when applied to parameters conforming to types \verb@ps@
-initializes instances of type \verb@c[tps]@ by evaluating the template
-\verb@t@.
-
-\subsection{Constructor Definitions}
-
-\syntax\begin{verbatim}
- FunDef \=::=\= this ParamClause `=' ConstrExpr
- ConstrExpr \>::=\> this ArgumentExpr
- \> |\> `{' {BlockStat `;'} ConstrExpr `}'
-\end{verbatim}
-
-A class may have additional constructors besides the primary
-constructor. These are defined by constructor definitions of the form
-\verb@def this(ps) = e@. Such a definition introduces an additional
-constructor for the enclosing class, with parameters as given in the
-formal parameter list \verb@ps@, and whose evaluation is defined by
-the constructor expression \verb@e@. The scope of each formal
-parameter is the constructor expression \verb@e@. A constructor
-expression is either a self constructor invocation \verb@this(args)@
-or a block which ends in a constructor expression. In terms of
-visibility rules, constructor definitions are conceptually outside
-their enclosing class. Hence, they can access neither value
-parameters nor members of the enclosing class by simple name, and the
-value \verb@this@ refers to an object of the class enclosing the class
-of the object being constructed. However, constructor definitions can
-access type parameters of the enclosing class.
-
-If there are auxiliary constructors of a class \verb@C@, they define
-together with \verb@C@'s primary constructor an overloaded constructor
-value. The usual rules for overloading resolution
-(\sref{sec:overloaded-defs}) apply for constructor invocations of \verb@C@,
-including the self constructor invocations in the constructor
-expressions themselves. To prevent infinite cycles of constructor
-invocations, there is the restriction that every self constructor
-invocation must refer to a constructor definition which precedes it
-(i.e. it must refer to either a preceding auxiliary constructor or the
-primary constructor of the class). The type of a constructor
-expression must be always so that a generic instance of the class is
-constructed. I.e., if the class in question has name \verb@C@ and type
-parameters \verb@[tps]@, then each constructor must construct an
-instance of \verb@C[tps]@; it is not permitted to instantiate formal
-type parameters.
-
-\example Consider the class definition
-
-\begin{verbatim}
-class LinkedList[a <: AnyRef](x: a, xs: LinkedList[a]) {
- var head = x;
- var tail = xs;
- def isEmpty = tail != null;
- def this() = this(null, null);
- def this(x: a) = { val empty = new LinkedList(); this(x, empty) }
-}
-\end{verbatim}
-This defines a class \verb@LinkedList@ with an overloaded constructor of type
-\begin{verbatim}
-[a <: AnyRef](x: a, xs: LinkList[a]): LinkedList[a] $\overload$
-[a <: AnyRef](): LinkedList[a] $\overload$
-[a <: AnyRef](x: a): LinkedList[a] .
-\end{verbatim}
-The second constructor alternative constructs an empty list, while the
-third one constructs a list with one element.
-
-\subsection{Case Classes}
-\label{sec:case-classes}
-
-\syntax\begin{verbatim} ClsDef \=::=\= case class ClassDef {`,' ClassDef}
-\end{verbatim}
-
-If a class definition is prefixed with \verb@case@, the class is said
-to be a {\em case class}. The primary constructor of a case class may
-be used in a constructor pattern (\sref{sec:patterns}). That
-constructor may not have any value parameters which are prefixed by
-\verb@def@. None of the base classes of a case class may be a case
-class. Furthermore, no type may have two different case classes among
-its base types.
-
-A case class definition of \verb@c[tps](ps)@ with type
-parameters \verb@tps@ and value parameters \verb@ps@ implicitly
-generates a function definition for a {\em case class factory}
-together with the class definition itself:
-\begin{verbatim}
-def c[tps](ps): s = new c[tps](ps)
-\end{verbatim}
-(Here, \verb@s@ s the self type of class \verb@c@.
-If a type parameter section
-is missing in the class, it is also missing in the factory
-definition).
-
-Also implicitly defined are accessor member definitions
-in the class that return its value parameters. Every binding
-\verb@x: T@ in the parameter section leads to a value definition of
-\verb@x@ that defines \verb@x@ to be an alias of the parameter.
-%Every
-%parameterless function binding \verb@def x: T@ leads to a
-%parameterless function definition of \verb@x@ which returns the result
-%of invoking the parameter function.
-%The case class may not contain a
-%directly bound member with the same simple name as one of its value
-%parameters.
-
-Every case class implicitly overrides some method definitions of class
-\verb@scala.Object@ (\sref{sec:cls-object}) unless a definition of the same
-method is already given in the case class itself or a non-abstract
-definition of the same method is given in some base class of the case
-class different from \verb@Object@. In particular:
-\begin{itemize}
-\item[] Method \verb@equals: (Any)boolean@ is structural equality, where two
-instances are equal if they belong to the same class and
-have equal (with respect to \verb@equals@) primary constructor arguments.
-\item[] Method \verb@hashCode: ()int@ computes a hash-code
-depending on the data structure in a way which maps equal (with respect to
-\verb@equals@) values to equal hash-codes.
-\item[] Method \verb@toString: ()String@ returns a string representation which
-contains the name of the class and its primary constructor arguments.
-\end{itemize}
-
-\example Here is the definition of abstract syntax for lambda
-calculus:
-
-\begin{verbatim}
-class Expr;
-case class
- Var \=(x: String) \=extends Expr,
- Apply \>(f: Expr, e: Expr) \>extends Expr,
- Lambda \>(x: String, e: Expr) \>extends Expr;
-\end{verbatim}
-This defines a class \verb@Expr@ with case classes
-\verb@Var@, \verb@Apply@ and \verb@Lambda@. A call-by-value evaluator for lambda
-expressions could then be written as follows.
-
-\begin{verbatim}
-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{verbatim}
-
-It is possible to define further case classes that extend type
-\verb@Expr@ in other parts of the program, for instance
-\begin{verbatim}
-case class Number(x: Int) extends Expr;
-\end{verbatim}
-
-This form of extensibility can be excluded by declaring the base class
-\verb@Expr@ \verb@sealed@; in this case, the only classes permitted to
-extend \verb@Expr@ are those which are nested inside \verb@Expr@, or
-which appear in the same statement sequence as the definition of
-\verb@Expr@.
-
-\section{Traits}
-
-\label{sec:traits}
-
-\syntax\begin{verbatim}
- ClsDef \=::=\= trait ClassDef {`,' ClassDef}
-\end{verbatim}
-
-A class definition which starts with the reserved word \verb@trait@
-instead of \verb@class@ defines a trait. A trait is a specific
-instance of an abstract class, so the \verb@abstract@ modifier is
-redundant for it. The template of a trait must satisfy the following
-three restrictions.
-\begin{enumerate}
-\item All base classes of the trait are traits.
-\item All parent class constructors of a template
- must be primary constructors with empty value
- parameter lists.
-\item All non-empty statements in the template are either imports or pure definitions (\sref{sec:defs}).
-\end{enumerate}
-A {\em pure} definition can be evaluated without any side effect.
-Function, type, class, or object definitions are always pure. A value
-definition is pure if its right-hand side expression is pure. Pure
-expressions are paths, literals, as well as typed expressions
-\verb@e: T@ where \verb@e@ is pure.
-
-These restrictions ensure that the evaluation of the mixin constructor
-of a trait has no effect. Therefore, traits may appear several times
-in the base class sequence of a template, whereas other classes cannot.
-%\item Packagings may add interface classes as new base classes to an
-%existing class or module.
-
-\example\label{ex:comparable}
-The following trait class defines the property of being
-ordered, i.e. comparable to objects of some type. It contains an abstract method
-\verb@<@ and default implementations of the other comparison operators
-\verb@<=@, \verb@>@, and \verb@>=@.
-
-\begin{verbatim}
-trait Ord[t <: Ord[t]]: 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{verbatim}
-
-\section{Object Definitions}
-\label{sec:modules}
-\label{sec:object-defs}
-
-\syntax\begin{verbatim}
- ObjectDef \=::=\= id [`:' SimpleType] ClassTemplate
-\end{verbatim}
-
-An object definition defines a single object of a new class. Its
-most general is
-\verb@object m: s extends t@. Here,
-\begin{itemize}
-\item[]
-\verb@m@ is the name of the object to be defined.
-\item[] \verb@s@ is the {\em self type} of the object. References to
-\verb@m@ are assumed to have type \verb@s@. Furthermore, inside the
-template \verb@t@, the type of \verb@this@ is also assumed to be \verb@s@.
-The self type must conform to the self types of all classes which are
-inherited by the template \verb@t@. The self type declaration
-`\verb@:s@' may be omitted, in which case the self type of the class is
-assumed to be equal to the anonymous class defined by \verb@t@.
-\item[]
-\verb@t@ is a
-template (\sref{sec:templates}) of the form
-\verb@sc with mc$_1$ with ... with mc$_n$ { stats }@
-which defines the base classes, behavior and initial state of \verb@m@.
-The extends clause \verb@extends sc with ... with mc$_n$@
-can be omitted, in which case
-\verb@extends scala.Object@ is assumed. The class body
-\verb@{stats}@ may also be omitted, in which case the empty body
-\verb@{}@ is assumed.
-\end{itemize}
-The object definition defines a single object (or: {\em module})
-conforming to the template \verb@t@. It is roughly equivalent to a class
-definition and a value definition that creates an object of the class:
-\begin{verbatim}
-final class m$\Dollar$class: s extends t;
-final val m: s = new m$\Dollar$class;
-\end{verbatim}
-(The \verb@final@ modifiers are omitted if the definition occurs as
-part of a block. The class name \verb@m$\Dollar$class@ is not
-accessible for user programs.)
-
-There are however two differences between an object definition and a
-pair of class and value definition as the one given above. First,
-object definitions may appear as top-level definitions in a
-compilation unit, whereas value definitions may not. Second, the
-module defined by an object definition is instantiated lazily. The
-\verb@new m$\Dollar$class@ constructor is evaluated not at the point
-of the object definition, but is instead evaluated the first time \verb@m@
-is dereferenced during execution of the program (which might be never
-at all). An attempt to dereference \verb@m@ again in the course of
-evaluation of the constructor leads to a infinite loop or run-time
-error. Other threads trying to dereference \verb@m@ while the constructor
-is being evaluated block until evaluation is complete.
-
-\example
-Classes in Scala do not have static members; however, an equivalent
-effect can be achieved by an accompanying object definition
-E.g.
-\begin{verbatim}
-abstract class Point {
- val x: Double;
- val y: Double;
- def isOrigin = (x == 0.0 && y == 0.0);
-}
-object Point {
- val origin = new Point() with { val x = 0.0, y = 0.0 }
-}
-\end{verbatim}
-This defines a class \verb@Point@ and an object \verb@Point@ which
-contains \verb@origin@ as a member. Note that the double use of the
-name \verb@Point@ is legal, since the class definition defines the name
-\verb@Point@ in the type name space, whereas the object definition
-defines a name in the term namespace.
-
-\comment{
-\example Here's an outline of a module definition for a file system.
-
-\begin{verbatim}
-module FileSystem with {
- private type FileDirectory;
- private val dir: FileDirectory
-
- interface File with {
- def read(xs: Array[Byte])
- def close: Unit
- }
-
- private class FileHandle extends File with { ... }
-
- def open(name: String): File = ...
-}
-\end{verbatim}
-}
-
-\chapter{Expressions}
-\label{sec:exprs}
-
-\syntax\begin{verbatim}
- Expr \=::=\= [Bindings `=>'] Expr
- \> |\> if `(' Expr `)' Expr [[`;'] else Expr]
- \> |\> try `{' block `}' [catch Expr] [finally Expr]
- \> |\> while '(' Expr ')' Expr
- \> |\> do Expr [`;'] while `(' Expr ')'
- \> |\> for `(' Enumerators `)' (do | yield) Expr
- \> |\> [SimpleExpr `.'] id `=' Expr
- \> |\> SimpleExpr ArgumentExpr `=' Expr
- \> |\> PostfixExpr [`:' Type1]
- PostfixExpr \>::=\> InfixExpr [id]
- InfixExpr \>::=\> PrefixExpr
- \> |\> InfixExpr id InfixExpr
- PrefixExpr \>::=\> [`-' | `+' | `~' | `!'] SimpleExpr
- SimpleExpr \>::=\> literal
- \> |\> Path
- \> |\> `(' [Expr] `)'
- \> |\> BlockExpr
- \> |\> new Template
- \> |\> SimpleExpr `.' id
- \> |\> SimpleExpr TypeArgs
- \> |\> SimpleExpr ArgumentExpr
- ArgumentExpr \>::=\> `(' Expr ')'
- \> |\> BlockExpr
- BlockExpr \>::=\> `{' CaseClause {CaseClause} `}'
- \> |\> `{' Block `}'
- Block \>::=\> {BlockStat `;'} [Expr]
- Exprs \>::= \> Expr {`,' Expr}
-\end{verbatim}
-
-Expressions are composed of operators and operands. Expression forms are
-discussed subsequently in decreasing order of precedence.
-
-The typing of expressions is often relative to some {\em expected
-type}. When we write ``expression \verb@e@ is expected to conform to
-type \verb@T@'', we mean: (1) the expected type of \verb@e@ is
-\verb@T@, and (2) the type of expression \verb@e@ must conform to
-\verb@T@.
-
-\section{Literals}
-
-\syntax\begin{verbatim}
- SimpleExpr \=::= \= literal
- literal \>::= \> intLit
- \> |\> floatLit
- \> |\> charLit
- \> |\> stringLit
- \> |\> symbolLit
-\end{verbatim}
-
-Typing and evaluation of numeric, character, and string literals are
-generally as in Java. An integer literal denotes an integer
-number. Its type is normally \verb@int@. However, if the expected type
-\verb@pt@ of the expression is either \verb@byte@, \verb@short@, or
-\verb@char@ and the integer number fits in the numeric range defined
-by the type, then the number is converted to type \verb@pt@ and the
-expression's type is \verb@pt@. A floating point literal denotes a
-single-precision or double precision IEEE floating point number. A
-character literal denotes a Unicode character. A string literal
-denotes a member of \verb@java.lang.String@.
-
-A symbol literal \verb@'id@ is a shorthand for the expression
-\verb@scala.Symbol("id")@. If the symbol literal is followed by an
-actual parameters, as in \verb@'id(args)@, then the whole expression
-is taken to be a shorthand for
-\verb@scala.Labelled(scala.Symbol("id"), args)@.
-
-\section{Boolean constants}
-
-\begin{verbatim}
- SimpleExpr \=::= \= true | false
-\end{verbatim}
-
-The boolean truth values are denoted by the reserved words \verb@true@
-and \verb@false@. The type of these expressions is \verb@boolean@, and
-their evaluation is immediate.
-
-\section{The $\NULL$ Reference}
-
-\syntax\begin{verbatim}
- SimpleExpr \=::= \= null
-\end{verbatim}
-
-The \verb@null@ expression is of type \verb@scala.AllRef@. It
-denotes a reference value which refers to a special ``null' object,
-which implements methods in class \verb@scala.AnyRef@ as follows:
-\begin{itemize}
-\item[]
-\verb@eq(x)@, \verb@==(x)@, \verb@equals(x)@ return \verb@true@ iff their
-argument \verb@x@ is also the ``null'' object.
-\item[]
-\verb@isInstanceOf[T]@ always returns \verb@false@.
-\item[]
-\verb@asInstanceOf[T]@ always returns the ``null'' object itself.
-\item[]
-\verb@toString@ returns the string ``null''.
-\end{itemize}
-A reference to any other member of the ``null'' object causes a
-\verb@NullPointerException@ to be thrown.
-
-\section{Designators}
-\label{sec:designators}
-
-\syntax\begin{verbatim}
- Designator \=::= \= Path
- \> | \> SimpleExpr `.' id
-\end{verbatim}
-
-A designator refers to a named term. It can be a {\em simple name} or
-a {\em selection}. If $r$ is a stable identifier of type $T$, the
-selection $r.x$ refers to the term member of $r$ that is identified in
-$T$ by the name $x$. For other expressions $e$, $e.x$ is typed as if
-it was $(\VAL;y=e\semi y.x)$ for some fresh name $y$. The typing rules
-for blocks implies that in that case $x$'s type may not refer to any
-abstract type member of \verb@e@.
-
-The expected type of a designator's prefix is always missing.
-The
-type of a designator is normally the type of the entity it refers
-to. However, if the designator is a path (\sref{sec:paths}) \verb@p@,
-its type is \verb@p.type@, provided the expression's expected type is
-a singleton type, or \verb@p@ occurs as the prefix of a selection,
-type selection, or mixin super expression.
-
-The selection $e.x$ is evaluated by first evaluating the qualifier
-expression $e$. The selection's result is then the value to which the
-selector identifier is bound in the selected object designated by $e$.
-
-\section{This and Super}
-\label{sec:this-super}
-
-\syntax\begin{verbatim}
- SimpleExpr \=::= \= [id `.'] this
- \> | \> [id `.'] super [`[' id `]'] `.' id
-\end{verbatim}
-
-The expression \verb@this@ can appear in the statement part of a
-template or compound type. It stands for the object being defined by
-the innermost template or compound type enclosing the reference. If
-this is a compound type, the type of \verb@this@ is that compound type.
-If it is a template of an instance creation expression, the type of
-\verb@this@ is the type of that template. If it is a template of a
-class or object definition with simple name \verb@C@, the type of this
-is the same as the type of \verb@C.this@.
-
-The expression \verb@C.this@ is legal in the statement part of an
-enclosing class or object definition with simple name \verb@C@. It
-stands for the object being defined by the innermost such definition.
-If the expression's expected type is a singleton type, or
-\verb@C.this@ occurs as the prefix of a selection, its type is
-\verb@C.this.type@, otherwise it is the self type of class \verb@C@.
-
-A reference \verb@super.m@ in a template refers to the definition of
-\verb@m@ in the actual superclass (\sref{sec:base-classes}) of the
-template. A reference \verb@C.super.m@ refers to the definition of
-\verb@m@ in the actual superclass of the innermost enclosing class or
-object definition named \verb@C@ which encloses the reference. The
-definition referred to by \verb@super@ or \verb@C.super@ must be
-concrete, or the template containing the reference must contain a
-definition which has an \verb@override@ modifier and which overrides
-\verb@m@.
-
-The \verb@super@ prefix may be followed by a mixin qualifier
-\verb@[M]@, as in \verb@C.super[M].x@. This is called a {\em mixin
-super reference}. In this case, the reference is to the member of
-\verb@x@ in the (first) mixin class of \verb@C@ whose simple name
-is \verb@M@.
-
-\example\label{ex:super}
-Consider the following class definitions
-
-\begin{verbatim}
-class Root { val x = "Root" }
-class A extends Root { override val x = "A" ; val superA = super.x }
-class B extends Root { override val x = "B" ; val superB = super.x }
-class C extends A with B with { override val x = "C" ; val superC = super.x }
-class D extends A with { val superD = super.x }
-class E extends C with D with { val superE = super.x }
-\end{verbatim}
-Then we have:
-\begin{verbatim}
-new A.superA = "Root", new B.superB = "Root"
-new C.superA = "Root", new C.superB = "A", new C.superC = "A"
-new D.superA = "Root", new D.superD = "A"
-new E.superA = "Root", new E.superB = "A", new E.superC = "A",
- new E.superD = "C", new E.superE = "C"
-\end{verbatim}
-Note that the \verb@superB@ function returns different results
-depending on whether \verb@B@ is used as defining class or as a mixin class.
-
-\example Consider the following class definitions:
-\begin{verbatim}
-class Shape {
- override def equals(other: Any) = ...;
- ...
-}
-trait Bordered extends Shape {
- val thickness: int;
- override def equals(other: Any) = other match {
- case that: Bordered => this.thickness == that.thickness
- case _ => false
- }
- ...
-}
-trait Colored extends Shape {
- val color: Color;
- override def equals(other: Any) = other match {
- case that: Colored => this.color == that.color
- case _ => false
- }
- ...
-}
-\end{verbatim}
-
-All three definitions of \verb@equals@ are combined in the class
-below, which makes use of both plain and mixin super references.
-\begin{verbatim}
-trait BorderedColoredShape extends Shape with Bordered with Colored {
- override def equals(other: Any) = other match {
- case that: BorderedColoredShape =>
- super.equals(that) &&
- super[Bordered].equals(that) &&
- super[Colored].equals(that)
- case _ => false
- }
-}
-\end{verbatim}
-
-\section{Function Applications}
-\label{sec:apply}
-
-\syntax\begin{verbatim}
- SimpleExpr \=::= \= SimpleExpr ArgumentExpr
-\end{verbatim}
-
-An application \verb@f(e$_1$, ..., e$_n$)@ applies the function \verb@f@ to the
-argument expressions \verb@e$_1$, ..., e$_n$@. If \verb@f@ has a method type
-\verb@(T$_1$, ..., T$_n$)U@, the type of each argument
-expression \verb@e$_i$@ must conform to the corresponding parameter type
-\verb@T$_i$@. If \verb@f@ has some value type, the application is taken to be
-equivalent to \verb@f.apply(e$_1$, ..., e$_n$)@, i.e.\ the
-application of an \verb@apply@ function defined by \verb@f@.
-
-%Class constructor functions
-%(\sref{sec:classes}) can only be applied in constructor invocations
-%(\sref{sec:constr-invoke}), never in expressions.
-
-Evaluation of \verb@f(e$_1$, ..., e$_n$)@ usually entails evaluation of
-\verb@f@ and \verb@e$_1$, ..., e$_n$@ in that order. Each argument expression
-is converted to the type of its corresponding formal parameter. After
-that, the application is rewritten to the function's right hand side,
-with actual arguments substituted for formal parameters. The result
-of evaluating the rewritten right-hand side is finally converted to
-the function's declared result type, if one is given.
-
-The case of a formal \verb@def@-parameter with a parameterless
-method type \verb@[]T@ is treated specially. In this case, the
-corresponding actual argument expression is not evaluated before the
-application. Instead, every use of the formal parameter on the
-right-hand side of the rewrite rule entails a re-evaluation of the
-actual argument expression. In other words, the evaluation order for
-\verb@def@-parameters is {\em call-by-name} whereas the evaluation
-order for normal parameters is {\em call-by-value}.
-
-\section{Type Applications}
-\label{sec:type-app}
-\syntax\begin{verbatim}
- SimpleExpr \=::= \= SimpleExpr `[' Types `]'
-\end{verbatim}
-
-A type application \verb@e[T$_1$, ..., T$_n$]@ instantiates a
-polymorphic value \verb@e@ of type
-\verb@[a$_1$ >: L$_1$ <: U$_1$, ..., a$_n$ >: L$_n$ <: U$_n$]S@ with
-argument types \verb@T$_1$, ..., T$_n$@. Every argument type
-\verb@T$_i$@ must obey corresponding bounds \verb@L$_i$@ and
-\verb@U$_i$@. That is, for each \verb@i = 1, ..., n@, we must
-have \verb@L$_i \sigma$ <: T$_i$ <: U$_i \sigma$@, where $\sigma$ is the
-substitution \verb@[a$_1$ := T$_1$, ..., a$_n$ := T$_n$]@. The type
-of the application is \verb@S$\sigma$@.
-
-The function part \verb@e@ may also have some value type. In this case
-the type application is taken to be equivalent to
-\verb@e.apply[T$_1$, ..., T$_n$]@, i.e.\ the
-application of an \verb@apply@ function defined by \verb@e@.
-
-Type applications can be omitted if local type inference
-(\sref{sec:local-type-inf}) can infer best type parameters for a
-polymorphic functions from the types of the actual function arguments
-and the expected result type.
-
-\section{References to Overloaded Bindings}
-\label{sec:overloaded-refs}
-
-If a name \verb@f@ referenced in an identifier or selection is
-overloaded (\sref{sec:overloaded-types}), the context of the reference
-has to identify a unique alternative of the overloaded binding. The
-way this is done depends on whether or not \verb@f@ is used as a
-function. Let $\AA$ be the set of all type alternatives of
-\verb@f@.
-
-Assume first that \verb@f@ appears as a function in an application, as
-in \verb@f(args)@. If there is precisely one alternative in
-$\AA$ which is a (possibly polymorphic) method type whose arity
-matches the number of arguments given, that alternative is chosen.
-
-Otherwise, let \verb@argtypes@ be the vector of types obtained by
-typing each argument with a missing expected type. One determines
-first the set of applicable alternatives. A method type alternative is
-{\em applicable} if each type in \verb@argtypes@ is compatible with
-the corresponding formal parameter type in the alternative, and, if
-the expected type is defined, the method's result type is compatible to
-it. A polymorphic method type is applicable if local type inference
-can determine type arguments so that the instantiated method type is
-applicable.
-
-Here, a type \verb@T@ is {\em compatible} to a type \verb@U@ if one of the
-following three clauses applies:
-\begin{enumerate}
-\item
-\verb@T@ conforms to \verb@U@.
-\item
-\verb@T@ is a parameterless method type \verb@[]T'@ and \verb@T'@
-conforms to \verb@U@.
-\item
-\verb@T@ is a monomorphic method type \verb@(Ts$_1$) ... (Ts$_n$)S@ which
-can be converted to a function type \verb@T'@ by using the rules for
-implicit conversions (\sref{sec:impl-conv}) and \verb@T'@ conforms to
-\verb@U@.
-\end{enumerate}
-
-Let $\BB$ be the set of applicable alternatives. It is an error if
-$\BB$ is empty. Otherwise, one chooses the {\em most specific}
-alternative among the alternatives in $\BB$, according to the
-following definition of being ``more specific''.
-\begin{itemize}
-\item
-A method type \verb@(Ts)U@ is more specific than some other
-type \verb@S@ if \verb@S@ is applicable to arguments \verb@(ps)@ of
-types \verb@Ts@.
-\item
-A polymorphic method type
-\verb@[a$_1$ >: L$_1$ <: U$_1$, ..., a$_n$ >: L$_n$ <: U$_n$]T@ is
-more specific than some other type \verb@S@ if \verb@T@ is more
-specific than \verb@S@ under the assumption that for
-\verb@i = 1, ..., n@ each \verb@a$_i$@ is an abstract type name
-bounded from below by \verb@L$_i$@ and from above by \verb@U$_i$@.
-\item
-Any other type is always more specific than a parameterized method
-type or a polymorphic type.
-\end{itemize}
-It is an error if there is no unique alternative in $\BB$ which is
-more specific than all other alternatives in $\BB$.
-
-Assume next that \verb@f@ appears as a function in a type
-application, as in \verb@f[targs]@. Then we choose an alternative in
-$\AA$ which takes the same number of type parameters as there are
-type arguments in \verb@targs@. It is an error if no such alternative
-exists, or if it is not unique.
-
-Assume finally that \verb@f@ does not appear as a function in either
-an application or a type application. If an expected type is given,
-let $\BB$ be the set of those alternatives in $\AA$ which are
-compatible to it. Otherwise, let $\BB$ be the same as $\AA$.
-We choose in this case the most specific alternative among all
-alternatives in $\BB$. It is an error if there is no unique
-alternative in $\BB$ which is more specific than all other
-alternatives in $\BB$.
-
-\example Consider the following definitions:
-
-\begin{verbatim}
- class A extends B {}
- def f(x: B, y: B) = ...
- def f(x: A, y: B) = ...
- val a: A, b: B
-\end{verbatim}
-Then the application \verb@f(b, b)@ refers to the first
-definition of \verb@f@ whereas the application \verb@f(a, a)@
-refers to the second. Assume now we add a third overloaded definition
-\begin{verbatim}
- def f(x: B, y: A) = ...
-\end{verbatim}
-Then the application \verb@f(a, a)@ is rejected for being ambiguous, since
-no most specific applicable signature exists.
-
-\section{Instance Creation Expressions}
-\label{sec:inst-creation}
-
-\syntax\begin{verbatim}
- SimpleExpr \=::= \= new Template
-\end{verbatim}
-
-A simple instance creation expression is \verb@new c@ where \verb@c@
-is a constructor invocation (\sref{sec:constr-invoke}). Let \verb@T@
-be the type of \verb@c@. Then \verb@T@ must denote a (a type instance
-of) a non-abstract subclass of \verb@scala.AnyRef@ which
-conforms to its self type. The expression is evaluated by creating a
-fresh object of the type \verb@T@, which is is initialized by
-evaluating \verb@c@. The type of the expression is \verb@T@'s self
-type (which might be less specific than \verb@T@).
-
-A general instance creation expression is
-\verb@new sc with mc$_1$ with ... with mc$_n$ {stats}@ where
-\verb@n $\geq$ 0@, \verb@sc@ as well as \verb@mc$_1$, ..., mc$_n$@ are
-constructor invocations (of types \verb@S, T$_1$, ...,T$_n$@, say) and
-\verb@stats@ is a statement sequence containing initializer statements
-and member definitions (\sref{sec:members}). The type of such an
-instance creation expression is then the compound type
-\verb@S with T$_1$ with ... with T$_n$ {R}@, where \verb@{R}@ is a
-refinement (\sref{sec:compound-types}) which declares exactly those
-members of \verb@stats@ that override a member of \verb@S@ or
-\verb@T$_1$, ..., T$_n$@. For this type to be well-formed, \verb@R@
-may not reference types defined in \verb@stats@ which do not
-themselves form part of \verb@R@.
-
-The instance creation expression is evaluated by creating a fresh
-object, which is initialized by evaluating the expression template.
-
-\example Consider the class
-\begin{verbatim}
-abstract class C {
- type T; val x: T; def f(x: T): Object
-}
-\end{verbatim}
-and the instance creation expression
-\begin{verbatim}
-C { type T = Int; val x: T = 1; def f(x: T): T = y; val y: T = 2 }
-\end{verbatim}
-Then the created object's type is:
-\begin{verbatim}
-C { type T = Int; val x: T; def f(x: T): T }
-\end{verbatim}
-The value \verb@y@ is missing from the type, since \verb@y@ does not
-override a member of \verb@C@.
-
-\section{Blocks}
-\label{sec:blocks}
-
-\syntax\begin{verbatim}
- BlockExpr \=::= \= `{' Block `}'
- Block \>::= \> [{BlockStat `;'} Expr]
-\end{verbatim}
-
-A block expression \verb@{s$_1$; ...; s$_n$; e}@ is constructed from a
-sequence of block statements \verb@s$_1$ , ..., s$_n$@ and a final
-expression \verb@e@. The final expression can be omitted, in which
-case the unit value \verb@()@ is assumed.
-
-%Whether or not the scope includes the statement itself
-%depends on the kind of definition.
-
-The expected type of the final expression \verb@e@ is the expected
-type of the block. The expected type of all preceding statements is
-missing.
-
-The type of a block \verb@s$_1$; ...; s$_n$; e@ is usually the type of
-\verb@e@. That type must be equivalent to a type which does not refer
-to an entity defined locally in the block. If this condition is
-violated, but a fully defined expected type is given, the type of the
-block is instead assumed to be the expected type.
-
-Evaluation of the block entails evaluation of its statement sequence,
-followed by an evaluation of the final expression \verb@e@, which
-defines the result of the block.
-
-\example
-Written in isolation,
-the block \verb@{ class C extends B {...} ; new C }@ is illegal, since its type
-refers to class \verb@C@, which is defined locally in the block.
-
-However, when used in a definition such as
-\begin{verbatim}
-val x: B = { class C extends B {...} ; new C }
-\end{verbatim}
-the block is well-formed, since the problematic type \verb@C@ can be
-replaced by the expected type \verb@B@.
-
-\section{Prefix, Infix, and Postfix Operations}
-\label{sec:infix-operations}
-
-\syntax\begin{verbatim}
- PostfixExpr \=::=\= InfixExpr [id]
- InfixExpr \>::=\> PrefixExpr
- \> |\> InfixExpr id InfixExpr
- PrefixExpr \>::=\> [`-' | `+' | `!' | `~'] SimpleExpr
-\end{verbatim}
-
-Expressions can be constructed from operands and operators. A prefix
-operation \verb@op e@ consists of a prefix operator \verb@op@, which
-must be one of the identifiers `\verb@+@', `\verb@-@', `\verb@!@', or
-`\verb@~@', and a simple expression \verb@e@. The expression is
-equivalent to the postfix method application \verb@e.op@.
-
-Prefix operators are different from normal function applications in
-that their operand expression need not be atomic. For instance, the
-input sequence \verb@-sin(x)@ is read as \verb@-(sin(x))@, whereas the
-function application \verb@negate sin(x)@ would be parsed as the
-application of the infix operator \verb@sin@ to the operands
-\verb@negate@ and \verb@(x)@.
-
-An infix or postfix operator can be an arbitrary identifier. Binary
-operators have precedence and associativity defined as follows:
-
-The {\em precedence} of an operator is determined by the operator's first
-character. Characters are listed below in increasing order of
-precedence, with characters on the same line having the same precedence.
-\begin{verbatim}
- (all letters)
- |
- ^
- &
- < >
- = !
- :
- + -
- * / %
- (all other special characters)
-\end{verbatim}
-That is, operators starting with a letter have lowest precedence,
-followed by operators starting with `\verb@|@', etc.
-
-The {\em associativity} of an operator is determined by the operator's
-last character. Operators ending with a colon `\verb@:@' are
-right-associative. All other operators are left-associative.
-
-Precedence and associativity of operators determine the grouping of
-parts of an expression as follows.
-\begin{itemize}
-\item If there are several infix operations in an
-expression, then operators with higher precedence bind more closely
-than operators with lower precedence.
-\item If there are consecutive infix
-operations \verb@e$_0$ op$_1$ e$_1$ op$_2$ ... op$_n$ e$_n$@
-with operators \verb@op$_1$, ..., op$_n$@ of the same precedence,
-then all these operators must
-have the same associativity. If all operators are left-associative,
-the sequence is interpreted as
-\verb@(...(e$_0$ op$_1$ e$_1$) op$_2$...) op$_n$ e$_n$@.
-Otherwise, if all operators are right-associative, the
-sequence is interpreted as
-\verb@e$_0$ op$_1$ (e$_1$ op$_2$ (... op$_n$ e$_n$)...)@.
-\item
-Postfix operators always have lower precedence than infix
-operators. E.g.\ \verb@e$_1$ op$_1$ e$_2$ op$_2$@ is always equivalent to
-\verb@(e$_1$ op$_1$ e$_2$) op$_2$@.
-\end{itemize}
-A postfix operation \verb@e op@ is interpreted as \verb@e.op@. A
-left-associative binary operation \verb@e$_1$ op e$_2$@ is interpreted as
-\verb@e$_1$.op(e$_2$)@. If \verb@op@ is right-associative, the same operation is
-interpreted as \verb@(val x=e$_1$; e$_2$.op(x))@,
-where \verb@x@ is a fresh name.
-
-\section{Typed Expressions}
-
-\syntax\begin{verbatim}
- Expr \=::= \= PostfixExpr [`:' Type1]
-\end{verbatim}
-
-The typed expression \verb@e: T@ has type \verb@T@. The type of
-expression \verb@e@ is expected to conform to \verb@T@. The result of
-the expression is the value of \verb@e@ converted to type \verb@T@.
-
-\example Here are examples of well-typed and illegal typed expressions.
-
-\begin{verbatim}
- 1: int \=// legal, of type int
- 1: long \>// legal, of type long
- // 1: string \>// illegal
-\end{verbatim}
-
-\section{Assignments}
-
-\syntax\begin{verbatim}
- Expr \=::= \= Designator `=' Expr
- \> | \> SimpleExpr ArgumentExpr `=' Expr
-\end{verbatim}
-
-An assignment to a simple variable \verb@x = e@ is interpreted
-depending on whether \verb@x@ is defined in a block or in a
-template. If \verb@x@ is a variable defined in a block, then the
-assignment changes the current value of \verb@x@ to be the result of
-evaluating the expression \verb@e@. The type of \verb@e@ is expected
-to conform to the type of \verb@x@. If \verb@x@ is a member
-of a template, the assignment \verb@x = e@ is interpreted as the
-invocation \verb@x_=(e)@ of the setter function for variable \verb@x@
-(\sref{sec:vardef}). Analogously, an assignment \verb@f.x = e@ to a
-field \verb@x@ is interpreted as the invocation \verb@f.x_=(e)@.
-
-An assignment \verb@f(args) = e@ with a function application to the
-left of the ``\verb@=@' operator is interpreted as
-\verb@f.update(args, e)@, i.e.\
-the invocation of an \verb@update@ function defined by \verb@f@.
-
-\example \label{ex:imp-mat-mul}
-Here is the usual imperative code for matrix multiplication.
-
-\begin{verbatim}
-def matmul(xss: Array[Array[double]], yss: Array[Array[double]]) = {
- val zss: Array[Array[double]] = new Array(xss.length, yss.length);
- var i = 0;
- while (i < xss.length) {
- var j = 0;
- while (j < yss(0).length) {
- var acc = 0.0;
- var k = 0;
- while (k < yss.length) {
- acc = acc + xs(i)(k) * yss(k)(j);
- k = k + 1
- }
- zss(i)(j) = acc;
- j = j + 1
- }
- i = i + 1
- }
- zss
-}
-\end{verbatim}
-Desugaring the array accesses and assignments yields the following
-expanded version:
-\begin{verbatim}
-def matmul(xss: Array[Array[double]], yss: Array[Array[double]]) = {
- val zss: Array[Array[double]] = new Array(xss.length, yss.length);
- var i = 0;
- while (i < xss.length) {
- var j = 0;
- while (j < yss(0).length) {
- var acc = 0.0;
- var k = 0;
- while (k < yss.length) {
- acc = acc + xss.apply(i).apply(k) * yss.apply(k).apply(j);
- k = k + 1
- }
- zss.apply(i).update(j, acc);
- j = j + 1
- }
- i = i + 1
- }
- zss
-}
-\end{verbatim}
-
-\section{Conditional Expressions}
-
-\syntax\begin{verbatim}
- Expr \=::= \= if `(' Expr `)' Expr [[`;'] else Expr]
-\end{verbatim}
-
-The conditional expression \verb@if (e$_1$) e$_2$ else e$_3$@ chooses
-one of the values of \verb@e$_2$@ and \verb@e$_2$@, depending on the
-value of \verb@e$_1$@. The condition \verb@e$_1$@ is expected to
-conform to type \verb@boolean@. The then-part \verb@e$_2$@ and the
-else-part \verb@e$_3$@ are both expected to conform to the expected
-type of the conditional expression. The type of the conditional
-expression is the least upper bound of the types of \verb@e$_1$@ and
-\verb@e$_2$@. A semicolon preceding the \verb@else@ symbol of a
-conditional expression is ignored.
-
-The conditional expression is evaluated by evaluating first
-\verb@e$_1$@. If this evaluates to \verb@true@, the result of
-evaluating \verb@e$_2$@ is returned, otherwise the result of
-evaluating \verb@e$_3$@ is returned.
-
-A short form of the conditional expression eliminates the
-else-part. The conditional expression \verb@if (e$_1$) e$_2$@ is
-evaluated as if it was \verb@if (e$_1$) e$_2$ else ()@. The type of
-this expression is \verb@unit@ and the then-part
-\verb@e$_2$@ is also expected to conform to type \verb@unit@.
-
-\section{While Loop Expressions}
-
-\syntax\begin{verbatim}
- Expr \=::= \= while `(' Expr ')' Expr
-\end{verbatim}
-
-The while loop expression \verb@while (e$_1$) e$_2$@ is typed and
-evaluated as if it was an application of \verb@whileLoop (e$_1$) (e$_2$)@ where
-the hypothetical function \verb@whileLoop@ is defined as follows.
-
-\begin{verbatim}
- def whileLoop(def c: boolean)(def s: unit): unit =
- if (c) { s ; while(c)(s) } else {}
-\end{verbatim}
-
-\example The loop
-\begin{verbatim}
- while (x != 0) { y = y + 1/x ; x = x - 1 }
-\end{verbatim}
-Is equivalent to the application
-\begin{verbatim}
- whileLoop (x != 0) { y = y + 1/x ; x = x - 1 }
-\end{verbatim}
-Note that this application will never produce a division-by-zero
-error at run-time, since the
-expression \verb@(y = 1/x)@ will be evaluated in the body of
-\verb@while@ only if the condition parameter is false.
-
-\section{Do Loop Expressions}
-
-\syntax\begin{verbatim}
- Expr \=::= \= do Expr [`;'] while `(' Expr ')'
-\end{verbatim}
-
-The do loop expression \verb@do e$_1$ while (e$_2$)@ is typed and
-evaluated as if it was the expression \verb@(e$_1$ ; while (e$_2$) e$_1$)@.
-A semicolon preceding the \verb@while@ symbol of a do loop expression is ignored.
-
-\section{Comprehensions}
-
-\syntax\begin{verbatim}
- Expr \=::= \= for `(' Enumerators `)' (do | yield) Expr
- Enumerator \>::=\> Generator {`;' Enumerator}
- Enumerator \>::=\> Generator
- \> |\> Expr
- Generator \>::=\> val Pattern `<-' Expr
-\end{verbatim}
-
-A comprehension \verb@for (ens) yield e@ evaluates expression \verb@e@ for each
-binding generated by the enumerators \verb@ens@. An enumerator is a generator,
-possibly followed by further generators or filters. A generator
-\verb@val p <- e@ produces bindings from an expression \verb@e@ which is
-matched in some way against pattern \verb@p@. Filters are expressions which
-restrict enumerated bindings. The precise meaning of generators and
-filters is defined by translation to invocations of four methods:
-\verb@map@, \verb@filter@, \verb@flatMap@, and \verb@foreach@. These
-methods can be implemented in different ways for different carrier
-types. As an example, an implementation of these methods for lists is
-given in \sref{cls-list}.
-
-The translation scheme is as follows.
-In a first step, every generator \verb@val p <- e@, where \verb@p@ is not
-a pattern variable, is replaced by
-\begin{verbatim}
-val p <- e.filter { case p => true; case _ => false }
-\end{verbatim}
-Then, the following
-rules are applied repeatedly until all comprehensions have been eliminated.
-\begin{itemize}
-\item
-A generator \verb@q <- e@ followed by a filter \verb@f@ is translated to
-a single generator \verb@q <- e.filter(x$_1$, ..., x$_n$ => f)@ where
-\verb@x$_1$, ..., x$_n$@ are the free variables of \verb@q@.
-
-\item
-A for-comprehension
-\verb@for (val p <- e) yield e'@
-is translated to
-\verb@e.map { case p => e' }@.
-
-\item
-A for-comprehension
-\verb@for (val p <- e) do e'@
-is translated to
-\verb@e.foreach { case p => e' }@.
-
-\item
-A for-comprehension
-\begin{verbatim}
-for (val p <- e; val p' <- e' ...) yield e'' ,
-\end{verbatim}
-where \verb@...@ is a (possibly empty)
-sequence of generators or filters,
-is translated to
-\begin{verbatim}
-e.flatmap { case p => for (val p' <- e' ...) yield e'' } .
-\end{verbatim}
-\item
-A for-comprehension
-\begin{verbatim}
-for (val p <- e; val p' <- e' ...) do e'' .
-\end{verbatim}
-where \verb@...@ is a (possibly empty)
-sequence of generators or filters,
-is translated to
-\begin{verbatim}
-e.foreach { case p => for (val p' <- e'...) do e'' } .
-\end{verbatim}
-\end{itemize}
-
-\example
-the following code produces all pairs of numbers
-between \verb@1@ and \verb@n-1@ whose sums are prime.
-\begin{verbatim}
-for \= { \= val i <- range(1, n);
- \> \> val j <- range(1, i);
- \> \> isPrime(i+j)
-} yield Pair (i, j)
-\end{verbatim}
-The for-comprehension is translated to:
-\begin{verbatim}
-range(1, n)
- .flatMap {
- case i => range(1, i)
- .filter { j => isPrime(i+j) }
- .map { case j => Pair(i, j) } }
-\end{verbatim}
-
-\comment{
-\example
-\begin{verbatim}
-package class List[a] with {
- def map[b](f: (a)b): List[b] = match {
- case <> => <>
- case x :: xs => f(x) :: xs.map(f)
- }
- def filter(p: (a)Boolean) = match {
- case <> => <>
- case x :: xs => if p(x) then x :: xs.filter(p) else xs.filter(p)
- }
- def flatMap[b](f: (a)List[b]): List[b] =
- if (isEmpty) Nil
- else f(head) ::: tail.flatMap(f);
- }
- def foreach(f: (a)Unit): Unit =
- if (isEmpty) ()
- else (f(head); tail.foreach(f));
-}
-\end{verbatim}
-
-\example
-\begin{verbatim}
-abstract class Graph[Node] {
- type Edge = (Node, Node)
- val nodes: List[Node]
- val edges: List[Edge]
- def succs(n: Node) = for ((p, s) <- g.edges, p == n) s
- def preds(n: Node) = for ((p, s) <- g.edges, s == n) p
-}
-def topsort[Node](g: Graph[Node]): List[Node] = {
- val sources = for (n <- g.nodes, g.preds(n) == <>) n
- if (g.nodes.isEmpty) <>
- else if (sources.isEmpty) new Error(``topsort of cyclic graph'') throw
- else sources :+: topsort(new Graph[Node] with {
- val nodes = g.nodes diff sources
- val edges = for ((p, s) <- g.edges, !(sources contains p)) (p, s)
- })
-}
-\end{verbatim}
-}
-
-\example For comprehensions can be used to express vector
-and matrix algorithms concisely.
-For instance, here is a function to compute the transpose of a given matrix:
-
-\begin{verbatim}
-def transpose[a](xss: Array[Array[a]]) {
- for (val i <- Array.range(0, xss(0).length)) yield
- Array(for (val xs <- xss) yield xs(i))
-\end{verbatim}
-
-Here is a function to compute the scalar product of two vectors:
-\begin{verbatim}
-def scalprod(xs: Array[double], ys: Array[double]) {
- var acc = 0.0;
- for (val Pair(x, y) <- xs zip ys) do acc = acc + x * y;
- acc
-}
-\end{verbatim}
-
-Finally, here is a function to compute the product of two matrices. Compare with the imperative version of \ref{ex:imp-mat-mul}.
-\begin{verbatim}
-def matmul(xss: Array[Array[double]], yss: Array[Array[double]]) = {
- val ysst = transpose(yss);
- for (val xs <- xs) yield
- for (val yst <- ysst) yield
- scalprod(xs, yst)
-}
-\end{verbatim}
-The code above makes use of the fact that \verb@map@, \verb@flatmap@,
-\verb@filter@, and \verb@foreach@ are defined for members of class
-\verb@scala.Array@.
-
-\section{Try Expressions}
-
-\syntax\begin{verbatim}
- Expr \=::= \= try `{' block `}' [catch Expr] [finally Expr]
-\end{verbatim}
-
-A try expression \verb@try { b } catch e@ evaluates the block
-\verb@b@. If evaluation of \verb@b@ does not cause an exception to be
-thrown, the result of \verb@b@ is returned. Otherwise the {\em
-handler} \verb@e@ is applied to the thrown exception. Let \verb@pt@
-be the expected type of the try expression. The block \verb@b@ is
-expected to conform to \verb@pt@. The handler \verb@e@ is expected
-conform to type \verb@scala.PartialFunction[scala.Throwable, pt]@.
-The type of the try expression is the least upper bound of the type of
-\verb@b@ and the result type of \verb@e@.
-
-A try expression \verb@try { b } finally e@ evaluates the block
-\verb@b@. If evaluation of \verb@b@ does not cause an exception to be
-thrown, expression \verb@e@ is evaluated. If an exception is thrown
-during evaluation of \verb@e@, the evaluation of the try expression is
-aborted with the thrown exception. If no exception is thrown during
-evaluation of \verb@e@, the result of \verb@b@ is returned as the
-result of the try expression. If an exception is thrown during
-evaluation of \verb@b@, the finally block
-\verb@e@ is also evaluated. If another exception \verb@e@ is thrown
-during evaluation of \verb@e@, evaluation of the try expression is
-aborted with the thrown exception. If no exception is thrown during
-evaluation of \verb@e@, the original exception thrown in \verb@b@ is
-re-thrown once evaluation of \verb@e@ has completed. The block
-\verb@b@ is expected to conform to the expected type of the try
-expression. The finally expression \verb@e@ is expected to conform to
-type \verb@unit@.
-
-A try expression \verb@try { b } catch e$_1$ finally e$_2$@ is a shorthand
-for \verb@try { try { b } catch e$_1$ } finally e$_2$@.
-
-\section{Anonymous Functions}
-\label{sec:closures}
-
-\syntax\begin{verbatim}
- Expr \=::= \= [Bindings `=>'] Expr
- Bindings \>::=\> `(' Binding {`,' Binding `)'
- \> |\> id [`:' Type1]
- Binding \>::= \> id [`:' Type]
-\end{verbatim}
-
-The anonymous function \verb@(x$_1$: T$_1$, ..., x$_n$: T$_n$) => e@
-maps parameters \verb@x$_i$@ of types \verb@T$_i$@ to a result given
-by expression \verb@e@. The scope of each formal parameter
-\verb@x$_i$@ is \verb@e@.
-
-If the expected type of the anonymous function is of the form
-\verb@scala.Function$\,n$[S$_1$, ..., S$_n$, R]@, the expected types
-of \verb@e@ is \verb@R@ and the type \verb@T$_i$@ of any of the
-parameters \verb@x$_i$@ can be omitted, in which case
-\verb@T$_i$ = S$_i$@ is assumed. If the expected type of the anonymous
-function is some other type, all formal parameter types must be
-explicitly given, and the expected type of \verb@e@ is missing. The
-type of the anonymous function is
-\verb@scala.Function$\,n$[S$_1$, ..., S$_n$, T]@, where \verb@T@ is
-the type of \verb@e@. \verb@T@ must be equivalent to a type which does
-not refer to any of the formal parameters \verb@x$_i$@.
-
-The anonymous function is evaluated as the instance creation expression
-\begin{verbatim}
-scala.Function$\,n$[T$_1$, ..., T$_n$, T] {
- def apply(x$_1$: T$_1$, ..., x$_n$: T$_n$): T = e
-}
-\end{verbatim}
-In the case of a single formal parameter, \verb@(x: T) => e@ and \verb@(x) => e@
-can be abbreviated to \verb@x: T => e@, and \verb@x => e@, respectively.
-
-\example Examples of anonymous functions:
-
-\begin{verbatim}
- x => x \=// The identity function
-
- f => g => x => f(g(x)) \>// Curried function composition
-
- (x: Int,y: Int) => x + y \>// A summation function
-
- () => { count = count + 1; count } \>// The function which takes an empty
- \>// parameter list $()$, increments a non-local
- \>// variable count and returns the new value.
-\end{verbatim}
-
-\section{Statements}
-\label{sec:statements}
-
-\syntax\begin{verbatim}
- BlockStat \=::= \= Import
- \> | \> Def
- \> | \> {LocalModifier} ClsDef
- \> | \> Expr
- \> | \>
- TemplateStat \>::= \> Import
- \> | \> {Modifier} Def
- \> | \> {Modifier} Dcl
- \> | \> Expr
- \> | \>
-\end{verbatim}
-
-Statements occur as parts of blocks and templates. A statement can be
-an import, a definition or an expression, or it can be empty.
-Statements used in the template of a class definition can also be
-declarations. An expression that is used as a statement can have an
-arbitrary value type. An expression statement $e$ is evaluated by
-evaluating $e$ and discarding the result of the evaluation.
-
-Block statements may be definitions which bind local names in the
-block. The only modifiers allowed in block-local definitions are modifiers
-\verb@abstract@, \verb@final@, or \verb@sealed@ preceding a class or
-object definition.
-
-With the exception of overloaded definitions
-(\sref{sec:overloaded-defs}), a statement sequence making up a block
-or template may not contain two definitions or declarations that bind
-the same name in the same namespace. Evaluation of a statement
-sequence entails evaluation of the statements in the order they are
-written.
-
-\chapter{Pattern Matching}
-
-\section{Patterns}
-
-% 2003 July - changed to new pattern syntax + semantic Burak
-
-\label{sec:patterns}
-
-\syntax\begin{verbatim}
-Pattern \=::= \= TreePattern { `|' TreePattern }
-
-TreePattern \>::= \> varid `:' Type
- \> | \> `_' `:' Type
- \> | \> SimplePattern [ '*' | '?' | '+' ]
- \> | \> SimplePattern { id SimplePattern }
-
-SimplePattern \=::= \> varid [ '@' SimplePattern ]
- \> | \> `_'
- \> | \> literal
- \> | \> StableId [ `(' [Patterns] `)' ]
- \> | \> `(' Patterns `)'
- \> | \>
-
- Patterns \>::= \> Pattern {`,' Pattern}
-\end{verbatim}
-
-A pattern is built from constants, constructors, variables and regular
-operators. Pattern matching tests whether a given value (or sequence
-of values) has the shape defined by a pattern, and, if it does, binds
-the variables in the pattern to the corresponding components of the
-value (or sequence of values). The same variable name may not be
-bound more than once in a pattern.
-
-The type of a pattern and the expected types of variables within the
-pattern are determined by the context, except for patterns
-that employ regular operators. In the latter case the missing
-information is provided by the structure of the pattern.
-We distinguish the following kinds of patterns.
-
-A {\em wild-card pattern} \_ matches any value.
-
-A {\em variable-binding pattern} $x @ p$ is a simple identifier $x$
-which starts with a lower case letter, together with a pattern $p$. It
-matches a value or a sequence of values whenever $p$ does, and in
-addition binds the variable name to that value or to that sequence of
-values. The type of $x$ is either $T$ as determined from the context, or
-\verb@List[T]@ \todo{really?}, if $p$ matches sequences of values. A
-special case is a {\em variable pattern} $x$ which is treated as $x @ \_$.
-
-A {\em typed pattern} $x: T$ consists of a pattern variable $x$ and a
-simple type $T$. The type $T$ may be a class type or a compound type;
-it may not contain a refinement (\sref{sec:refinements}). This
-pattern matches any non-null value of type $T$ and binds the variable
-name to that value. $T$ must conform to the pattern's expected
-type. The type of $x$ is $T$.
-
-A {\em pattern literal} $l$ matches any value that is equal (in terms
-of $==$) to it. It's type must conform to the expected type of the
-pattern.
-
-A {\em named pattern constant} $p$ is a stable identifier
-(\sref{sec:stableids}). To resolve the syntactic overlap with a
-variable pattern, a named pattern constant may not be a simple name
-starting with a lower-case letter. The stable identifier $p$ is
-expected to conform to the expected type of the pattern. The pattern
-matches any value $v$ such that \verb@$r$ == $v$@
-(\sref{sec:cls-object}).
-
-A {\em sequence pattern} $p_1 \commadots p_n$ where $n \geq 0$ is a
-sequence of patterns separated by commas and matching the sequence of
-values that are matched by the components. Sequence pattern may only
-appear under constructor applications. Note that empty sequence
-patterns are allowed. The type of the value patterns \todo{where defined?}
-that appear in
-the pattern is the expected type as determined from the context.
-
-A {\em choice pattern} $p_1 | \ldots | p_n$ is a choice among several
-alternatives, which may not contain variable-binding patterns. It
-matches every value matched by at least one of its alternatives. Note
-that the empty sequence may appear as an alternative. An {\em option
-pattern} $p?$ is an abbreviation for $(p| )$. If the alternatives
-are value patterns, then the whole choice pattern is a value pattern,
-whose type is the least upper bound of the types of the alternatives.
-
-An {\em iterated pattern} $p*$ matches the sequence of values
-consisting of zero, one or more occurrences of values matched by $p$,
-where $p$ may not contain a variable-binding pattern. A {\em non-empty
-iterated pattern} $p+$ is an abbreviation for $(p,p*)$.
-
-A non-regular sequence \todo{find other term?}
-pattern is a sequence pattern $p_1 \commadots p_n$
-where $n \geq 1$ with no component pattern containing iterated or nested
-sequence patterns.
-
-A {\em constructor pattern} $c ( p )$ consists of a simple type $c$
-followed by a pattern $p$. If $c$ designates a monomorphic case
-class, then it must conform to the expected type of the pattern, the
-pattern must be a non-regular sequence pattern $p_1 \commadots p_n$
-whose length corresponds to the number of arguments of $c$'s primary
-constructor. The expected types of the component patterns are then
-taken from the formal parameter types of (said) constructor. If $c$
-designates a polymorphic case class, then there must be a unique type
-application instance of it such that the instantiation of $c$ conforms
-to the expected type of the pattern. The instantiated formal parameter
-types of $c$'s primary constructor are then taken as the expected
-types of the component patterns $p_1\commadots p_n$. In both cases,
-the pattern matches all objects created from constructor invocations
-$c(v_1 \commadots v_n)$ where each component pattern $p_i$ matches the
-corresponding value $v_i$. If $c$ does not designate a case class, it
-must be a subclass of \verb@Seq[ T ]@. In that case $p$ may be an
-arbitrary pattern. Value patterns in $p$ are expected to conform to
-type $T$, and the pattern matches all objects whose \verb@elements()@
-method returns a sequence that matches $p$.
-
-The pattern $(p)$ is regarded as equivalent to the pattern $p$, if $p$
-is a nonempty sequence pattern. The empty tuple $()$ is a shorthand
-for the constructor pattern \verb@Unit@.
-
-An {\em infix operation pattern} \verb@p id p'@ is a shorthand for the
-constructor pattern \verb@id(p, p')@. The precedence and
-associativity of operators in patterns is the same as in expressions
-(\sref{sec:infix-operations}). The operands may not be empty sequence
-patterns.
-
-Regular expressions that contain variable bindings may be ambiguous,
-i.e. there might be several ways to match a sequence against the
-pattern. In these cases, the \emph{shortest-match policy} applies:
-patterns that appear before other, overlapping patterns match
-as little as possible.
-
-\example Some examples of patterns are:
-\begin{enumerate}
-\item
-The pattern \verb@ex: IOException@ matches all instances of class
-\verb@IOException@, binding variable \verb@ex@ to the instance.
-\item
-The pattern \verb@Pair(x, _)@ matches pairs of values, binding \verb@x@ to
-the first component of the pair. The second component is matched
-with a wildcard pattern.
-\item
-The pattern \verb+List( x, y, xs @ _ * )+ matches lists of length $\geq 2$,
-binding \verb@x@ to the list's first element, \verb@y@ to the list's
-second element, and \verb@xs@ to the remainder, which may be empty.
-\item
-The pattern \verb=List( 1, x@(( 'a' | 'b' )+),y,_ )= matches a list that
-contains 1 as its first element, continues with a non-empty sequence of
-\verb@'a'@s and \verb@'b'@s, followed by two more elements. The sequence 'a's and 'b's
-is bound to \verb@x@, and the next to last element is bound to \verb@y@.
-\item
-The pattern \verb=List( x@( 'a'* ), 'a'+ )= matches a non-empty list of
-\verb@'a'@s. Because of the shortest match policy, \verb@x@ will always be bound to
-the empty sequence.
-\item
-The pattern \verb=List( x@( 'a'+ ), 'a'* )= also matches a non-empty list of
-\verb@'a'@s. Here, \verb@x@ will always be bound to
-the sequence containing one \verb@'a'@
-\end{enumerate}
-
-\subsection{Pattern Matching Expressions}
-\label{sec:pattern-match}
-
-\syntax\begin{verbatim}
- BlockExpr \=::=\= `{' CaseClause {CaseClause} `}'
- CaseClause \>::=\> case Pattern [`if' PostfixExpr] `=>' Block
-\end{verbatim}
-
-A pattern matching expression
-\verb@case p$_1$ => b$_1$ ... case p$_n$ => b$_n$@ consists of a number
-$n \geq 1$ of cases. Each case consists of a (possibly guarded) pattern
-$p_i$ and a block $b_i$. The scope of the pattern variables in $p_i$ is
-the corresponding block $b_i$.
-
-The expected type of a pattern matching expression must in part be
-defined. It must be either \verb@scala.Function1[T$_p$, T$_r$]@ or
-\verb@scala.PartialFunction[T$_p$, T$_r$]@, where the argument type
-\verb@T$_p$@ must be fully determined, but the result type
-\verb@T$_r$@ may be undetermined. All patterns are typed
-relative to the expected type $T_p$ (\sref{sec:patterns}). The expected type of
-every block \verb@b$_i$@ is \verb@T$_r$@.
-Let \verb@T$_b$@ be the least upper bound of the types of all blocks
-\verb@b$_i$@. The type of the pattern matching expression is
-then the required type with \verb@T$_r$@ replaced by \verb@T$_b$@
-(i.e. the type is either \verb@scala.Function[T$_p$, T$_b$]@ or
-\verb@scala.PartialFunction[T$_p$, T$_b$]@.
-
-When applying a pattern matching expression to a selector value,
-patterns are tried in sequence until one is found which matches the
-selector value (\sref{sec:patterns}). Say this case is $\CASE;p_i
-\Arrow b_i$. The result of the whole expression is then the result of
-evaluating $b_i$, where all pattern variables of $p_i$ are bound to
-the corresponding parts of the selector value. If no matching pattern
-is found, a \verb@scala.MatchError@ exception is thrown.
-
-The pattern in a case may also be followed by a guard suffix \verb@if e@
-with a boolean expression $e$. The guard expression is evaluated if
-the preceding pattern in the case matches. If the guard expression
-evaluates to \verb@true@, the pattern match succeeds as normal. If the
-guard expression evaluates to \verb@false@, the pattern in the case
-is considered not to match and the search for a matching pattern
-continues.
-
-\comment{
-A case with several patterns $\CASE;p_1 \commadots p_n ;\IF; e \Arrow b$ is a
-shorthand for a sequence of single-pattern cases $\CASE;p_1;\IF;e \Arrow b
-;\ldots; \CASE;p_n ;\IF;e\Arrow b$. In this case none of the patterns
-$p_i$ may contain a named pattern variable (but the patterns may contain
-wild-cards).
-}
-
-In the interest of efficiency the evaluation of a pattern matching
-expression may try patterns in some other order than textual
-sequence. This might affect evaluation through
-side effects in guards. However, it is guaranteed that a guard
-expression is evaluated only if the pattern it guards matches.
-
-\example
-Often, pattern matching expressions are used as arguments
-of the \verb@match@ method, which is predefined in class \verb@Any@
-(\sref{sec:cls-object}) and is implemented there by postfix function
-application. Here is an example:
-\begin{verbatim}
-def length [a] (xs: List[a]) = xs match {
- case Nil => 0
- case x :: xs1 => 1 + length (xs1)
-}
-\end{verbatim}
-
-\chapter{Top-Level Definitions}
-\label{sec:topdefs}
-
-\syntax\begin{verbatim}
- CompilationUnit \=::=\= [package QualId `;'] {TopStat `;'} TopStat
- TopStat \>::=\> {Modifier} ClsDef
- \> |\> Import
- \> |\> Packaging
- \> |\>
- QualId \>::=\> id {`.' id}
-\end{verbatim}
-
-A compilation unit consists of a sequence of packagings, import
-clauses, and class and object definitions, which may be preceded by a
-package clause.
-
-A compilation unit \verb@package p; stats@ starting with a package
-clause is equivalent to a compilation unit consisting of a single
-packaging \verb@package p { stats }@.
-
-Implicitly imported into every compilation unit are, in that order:
-the package \verb@java.lang@, the package \verb@scala@, and the object
-\verb@scala.Predef@ (\sref{cls-predef}). Members of a later import in
-that order hide members of an earlier import.
-
-\section{Packagings}
-
-\syntax\begin{verbatim}
- Packaging \=::= \= package QualId `{' {TopStat `;'} TopStat `}'
-\end{verbatim}
-
-A package is a special object which defines a set of member classes,
-objects and packages. Unlike other objects, packages are not introduced
-by a definition. Instead, the set of members of a package is determined by
-packagings.
-
-A packaging \verb@package p { ds }@ injects all definitions in
-\verb@ds@ as members into the package whose qualified name is
-\verb@p@. If a definition in \verb@ds@ is labeled \verb@private@, it
-is visible only for other members in the package.
-
-Selections \verb@p.m@ from \verb@p@ as well as imports from \verb@p@
-work as for objects. However, unlike other objects, packages may not
-be used as values. It is illegal to have a package with the same fully
-qualified name as a module or a class.
-
-Top-level definitions outside a packaging are assumed to be injected
-into a special empty package. That package cannot be named and
-therefore cannot be imported. However, members of the empty package
-are visible to each other without qualification.
-
-\example The following example will create a hello world program as
-function \verb@main@ of module \verb@test.HelloWorld@.
-\begin{verbatim}
-package test;
-
-object HelloWord {
- def main(args: Array[String]) = System.out.println("hello world")
-}
-\end{verbatim}
-
-\end{document}
-
-\chapter{Local Type Inference}
-\label{sec:local-type-inf}
-
-This needs to be specified in detail.
-Essentially, similar to what is done for GJ.
-
-\comment{
-\section{Definitions}
-
-For a possibly recursive definition such as $\LET;x_1 = e_1
-;\ldots; \LET x_n = e_n$, local type inference proceeds as
-follows.
-A first phase assigns {\em a-priori types} to the $x_i$. The a-priori
-type of $x$ is the declared type of $x$ if a declared type is
-given. Otherwise, it is the inherited type, if one is
-given. Otherwise, it is undefined.
-
-A second phase assigns completely defined types to the $x_i$, in some
-order. The type of $x$ is the a-priori type, if it is completely
-defined. Otherwise, it is the a-priori type of $x$'s right hand side.
-The a-priori type of an expression $e$ depends on the form of $e$.
-\begin{enumerate}
-\item
-The a-priori type of a
-typed expression $e:T$ is $T$.
-\item
-The a-priori type of a class instance
-creation expression $c;\WITH;(b)$ is $C;\WITH;R$ where $C$ is the
-type of the class given in $c$ and $R$ is the a-priori type of block
-$b$.
-\item
-The a-priori type of a block is a record consisting the a-priori
-types of each non-private identifier which is declared in the block
-and which is visible at in last statement of the block. Here, it is
-required that every import clause $\IMPORT;e_1 \commadots e_n$ refers
-to expressions whose type can be computed with the type information
-determined so far. Otherwise, a compile time error results.
-\item
-The a-priori type of any other expression is the expression's type, if
-that type can be computed with the type information determined so far.
-Otherwise, a compile time error results.
-\end{enumerate}
-The compiler will find an ordering in which types are assigned without
-compiler errors to all variables $x_1 \commadots x_n$, if such an
-ordering exists. This can be achieved by lazy evaluation.
-}
-
-\chapter{The Scala Standard Library}
-
-The Scala standard library consists of the package \verb@scala@ with a
-number of classes and modules.
-
-\section{Root Classes}
-\label{sec:cls-root}
-\label{sec:cls-any}
-\label{sec:cls-object}
-
-The root of the Scala class hierarchy is formed by class \verb@Any@.
-Every class in a Scala execution environment inherits directly or
-indirectly from this class. Class \verb@Any@ has exactly two direct
-subclasses: \verb@AnyRef@ and\verb@AnyVal@.
-
-The subclass \verb@AnyRef@ represents all values which are represented
-as objects in the underlying host system. The type of the \verb@null@
-value copnforms to every subclass of \verb@AnyRef@. A direct subclass
-of
-\verb@AnyRef@ is class \verb@Object@. Every user-defined Scala
-class inherits directly or indirectly from this class. Classes written
-in other languages still inherit from \verb@scala.AnyRef@, but not
-necessarily from \verb@scala.Object@.
-
-The class \verb@AnyVal@ has a fixed number subclasses, which describe
-values which are not implemented as objects in the underlying host
-system.
-
-Classes \verb@AnyRef@ and \verb@AnyVal@ are required to provide only
-the members declared in class \verb@Any@, but implementations may add
-host-specific methods to these classes (for instance, an
-implementation may identify class \verb@AnyRef@ with its own root
-class for objects).
-
-The standard interfaces of these root classes is described by the
-following definitions.
-
-\begin{verbatim}
-abstract class Any with {
- /** Get runtime type descriptor */
- def getType: Type = ...
-
- /** Reference equality */
- def eq (that: Any): Boolean = ...
-
- /** Hash code */
- def def hashCode: Int = ...
-\end{verbatim}
-\begin{verbatim}
- /** Type test */
- def is [a]: Boolean = ...
-
- /** Type cast */
- def as[a]: a = if (is[a]) ... else new CastException() throw
-
- /** Semantic equality between values of same type */
- def == (that: Any): Boolean = this equals that
-
- /** Semantic inequality between values of same type */
- def != (that: Any): Boolean = !(this == that)
-
- /** Semantic equality between arbitrary values */
- def equals (that: Any): Boolean = ...
-
- /** Representation as string */
- def toString: String = getType.toString ++ "@" ++ hashCode
-
- /** Concatenation of string representations */
- final def + (that: Any) = toString.concat(that)
-
- /** Pattern matching application */
- final def match [a] (f: (Any)a): a = f(this)
-}
-final class AnyVal extends Any
-class AnyRef extends Any
-class Object extends AnyRef
-\end{verbatim}
-
-
-\section{Value Classes}
-\label{sec:cls-value}
-
-Value classes are classes whose instances are not represented as
-objects by the underlying host system. All value classes inherit from
-class \verb@AnyVal@. Scala implementations need to provide the
-following value classes (but are free to provide others as well).
-
-\begin{verbatim}
-final class Unit extends AnyVal with { ... }
-final class Boolean extends AnyVal with { ... }
-final class Double extends AnyVal with { ... }
-final class Float extends Double with { ... }
-final class Long extends Float with { ... }
-final class Int extends Long with { ... }
-final class Char extends Int with { ... }
-final class Short extends Int with { ... }
-final class Byte extends Short with { ... }
-\end{verbatim}
-
-These classes are defined in the following.
-
-\subsection{Class \prog{Double}}
-
-\begin{verbatim}
-final class Double extends AnyVal with Ord with {
- def asDouble: Double \=// convert to Double
- def asFloat: Float \>// convert to Float
- def asLong: Long \>// convert to Long
- def asInt: Int \>// convert to Int
- def asChar: Char \>// convert to Char
- def asShort: Short \>// convert to Short
- def asByte: Byte \>// convert to Byte
-
- def + (that: Double): Double \>// double addition
- def - (that: Double): Double \>// double subtraction
- def * (that: Double): Double \>// double multiplication
- def / (that: Double): Double \>// double division
- def % (that: Double): Double \>// double remainder
-
- def == (that: Double): Boolean \>// double equality
- def != (that: Double): Boolean \>// double inequality
- def < (that: Double): Boolean \>// double less
- def > (that: Double): Boolean \>// double greater
- def <= (that: Double): Boolean \>// double less or equals
- def >= (that: Double): Boolean \>// double greater or equals
-
- def - : Double = 0.0 - this \>// double negation
- def + : Double = this
-}
-\end{verbatim}
-
-\subsection{Class \prog{Float}}
-
-\begin{verbatim}
-final class Float extends Double with {
- def asDouble: Double \=// convert to Double
- def asFloat: Float \>// convert to Float
- def asLong: Long \>// convert to Long
- def asInt: Int \>// convert to Int
- def asChar: Char \>// convert to Char
- def asShort: Short \>// convert to Short
- def asByte: Byte \>// convert to Byte
-
- def + (that: Double): Double = asDouble + that
- def + (that: Float): Double \>// float addition
- /* analogous for -, *, /, % */
-
- def == (that: Double): Boolean = asDouble == that
- def == (that: Float): Boolean \>// float equality
- /* analogous for !=, <, >, <=, >= */
-
- def - : Float = 0.0f - this \>// float negation
- def + : Float = this
-}
-\end{verbatim}
-
-\subsection{Class \prog{Long}}
-
-\begin{verbatim}
-final class Long extends Float with {
- def asDouble: Double \=// convert to Double
- def asFloat: Float \>// convert to Float
- def asLong: Long \>// convert to Long
- def asInt: Int \>// convert to Int
- def asChar: Char \>// convert to Char
- def asShort: Short \>// convert to Short
- def asByte: Byte \>// convert to Byte
-
- def + (that: Double): Double = asDouble + that
- def + (that: Float): Double = asFloat + that
- def + (that: Long): Long = \>// long addition
- /* analogous for -, *, /, % */
-
- def << (cnt: Int): Long \>// long left shift
- def >> (cnt: Int): Long \>// long signed right shift
- def >>> (cnt: Int): Long \>// long unsigned right shift
- def & (that: Long): Long \>// long bitwise and
- def | (that: Long): Long \>// long bitwise or
- def ^ (that: Long): Long \>// long bitwise exclusive or
-
- def == (that: Double): Boolean = asDouble == that
- def == (that: Float): Boolean = asFloat == that
- def == (that: Long): Boolean \>// long equality
- /* analogous for !=, <, >, <=, >= */
-
- def - : Long = 0l - this \>// long negation
- def + : Long = this
-}
-\end{verbatim}
-
-
-\subsection{Class \prog{Int}}
-
-\begin{verbatim}
-class Int extends Long with {
- def asDouble: Double \=// convert to Double
- def asFloat: Float \>// convert to Float
- def asLong: Long \>// convert to Long
- def asInt: Int \>// convert to Int
- def asChar: Char \>// convert to Char
- def asShort: Short \>// convert to Short
- def asByte: Byte \>// convert to Byte
-
- def + (that: Double): Double = asDouble + that
- def + (that: Float): Double = asFloat + that
- def + (that: Long): Long = \>// long addition
- def + (that: Int): Int = \>// long addition
- /* analogous for -, *, /, % */
-
- def << (cnt: Int): Int \>// long left shift
- /* analogous for >>, >>> */
-
- def & (that: Long): Long = asLong & that
- def & (that: Int): Int \>// bitwise and
- /* analogous for |, ^ */
-
- def == (that: Double): Boolean = asDouble == that
- def == (that: Float): Boolean = asFloat == that
- def == (that: Long): Boolean \>// long equality
- /* analogous for !=, <, >, <=, >= */
-
- def - : Long = 0l - this \>// long negation
- def + : Long = this
-}
-\end{verbatim}
-
-\subsection{Class \prog{Boolean}}
-\label{sec:cls-boolean}
-
-\begin{verbatim}
-abstract final class Boolean extends AnyVal with Ord with {
- def ifThenElse[a](def t: a)(def e: a): a
-
- def ifThen(def t: Unit): Unit = ifThenElse(t)()
-
- def && (def x: Boolean): Boolean = ifThenElse(x)(False)
- def || (def x: Boolean): Boolean = ifThenElse(True)(x)
- def ! (def x: Boolean): Boolean = ifThenElse(False)(True)
-
- def == (x: Boolean): Boolean = ifThenElse(x)(x.!)
- def != (x: Boolean): Boolean = ifThenElse(x.!)(x)
- def < (x: Boolean): Boolean = ifThenElse(False)(x)
- def > (x: Boolean): Boolean = ifThenElse(x.!)(False)
- def <= (x: Boolean): Boolean = ifThenElse(x)(True)
- def >= (x: Boolean): Boolean = ifThenElse(True)(x.!)
-}
-case class True extends Boolean with { def ifThenElse(t)(e) = t }
-case class False extends Boolean with { def ifThenElse(t)(e) = e }
-\end{verbatim}
-
-
-\comment{
-\section{Reflection}
-
-\subsection{Classes \prog{Type}, \prog{Class}, \prog{CompoundType}}
-
-\begin{verbatim}
-class Type[A] with {
- def isSubType [B] (that: Type[B]): Boolean = ...
-}
-\end{verbatim}
-
-\begin{verbatim}
-class Class[A] extends Type[A] with {
- ...
-}
-\end{verbatim}
-
-\begin{verbatim}
-abstract class CompoundType[A] extends Type[A] with {
- def components: List[Class[A]]
- ...
-}
-\end{verbatim}
-}
-\section{Other Standard Classes}
-
-\subsection{Class \prog{Unit} and the \prog{Tuple} Classes}
-\label{sec:cls-tuple}
-
-\begin{verbatim}
-case class Unit with {
- def toString = "()"
-}
-case class Tuple$\,n$[a$_1$, ..., a$_n$](x$_1$: a$_1$, ..., x$_n$: a$_n$) with {
- def $\_1$: a$_1$ = x$_1$
- ...
- def $\_n$: a$_n$ = x$_n$
- def toString = "(" ++ x$_1$ ++ "," ++ ... ++ x$_n$ ++ ")"
-}
-\end{verbatim}
-
-\subsection{The \prog{Function} Classes}
-\label{sec:cls-function}
-
-\begin{verbatim}
-class Function$\,n$[a$_1$, ..., a$_n$,b] with {
- // some methods in Any are overwritten
- def apply(x$_1$: a$_1$, ..., x$_n$: a$_n$): b
-}
-\end{verbatim}
-Class \verb@Function1@ additionally defines the method
-\begin{verbatim}
- def o [c] (f: Function1[c,a$_1$]): Function1[c,b] = x: c => apply(f(x))
-\end{verbatim}
-There is also a module \verb@Function@, defined as follows.
-\begin{verbatim}
-module Function {
- def compose[a](fs: List[(a)a]): (a)a = {
- x => fs match {
- case Nil => x
- case f :: fs1 => compose(fs1)(f(x))
- }
- }
-}
-\end{verbatim}
-A subclass of \verb@Function$\,n$@ describes partial functions, which
-are undefined on some points in their domain.
-
-\begin{verbatim}
-class PartialFunction$\,n$[a$_1$, ..., a$_n$,b] extends Function$\,n$[a$_1$, ..., a$_n$,b] with {
- def isDefined(x$_1$: a$_1$, ..., x$_n$: a$_n$): Boolean
-}
-\end{verbatim}
-
-In addition to the \verb@apply@ method of functions, partial functions
-also have a \verb@isDefined@ method, which tells whether the function
-is defined at the given argument.
-
-Classes \verb@Function@ and \verb@PartialFunction@ are defined to be aliases for
-\verb@Function1@ and \verb@PartialFunction1@:
-\begin{verbatim}
- type Function[a,b] = Function1[a,b]
- type PartialFunction[a,b] = PartialFunction1[a,b]
- def Function[a,b]: class Function1[a,b] = Function1[a,b]
- def PartialFunction[a,b]: class PartialFunction1[a,b] = PartialFunction1[a,b]
-\end{verbatim}
-
-\subsection{Class \prog{List}}\label{cls-list}
-
-\begin{verbatim}
-abstract class List[a] with {
- abstract def isEmpty: Boolean;
- abstract def head: a;
- abstract def tail: List[a];
-
- def ::(x: a): List[a] =
- new ::_class(x)(this);
-
- def :::(prefix: List[a]): List[a] =
- if (prefix.isEmpty) this
- else prefix.head :: (prefix.tail ::: this);
-
- def length: Int = {
- this match {
- case [] => 0
- case _ :: xs => xs.length + 1}
- }
-\end{verbatim}
-\begin{verbatim}
- def init: List[a] =
- if (isEmpty) error("Nil.init")
- else if (tail.isEmpty) Nil
- else head :: tail.init;
-
- def last: a =
- if (isEmpty) error("Nil.last")
- else if (tail.isEmpty) head
- else tail.last;
-
- def take(n: Int): List[a] =
- if (n == 0) Nil
- else head :: tail.take(n-1);
-
- def drop(n: Int): List[a] =
- if (n == 0) this
- else tail.drop(n-1);
-
- def takeWhile(p: (a)Boolean): List[a] =
- if (isEmpty || !p(head)) Nil
- else head :: tail.takeWhile(p);
-
- def dropWhile(p: (a)Boolean): List[a] =
- if (isEmpty || !p(head)) this
- else tail.dropWhile(p);
-
- def at(n: Int) = drop(n).head;
-\end{verbatim}
-\begin{verbatim}
- def map[b](f: (a)b): List[b] =
- if (isEmpty) Nil
- else f(head) :: tail.map(f);
-
- def foreach(f: (a)Unit): Unit =
- if (isEmpty) ()
- else (f(head); tail.foreach(f));
-
- def filter(p: (a)Boolean): List[a] =
- if (isEmpty) this
- else if (p(head)) head :: tail.filter(p)
- else tail.filter(p);
-
- def forall(p: (a)Boolean): Boolean =
- isEmpty || (p(head) && tail.forall(p));
-
- def exists(p: (a)Boolean): Boolean =
- !isEmpty && (p(head) || tail.exists(p));
-\end{verbatim}
-\begin{verbatim}
- def :_foldl[b](z: b)(f: (b, a)b) = match {
- case [] => z
- case x :: xs => (f(z, x) :_foldl xs)(f)
- }
-
- def foldr[b](z: b)(f: (a, b)b) = match {
- case [] => z
- case x :: xs => f(x, (xs foldr z)(f))
- }
-
- def redl(f: (a, a)a) = match {
- case [] => error("redl of empty list")
- case x :: xs => (x :_foldl xs)(f)
- }
-
- def redr(f: (a, a)a): a = match {
- case [] => error("redr of empty list")
- case [x] => x
- case x :: xs => f(x, xs redr f)
- }
-\end{verbatim}
-\begin{verbatim}
- def flatMap[b](f: (a)List[b]): List[b] =
- if (isEmpty) Nil
- else f(head) ::: tail.flatMap(f);
-
- def reverse: List[a] = {
- def snoc(xs: List[a], x: a): List[a] = x :: xs;
- fold(snoc)(Nil)
- }
-
- def print: Unit =
- if (isEmpty) System.out.println("[]")
- else {
- System.out.print(head.as[java.lang.Object]);
- System.out.print(" :: ");
- tail.print
- }
-
- def toArray: Array[a] = {
- val xs = new Array[a](length);
- copyToArray(xs, 0);
- xs
- }
-
- def copyToArray(xs: Array[a], start: Int): Int = {
- xs(start) = head;
- tail.copyToArray(xs, start + 1)
- }
-\end{verbatim}
-\begin{verbatim}
- def mkString(start: String, sep: String, end: String): String =
- start +
- (if (isEmpty) end
- else if (tail.isEmpty) head.toString() + end
- else head.toString().concat(sep).concat(tail.mkString("", sep, end)));
-
- def zip[b](that: List[b]): List[(a,b)] =
- if (this.isEmpty || that.isEmpty) Nil
- else (this.head, that.head) :: this.tail.zip(that.tail);
-\end{verbatim}
-\begin{verbatim}
- def contains(elem: a) = exists(x => x == elem);
-
- def union(that: List[a]): List[a] =
- if (this.isEmpty) that
- else {
- val result = this.tail union that;
- if (that contains this.head) result else this.head :: result;
- }
-
- def diff(that: List[a]): List[a] =
- if (that.isEmpty) this
- else {
- val result = this.tail diff that;
- if (that contains this.head) result else this.head :: result;
- }
-
- def intersect(that: List[a]): List[a] = filter(x => that contains x);
-
- def removeDuplicates: List[a] =
- if (isEmpty) this
- else {
- val rest = tail.removeDuplicates;
- if (rest contains head) rest else head :: rest
- }
-}
-\end{verbatim}
-\begin{verbatim}
-final case class ::_class[b](hd: b)(tl: List[b]) extends List[b] with {
- def isEmpty = False;
- def head = hd;
- def tail = tl;
- override def toString(): String = mkString("[", ",", "]");
-}
-\end{verbatim}
-\begin{verbatim}
-final case class Nil[c] extends List[c] with {
- def isEmpty = True;
- def head: c = error("head of empty list");
- def tail: List[c] = error("tail of empty list");
- override def toString(): String = "[]";
-}
-\end{verbatim}
-
-\subsection{Class \prog{Array}}
-
-The class of generic arrays is defined as follows.
-
-\begin{verbatim}
-class Array[a](l: int) extends Function[Int, a] with {
- def length: int = l
- def apply(i: Int): a = ...
- def update(i: Int)(x: a): Unit = ...
-}
-\end{verbatim}
-\comment{
-\begin{verbatim}
-module Array {
- def create[a](i1: Int): Array[a] = Array[a](i1)
- def create[a](i1: Int, i2: Int): Array[Array[a]] = {
- val x: Array[Array[a]] = create(i1)
- 0 to (i1 - 1) do { i => x(i) = create(i2) }
- x
- }
- ...
- def create[a](i1: Int, i2: Int, i3: Int, i4: Int, i5: Int,
- i6: Int, i7: Int, i8: Int, i9: Int, i10: Int)
- : Array[Array[Array[Array[Array[Array[Array[Array[Array[Array[a]]]]]]]]]] = {
- val x: Array[Array[Array[Array[Array[Array[Array[Array[Array[a]]]]]]]]] = create(i1)
- 0 to (i1 - 1) do { i => x(i) = create(i2, i3, i4, i5, i6, i7, i8, i9, i10) }
- x
- }
-}
-\end{verbatim}
-}
-\section{Exceptions}
-\label{sec:exceptions}
-
-There is a predefined type \verb@Throwable@, as well as functions to
-throw and handle values of type \verb@Throwable@. These are declared
-as follows.
-
-\begin{verbatim}
- class Throwable with {
- def throw[a]: a
- }
- class ExceptOrFinally[a] with {
- def except (handler: PartialFunction[Throwable,a]): a
- def finally (def handler: Unit): a
- }
- def try [a] (def body: a): ExceptOrFinally[a]
-\end{verbatim}
-
-The type \verb@Throwable@ represents exceptions and error objects; it
-may be identified with an analogous type of the underlying
-implementation such as \verb@java.lang.Throwable@. We will in the
-following loosely call values of type \verb@Throwable@ exceptions.
-
-The \verb@throw@ method in \verb@Throwable@ aborts execution of the
-thread executing it and passes the thrown exception to the handler
-that was most recently installed by a
-\verb@try@ function in the current thread. If no \verb@try@ method is
-active, the thread terminates.
-
-The \verb@try@ function executes its body with the given exception
-handler. A \verb@try@ expression comes in two forms. The first form is
-
-\begin{verbatim}
-try $body$ except $handler$ .
-\end{verbatim}
-
-If $body$ executes without an exception being thrown, then executing
-the try expression is equivalent to just executing $body$. If some
-exception is thrown from within $body$ for which \verb@handler@ is defined,
-the handler is invoked with the thrown exception as argument.
-
-The second form of a try expression is
-
-\begin{verbatim}
-try $body$ finally $handler$ .
-\end{verbatim}
-
-This expression will execute $body$. A normal execution of $body$ is
-followed by an invocation of the $handler$ expression. The $handler$
-expression does not take arguments and has \verb@Unit@ as result type.
-If execution of the handler expression throws an exception, this
-exception is propagated out of the \verb@try@ statement. Otherwise,
-if an exception was thrown in $body$ prior to invocation of $handler$,
-that exception is re-thrown after the invocation. Finally, if both
-$body$ and $handler$ terminate normally, the original result of
-$body$ is the result of the \verb@try@ expression.
-
-\example An example of a try-except expression:
-
-\begin{verbatim}
-try {
- System.in.readString()
-} except {
- case ex: EndOfFile => ""
-}
-\end{verbatim}
-
-\example An example of a try-finally expression:
-
-\begin{verbatim}
-file = open (fileName)
-if (file != null) {
- try {
- process (file)
- } finally {
- file.close
- }
-}
-\end{verbatim}
-
-\section{Concurrency}
-\label{sec:concurrency}
-
-\subsection{Basic Concurrency Constructs}
-
-Scala programs may be executed by several threads that operate
-concurrently. The thread model used is based on the model of the
-underlying run-time system. We postulate a predefined
-class \verb@Thread@ for run-time threads,
-\verb@fork@ function to spawn off a new thread,
-as well as \verb@Monitor@ and \verb@Signal@ classes. These are
-specified as follows\nyi{Concurrentcy constructs are}.
-
-
-\begin{verbatim}
-class Thread with { ... }
-def fork (def p: Unit): Thread
-\end{verbatim}
-
-The \verb@fork@ function runs its argument computation \verb@p@ in a
-separate thread. It returns the thread object immediately to its
-caller. Unhandled exceptions (\sref{sec:exceptions}) thrown during
-evaluation of \verb@p@ abort execution of the forked thread and are
-otherwise ignored.
-
-\begin{verbatim}
-class Monitor with {
- def synchronized [a] (def e: a): a
-}
-\end{verbatim}
-
-Monitors define a \verb@synchronized@ method which provides mutual
-exclusion between threads. It executes its argument computation
-\verb@e@ while asserting exclusive ownership of the monitor
-object whose method is invoked. If some other thread has ownership of
-the same monitor object, the computation is delayed until the other
-process has relinquished its ownership. Ownership of a monitor is
-relinquished at the end of the argument computation, and while the
-computation is waiting for a signal.
-
-\begin{verbatim}
-class Signal with {
- def wait: Unit
- def wait(msec: Long): Unit
- def notify: Unit
- def notifyAll: Unit
-}
-\end{verbatim}
-
-The \verb@Signal@ class provides the basic means for process
-synchronization. The \verb@wait@ method of a signal suspends the
-calling thread until it is woken up by some future invocation of the
-signal's \verb@notify@ or \verb@notifyAll@ method. The \verb@notify@
-method wakes up one thread that is waiting for the signal. The
-\verb@notifyAll@ method wakes up all threads that are waiting for the
-signal. A second version of the \verb@wait@ method takes a time-out
-parameter (given in milliseconds). A thread calling \verb@wait(msec)@
-will suspend until unblocked by a \verb@notify@ or \verb@notifyAll@
-method, or until the \verb@msec@ millseconds have passed.
-
-\subsection{Channels}
-
-\begin{verbatim}
-class Channel[a] with {
- def write(x: a): Unit
- def read: a
-}
-\end{verbatim}
-
-An object of type \verb@Channel[a]@ Channels offer a write-operation
-which writes data of type \verb@a@ to the channel, and a read
-operation, which returns written data as a result. The write operation
-is non-blocking; that is it returns immediately without waiting for
-the written data to be read.
-
-\subsection{Message Spaces}
-
-The Scala library also provides message spaces as a higher-level,
-flexible construct for process synchronization and communication. A
-{\em message} is an arbitrary object that inherits from the
-\verb@Message@ class.
-There is a special message \verb@TIMEOUT@ which is used to signal a time-out.
-\begin{verbatim}
-class Message
-case class TIMEOUT extends Message
-\end{verbatim}
-Message spaces implement the following class.
-\begin{verbatim}
-class MessageSpace with {
- def send(msg: Message): Unit
- def receive[a](f: PartialFunction1[Message, a]): a
- def receiveWithin[a](msec: Long)(f: PartialFunction1[Message, a]): a
-}
-\end{verbatim}
-The state of a message space consists of a multi-set of messages.
-Messages are added to the space using the \verb@send@ method. Messages
-are removed using the \verb@receive@ method, which is passed a message
-processor \verb@f@ as argument, which is a partial function from
-messages to some arbitrary result type. Typically, this function is
-implemented as a pattern matching expression. The \verb@receive@
-method blocks until there is a message in the space for which its
-message processor is defined. The matching message is then removed
-from the space and the blocked thread is restarted by applying the
-message processor to the message. Both sent messages and receivers are
-ordered in time. A receiver $r$ is applied to a matching message $m$
-only if there is no other (message, receiver) pair which precedes $(m,
-r)$ in the partial ordering on pairs that orders each component in
-time.
-
-The message space class also offers a method \verb@receiveWithin@
-which blocks for only a specified maximal amount of time. If no
-message is received within the specified time interval (given in
-milliseconds), the message processor argument $f$ will be unblocked
-with the special \verb@TIMEOUT@ message.
-
-\appendix
-\chapter{Scala Syntax Summary}
-
-The lexical syntax of Scala is given by the following grammar in EBNF
-form.
-
-\begin{verbatim}
- upper \=::= \=`A' | ... | `Z' | `$\Dollar$' | `_'
- lower \>::= \>`a' | ... | `z'
- letter \>::= \>upper | lower
- digit \>::= \>`0' | ... | `9'
- special \>::= \>``everything else except parentheses ([{}]) and period''
-
- op \>::= \>special {special} [`_' [id]]
- varid \>::= \>lower {letter | digit} [`_' [id]]
- id \>::= \>upper {letter | digit} [`_' [id]]
- \> |\>varid
- \> |\>op
-
- intLit \>::= \>``as in Java''
- floatLit \>::= \>``as in Java''
- charLit \>::= \>``as in Java''
- stringLit \>::= \>``as in Java''
-
- comment \>::= \>`/*' ``any sequence of characters'' `*/'
- \> |\>`//' `any sequence of characters up to end of line''
-\end{verbatim}
-
-The context-free syntax of Scala is given by the following EBNF
-grammar.
-
-\begin{verbatim}
- literal \=::= \= intLit
- \> |\> floatLit
- \> |\> charLit
- \> |\> stringLit
- \> |\> symbolLit
-\end{verbatim}
-
-\begin{verbatim}
- StableId \=::= \= id
- \> |\> Path `.' id
- Path \>::=\> StableId
- \> |\> [id `.'] this
- \> |\> [id '.'] super [`[' id `]']`.' id
-
- Type \>::= \> Type1 `=>' Type
- \> |\> `(' [Types] `)' `=>' Type
- \> |\> Type1
- Type1 \>::= \> SimpleType {with SimpleType} [Refinement]
- SimpleType \>::= \> SimpleType TypeArgs
- \> |\> SimpleType `#' id
- \> |\> StableId
- \> |\> Path `.' type
- \> |\> `(' Type ')'
- TypeArgs \>::= \> `[' Types `]'
- Types \>::= \> Type {`,' Type}
- Refinement \>::=\> `{' [RefineStat {`;' RefineStat}] `}'
- RefineStat \>::=\> Dcl
- \> |\> type TypeDef {`,' TypeDef}
- \> |\>
-
- Exprs \>::=\> Expr {`,' Expr}
- Expr \>::=\> [Bindings `=>'] Expr
- \> |\> if `(' Expr `)' Expr [[`;'] else Expr]
- \> |\> try `{' block `}' [catch Expr] [finally Expr]
- \> |\> do Expr [`;'] while `(' Expr ')'
- \> |\> for `(' Enumerators `)' (do | yield) Expr
- \> |\> [SimpleExpr `.'] id `=' Expr
- \> |\> SimpleExpr ArgumentExpr `=' Expr
- \> |\> PostfixExpr [`:' Type1]
- PostfixExpr \>::=\> InfixExpr [id]
- InfixExpr \>::=\> PrefixExpr
- \> |\> InfixExpr id InfixExpr
- PrefixExpr \>::=\> [`-' | `+' | `~' | `!'] SimpleExpr
- SimpleExpr \>::=\> literal
- \> |\> true
- \> |\> false
- \> |\> null
- \> |\> Path
- \> |\> `(' [Expr] `)'
- \> |\> BlockExpr
- \> |\> new Template
- \> |\> SimpleExpr `.' id
- \> |\> id `#' id
- \> |\> SimpleExpr TypeArgs
- \> |\> SimpleExpr ArgumentExpr
- ArgumentExpr \>::=\> `(' Expr ')'
- \> |\> BlockExpr
- BlockExpr \>::=\> `{' CaseClause {CaseClause} `}'
- \> |\> `{' Block `}'
- Block \>::=\> {BlockStat `;'} [Expr]
-\end{verbatim}
-
-\begin{verbatim}
- Enumerators \=::= \= Generator {`;' Enumerator}
- Enumerator \>::=\> Generator
- \> |\> Expr
- Generator \>::=\> val Pattern `<-' Expr
- Block \>::=\> {BlockStat `;'} [Expr]
- BlockStat \>::=\> Import
- \> |\> Def
- \> |\> {LocalModifier} ClsDef
- \> |\> Expr
- \> |\>
-
- CaseClause \>::=\> case Pattern [`if' PostfixExpr] `=>' Block
-
- Constr \>::=\> StableId [TypeArgs] [`(' [Exprs] `)']
-
- Pattern \>::= \= TreePattern { `|' TreePattern }
-
- TreePattern \>::= \> varid `:' Type
- \> | \> `_' `:' Type
- \> | \> SimplePattern [ '*' | '?' | '+' ]
- \> | \> SimplePattern { id SimplePattern }
-
- SimplePattern \>::= \> varid [ '@' SimplePattern ]
- \> | \> `_'
- \> | \> literal
- \> | \> StableId [ `(' [Patterns] `)' ]
- \> | \> `(' Patterns `)'
- \> | \>
-
- Patterns \>::= \> Pattern {`,' Pattern}
-
- TypeParamClause \>::=\> `[' TypeParam {`,' TypeParam} `]'
- FunTypeParamClause \>::=\> `[' TypeDcl {`,' TypeDcl} `]'
- TypeParam \>::=\> [`+' | `-'] TypeDcl
- ParamClause \>::=\> `(' [Param {`,' Param}] `)'
- Param \>::=\> [def] id `:' Type [`*']
- Bindings \>::=\> id [`:' Type1]
- \> |\> `(' Binding {`,' Binding `)'
- Binding \>::=\> id [`:' Type]
-
- Modifier \>::=\> LocalModifier
- \> |\> private
- \> |\> protected
- \> |\> override
- LocalModifier \>::=\> abstract
- \> |\> final
- \> |\> sealed
-
- Template \>::=\> Constr {`with' Constr} [TemplateBody]
- TemplateBody \>::=\> `{' [TemplateStat {`;' TemplateStat}] `}'
-\end{verbatim}
-\begin{verbatim}
- TemplateStat \=::= \= Import
- \> |\> {Modifier} Def
- \> |\> {Modifier} Dcl
- \> |\> Expr
- \> |\>
-
- Import \>::=\> import ImportExpr {`,' ImportExpr}
- ImportExpr \>::=\> StableId `.' (id | `_' | ImportSelectors)
- ImportSelectors \>::=\> `{' {ImportSelector `,'} (ImportSelector | `_') `}'
- ImportSelector \>::=\> id [`=>' id | `=>' `_']
-
- Dcl \>::=\> val ValDcl {`,' ValDcl}
- \> |\> var VarDcl {`,' VarDcl}
- \> |\> def FunDcl {`,' FunDcl}
- \> |\> type TypeDcl {`,' TypeDcl}
- ValDcl \>::=\> id `:' Type
- VarDcl \>::=\> id `:' Type
- FunDcl \>::=\> id [FunTypeParamClause] {ParamClause} `:' Type
- TypeDcl \>::=\> id [`>:' Type] [`<:' Type]
-
- Def \>::=\> val PatDef {`,' PatDef}
- \> |\> var VarDef {`,' VarDef}
- \> |\> def FunDef {`,' FunDef}
- \> |\> type TypeDef {`,' TypeDef}
- \> |\> ClsDef
- PatDef \>::=\> Pattern `=' Expr
- VarDef \>::=\> id [`:' Type] `=' Expr
- \> |\> id `:' Type `=' `_'
- FunDef \>::=\> id [FunTypeParamClause] {ParamClause} [`:' Type] `=' Expr
- | this ParamClause `=' ConstrExpr
- TypeDef \>::=\> id [TypeParamClause] `=' Type
- ClsDef \>::=\> ([case] class | trait) ClassDef {`,' ClassDef}
- \> |\> [case] object ObjectDef {`,' ObjectDef}
- ClassDef \>::=\> id [TypeParamClause] [ParamClause] [`:' SimpleType] ClassTemplate
- ObjectDef \>::=\> id [`:' SimpleType] ClassTemplate
- ClassTemplate \>::=\> extends Template
- \> |\> TemplateBody
- \> |\>
- ConstrExpr \>::=\> this ArgumentExpr
- \> |\> `{' {BlockStat `;'} this ArgumentExpr {`;' BlockStat} `}'
-
- CompilationUnit \>::=\> [package QualId `;'] {TopStat `;'} TopStat
- TopStat \>::=\> {Modifier} ClsDef
- \> |\> Import
- \> |\> Packaging
- \> |\>
- Packaging \>::=\> package QualId `{' {TopStat `;'} TopStat `}'
- QualId \>::=\> id {`.' id}
-\end{verbatim}
-
-case class extends { ... }
-
-trait List { }
-class Nil
-class Cons
-
-\comment{changes:
- Type \=::= \= SimpleType {with SimpleType} [with Refinement]
- \> |\> class SimpleType
- SimpleType \>::=\> SimpleType [TypeArgs]
- \> |\> `(' [Types] `)'
- \> |\>
- \> |\> this
-}
-\end{document}
-
-\comment{changes:
-
- Type \=::= \= SimpleType {with SimpleType} [with Refinement]
- \> |\> class SimpleType
- SimpleType \>::=\> TypeDesignator [TypeArgs]
- \> |\> `(' Type `,' Types `)'
- \> |\> `(' [Types] `)' Type
- \> |\> this
-
- PureDef \>::=\> module ModuleDef {`,' ModuleDef}
- \>::=\> def FunDef {`,' FunDef}
- \> |\> type TypeDef {`,' TypeDef}
- \> |\> [case] class ClassDef {`,' ClassDef}
- \> |\> case CaseDef {`,' CaseDef}
- CaseDef \>::=\> Ids ClassTemplate
-
- Modifier \>::=\> final
- \> |\> private
- \> |\> protected
- \> |\> override [QualId]
- \> |\> qualified
- \> |\> abstract
-
-\section{Class Aliases}
-\label{sec:class-alias}
-
-\syntax\begin{verbatim}
- ClassDef \=::= \= ClassAlias
- InterfaceDef \>::= \> ClassAlias
- ClassAlias \>::= \> id [TypeParamClause] `=' SimpleType
-\end{verbatim}
-
-Classes may also be defined to be aliases for other classes. A class
-alias is of the form $\CLASS;c[tps] = d[targs]$ where $d[targs]$ is a
-class type. Both $tps$ and $targs$ may be empty.
-This introduces the type $c[tps]$ as an alias for type
-$d[targs]$, in the same way the following type alias definition would:
-\begin{verbatim}
-type c[tps] = d[targs]
-\end{verbatim}
-The class alias definition is legal if the type alias definition would be legal.
-
-Assuming $d$ defines a class with type parameters $tps'$ and
-parameters $(ps_1) \ldots (ps_n)$, the newly defined type is also
-introduced as a class with a constructor which takes type parameters
-$[tps]$, and which takes value parameters
-$([targs/tps']ps_1)\ldots([targs/tps']ps_n)$.
-
-The modifiers \verb@private@ and
-\verb@protected@ apply to a class alias independently of the class it represents.
-The class $c$ is regarded as final if $d$ is final, or if a
-\verb@final@ modifier is given for the alias definition.
-$c$ is regarded as a case class iff $d$ is one. In this
-case,
-\begin{itemize}
-\item the alias definition may also be prefixed with \verb@case@, and
-\item the case constructor is also aliased, as if it was
-defined such:
-\begin{verbatim}
-def c[tps](ps$_1$)\ldots(ps$_n$):D = d[targs]$([targs/tps']ps$_1$)\ldots([targs/tps']ps$_n$)$ .
-\end{verbatim}
-The new function $c$ is again classified as a case constructor, so
-it may appear in constructor patterns (\sref{sec:patterns}).
-\end{itemize}
-Aliases for interfaces follow the same rules as class aliases, but
-start with \verb@interface@ instead of \verb@class@.
-}
-
-type T extends { ... }
-
-class C extends { ... }
-
-new C { ... }
-
-type C
-class C < { ... }
-
-A & B & C &
-\ifqualified{
-Parameter clauses (\sref{sec:funsigs}),
-definitions that are local to a block (\sref{sec:blocks}), and import
-clauses always introduce {\em simple names} $x$, which consist of a
-single identifier. On the other hand, definitions and declarations
-that form part of a module (\sref{sec:modules}) or a class
-(\sref{sec:classes}) conceptually always introduce {\em qualified
-names}\nyi{Qualified names are}
-$Q\qex x$ where a simple name $x$ comes with a qualified
-identifier $Q$. $Q$ is either the fully qualified name of a module or
-class which is labelled
-\verb@qualified@, or it is the empty name $\epsilon$.
-
-The {\em fully qualified name} of a module or class $M[targs]$ with
-simple name $M$ and type arguments $[targs]$ is
-\begin{itemize}
-\item $Q.M$, if the definition of $M$ appears in the template defining
-a module or class with fully qualified name $Q$.
-\item
-$M$ if the definition of $M$ appears on the top-level or as a definition
-in a block.
-\end{itemize}
-}
-
-\ifqualified{
-It is possible that a definition in some class or module $M$
-introduces several qualified names $Q_1\qex x \commadots Q_n\qex x$ in a name
-space that have the same simple name suffix but different qualifiers
-$Q_1 \commadots Q_n$. This happens for instance if a module \verb@M@
-implements two qualified classes \verb@C@, \verb@D@ that each define a
-function \verb@f@:
-\begin{verbatim}
-qualified abstract class B { def f: Unit = ""}
-qualified abstract class C extends B { def f: Unit }
-qualified abstract class D extends B { def f: Unit }
-
-module M extends C with D with {
- override C def f = println("C::f")
- override D def f = println("D::f")
- \=
- // f \>// error: ambiguous
- (this:D).f \>// prints ``D::f''
-}
-
-def main() = (M:C).f \>// prints ``C::f''
-\end{verbatim}
-Members of modules or classes are accessed using simple names,
-not qualified names.
-
-The {\em qualified expansion} of a simple name $x$ in some type $T$ is
-determined as follows: Let $Q_1\qex x \commadots Q_n\qex x$ be all the
-qualified names of members of $T$ that have a simple name suffix $x$.
-If one of the qualifiers $Q_i$ is the empty name $\epsilon$, then the
-qualified expansion of $x$ in $T$ is $\epsilon\qex x$. Otherwise, let
-$C_1
-\commadots C_n$ be the base classes (\sref{sec:base-classes})
-of $T$ that have fully qualified
-names $Q_1
-\commadots Q_n$, respectively. If there exists a least class $C_j$
-among the $C_i$ in the subclass ordering, then the qualified expansion
-of $x$ in $T$ is $Q_j\qex x$. Otherwise the qualified expansion does not
-exist.
-
-Conversely, if $Q\qex x$ is the qualified expansion of some simple
-name $x$ in $M$, we say that the entity named $Q\qex x$ in $M$ is {\em
-identified in $M$ by the simple name} $x$. We leave out the
-qualification ``in $M$'' if it is clear from the context.
-In the example above, the qualified expansion of \verb@f@ in \verb@C@
-is \verb@C::f@, because \verb@C@ is a subclass of \verb@B@. On the
-other hand, the qualified expansion of \verb@f@ in \verb@M@ does not
-exist, since among the two choices \verb@C::f@ and \verb@D::f@ neither
-class is a subclass of the other.
-
-A member access $e.x$ of some type term $e$ of type $T$ references the
-member identified in $T$ by the simple name $x$ (i.e.\ the member
-which is named by the qualified expansion of $x$ in $T$).
-
-In the example above, the simple name \verb@f@ in \verb@M@ would be
-ambiguous since the qualified expansion of \verb@f@ in \verb@M@ does
-not exist. To reference one of the two functions with simple name
-\verb@f@, one can use an explicit typing. For instance, the name
-\verb@(this:D).f@ references the implementation of \verb@D::f@ in
-\verb@M@.
-}
-
-\comment{
-\example The following example illustrates the difference between
-virtual and non-virtual members with respect to overriding.
-
-\begin{verbatim}
-class C with {
- virtual def f = "f in C"
- def g = "g in C"
- def both1 = this.f ++ ", " ++ this.g
- def both2 = f ++ ", " ++ g
-}
-
-class D extends C with {
- override def f = "f in D"
- override def g = "redefined g in D"
- new def g = "new g in D"
-}
-
-val d = D
-println(d.f) \=// prints ``f in D''
-println(d.g) \>// prints ``new g in D''
-println(d.both1) \>// prints ``f in D, redefined g in D''
-println(d.both2) \>// prints ``f in D, g in C''
-
-val c: C = d
-println(c.f) \=// prints ``f in D''
-println(c.g) \>// prints ``redefined g in D''
-println(c.both1) \>// prints ``f in D, redefined g in D''
-println(c.both2) \>// prints ``f in D, g in C''
-\end{verbatim}
-}
-
-\comment{
-\section{The Self Type}
-\label{sec:self-type}
-
-\syntax\begin{verbatim}
-SimpleType \=::= \= $\This$
-\end{verbatim}
-
-The self type \verb@this@ may be used in the statement part of a
-template, where it refers to the type of the object being defined by
-the template. It is the type of the self reference \verb@this@.
-
-For every leaf class (\sref{sec:modifiers}) $C$, \verb@this@ is
-treated as an alias for the class itself, as if it was declared such:
-\begin{verbatim}
-final class C ... with {
- type this = C
- ...
-}
-\end{verbatim}
-For non-leaf classes $C$, \verb@this@ is treated as an abstract type
-bounded by the class itself, as if it was declared such:
-\begin{verbatim}
-abstract class C ... with {
- type this extends C
- ...
-}
-\end{verbatim}
-
-Analogously, for every compound type \verb@$T_1$ with ... with $T_n$@,
-\verb@this@ is treated as an abstract type conforming to the whole compound
-type, as if it was bound in the refinement
-\begin{verbatim}
-type this extends $T_1$ with ... with $T_n$ .
-\end{verbatim}
-Finally, for every declaration of a parameter or abstract type
-\mbox{$a \extends T$}, \verb@this@ is treated as an an abstract type
-conforming to $a$, as if the bound type $T$ was augmented to
-\verb@$T$ with { abstract type this extends $a$ }@.
-On the other hand, if the parameter or abstract type is declared
-\verb@final@, as in $\FINAL;a \extends T$, then \verb@this@ is treated as an alias
-for $a$, as if the bound type $T$ was augmented to
-\verb@$T$ with { type this = $a$ }@.
-
-\example
-Consider the following classes for one- and two-dimensional
-points with a \verb@distance@ method that computes the distance
-between two points of the same type.
-\begin{verbatim}
-class Point1D(x: Float) with {
- def xCoord = x
- def distance (that: this) = abs(this.xCoord - that.xCoord)
- def self: this = this
-}
-final class FinalPoint1D(x: Float) extends Point1D(x)
-
-class Point2D(x: Float, y: Float) extends Point1D(x) with {
- def yCoord = y
- override def distance(that: this) =
- sqrt (square(this.xCoord - that.xCoord) + square(this.yCoord - that.yCoord))
-}
-\end{verbatim}
-Assume the following definitions:
-\begin{verbatim}
-val p1f: FinalPoint1D = FinalPoint1D(0.0)
-val p1a: Point1D = p1f
-val p1b: Point1D = Point2D(3.0, 4.0)
-\end{verbatim}
-Of the following expressions, three are well-formed, the other three
-are ill-formed.
-\begin{verbatim}
-p1f distance p1f \=// OK, yields 0,0
-p1f distance p1b \>// OK, yields 3.0
-p1a distance p1a \>// OK, yields 0.0
-p1a distance p1f \>// ERROR, required: p1a.this, found: FinalPoint1D
-p1a distance p1b \>// ERROR, required: p1a.this, found: p1b.this
-p1b distance p1a \>// ERROR, required: p1b.this, found: p1a.this
-\end{verbatim}
-The last of these expressions would cause an illegal access to a
-non-existing class \verb@yCoord@ of an object of type \verb@Point1D@,
-if it were permitted to execute in spite of being not well-typed.
-}
-
-\iflet{
-\section{Let Definitions}
-\label{sec:letdef}
-
-\syntax\begin{verbatim}
- PureDef \=::= \= $\LET$ ValDef {`,' ValDef}
- ValDef \>::= \> id [`:' Type] `=' Expr
-\end{verbatim}
-
-A let definition $\LET;x: T = e$ defines $x$ as a name of the value
-that results from the delayed evaluation of $e$. The type $T$ must be
-a concrete value type (\sref{sec:types}) and the type of the
-expression $e$ must conform to $T$. The effect of the let definition
-is to bind the left-hand side $x$ to the result of evaluating $e$
-converted to type $T$. However, the expression $e$ is not evaluated
-at the point of the let definition, but is instead evaluated the first
-time $x$ is dereferenced during execution of the program (which might
-be never at all). An attempt to dereference $x$ again in the course of
-evaluation of $e$ leads to a run-time error. Other threads trying to
-dereference $x$ while $e$ is being evaluated block until evaluation is
-complete.
-
-The type $T$ may be omitted if it can be determined using local type
-inference (\sref{sec:local-type-inf}).
-}
-
-\section{Packagings}
-
-\syntax\begin{verbatim}
- Packaging \=::= \= package QualId `{' {TopStat `;'} TopStat `}'
-\end{verbatim}
-
-A package is a special object which defines a set of member classes,
-objects and packages. Unlike other objects, packages are not defined
-by a definition. Instead, the set of members is determined by
-packagings.
-
-A packaging \verb@package p { ds }@ injects all definitions in
-\verb@ds@ as members into the package whose qualified name is
-\verb@p@. If a definition in \verb@ds@ is labelled \verb@private@, it
-is visible only for other members in the package.
-
-Selections \verb@p.m@ from \verb@p@ as well as imports from \verb@p@
-work as for objects. However, unlike other objects, packages may not
-be used as values. It is illegal to have a package with the same fully
-qualified name as an object or a class.
-
-Top-level definitions outside a packaging are assumed to be injected
-into a special empty package. That package cannot be named and
-therefore cannot be imported. However, members of the empty package
-are visible to each other wihtout qualification.
-
-\example The following example will create a hello world program as
-function \verb@main@ of module \verb@test.HelloWorld@.
-\begin{verbatim}
-package test;
-
-object HelloWord {
- def main(args: Array[String]) = System.out.println("hello world")
-}
-\end{verbatim}
-
-\ifpackaging{
-Packagings augment top-level modules and classes. A simple packaging
-$$\PACKAGE;id;\WITH;mi_1;\ldots;\WITH;mi_n;\WITH;(stats)$$ augments the
-template of the top-level module or class named $id$ with new mixin
-classes and with new member definitions.
-
-The static effect of such a packaging can be expressed as a
-source-to-source tranformation which adds $mi_1 \commadots mi_n$ to
-the mixin classes of $id$, and which adds the definitions in $stats$
-to the statement part of $id$'s template. Each type $mi_j$ must refer
-to an interface type and $stats$ must consists only of pure and local
-definitions. The augmented template and any class that extends it
-must be well-formed. The aditional definitions may not overwrite
-definitions of the augmented template, and they may not access private
-members of it.
-
-Several packagings can be applied to the same top-level definition,
-and those packagings may reside in different compilation units.
-
-A qualified packaging $\PACKAGE;Q.id;\WITH;t$ is equivalent to the
-nested packagings
-\begin{verbatim}
-package $Q$ with {
- package $id$ with $t$
-}
-\end{verbatim}
-
-A packaging with type parameters $\PACKAGE;c[tps];\WITH;...$ applies to
-a parameterized class $c$. The number of type parameters must equal
-the number of type parameters of $c$, and every bound in $tps$ must
-conform to the corresponding bound in the original definition of $c$.
-
-The augmented class has the type parameters given in its original
-definition. If a parameter $a$ of an augmented class has a bound $T$
-which is a strict subtype of the corresponding bound in the original
-class, $a \conforms T$ is taken as an {\em application condition} for
-the packaging. That is, every time a member defined in the packaging
-is accessed or a conformance between class $c$ and a mixin base class
-of the packaging needs to be established, an (instantiation of) the
-application condition is checked. An unvalidated application
-condition constitutes a type error. \todo{Need to specify more
-precisely when application conditions are checked}
-
-\example The following example will create a hello world program as
-function \verb@main@ of module \verb@test.HelloWorld@.
-\begin{verbatim}
-package test with {
- module HelloWord with {
- def main(args: Array[String]) = out.println("hello world")
- }
-}
-\end{verbatim}
-This assumes there exists a top-level definition that defines a
-\verb@test@ module, e.g.:
-\begin{verbatim}
-module test
-\end{verbatim}
-
-\example The following packaging adds class \verb@Comparable@
-(\ref{ex:comparable}) as a mixin to class
-\verb@scala.List@, provided the list elements are also comparable.
-Every instance of \verb@List[$T$]@ will then implement
-\verb@Comparable[List[$T$]]@ in the way it is defined in the
-packaging. Each use of the added functionality for an instance type
-\verb@List[$T$]@ requires that the application condition
-\verb@T $<:$ Comparable@ is satisfied.
-\begin{verbatim}
-package scala.List[a extends Comparable[a]] with Comparable[List[a]] with {
- def < (that: List[a]) = (this, that) match {
- case (_, Nil) => False
- case (Nil, _) => True
- case (x :: xs, y :: ys) => (x < y) || (x == y && xs < ys)
- }
-}
-\end{verbatim}
-}