From bcfd151a69617ae1576318e3cfb7aee3dce03593 Mon Sep 17 00:00:00 2001 From: odersky Date: Tue, 20 Jan 2004 11:50:36 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@2418 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- doc/reference/ExamplesPart.tex | 102 ++-- doc/reference/ReferencePart.tex | 541 +----------------- doc/reference/ScalaRationale.tex | 2 - doc/reference/ScalaReference.tex | 3 + .../tools/scalac/typechecker/Analyzer.scala | 1 + test/files/neg/bug95.check | 4 +- 6 files changed, 77 insertions(+), 576 deletions(-) diff --git a/doc/reference/ExamplesPart.tex b/doc/reference/ExamplesPart.tex index ad6403ae9..6c27ed38e 100644 --- a/doc/reference/ExamplesPart.tex +++ b/doc/reference/ExamplesPart.tex @@ -23,8 +23,8 @@ interesting programming techniques. The present informal exposition is meant to be complemented by the Java Language Reference Manual which specifies Scala in a more detailed and precise way. -\paragraph{Acknowledgement} -We owe a great dept to Sussman and Abelson's wonderful book +\paragraph{Acknowledgment} +We owe a great debt to Abelson's and Sussman'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 @@ -86,7 +86,7 @@ instance, the name of the array \code{a} is visible in functions 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 +syntactic peculiarities. 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 @@ -106,7 +106,7 @@ def sort(xs: List[int]): List[int] = { \end{lstlisting} The functional program works with lists instead of arrays.\footnote{In -a future complete implemenetation of Scala, we could also have used arrays +a future complete implementation of Scala, we could also have used arrays instead of lists, but at the moment arrays do not yet support \code{filter} and \code{:::}.} It captures the essence of the quicksort algorithm in a concise way: @@ -114,7 +114,7 @@ It captures the essence of the quicksort algorithm in a concise way: \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. +third list which contains elements equal to pivot. \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 @@ -328,7 +328,7 @@ on one item. Objects of this class are created by indicating \end{itemize} The process behavior is defined by its \code{run} method. That method repeatedly selects (using \code{receiveWithin}) a message and reacts to it, -until the auction is closed, which is signalled by a \code{TIMEOUT} +until the auction is closed, which is signaled by a \code{TIMEOUT} message. Before finally stopping, it stays active for another period determined by the \code{timeToShutdown} constant and replies to further offers that the auction is closed. @@ -632,7 +632,7 @@ def sqrtIter(guess: double, x: double): double = else sqrtIter(improve(guess, x), x); \end{lstlisting} Note that \code{sqrtIter} calls itself recursively. Loops in -imperative programs can always be modelled by recursion in functional +imperative programs can always be modeled by recursion in functional programs. Note also that the definition of \code{sqrtIter} contains a return @@ -654,7 +654,7 @@ def isGoodEnough(guess: double, x: double) = abs(square(guess) - x) < 0.001; \end{lstlisting} -Finally, the \code{sqrt} function itself is defined by an aplication +Finally, the \code{sqrt} function itself is defined by an application of \code{sqrtIter}. \begin{lstlisting} def sqrt(x: double) = sqrtIter(1.0, x); @@ -800,7 +800,7 @@ executed in constant space. By contrast, the recursive call in \code{factorial} is followed by a multiplication. Hence, a new stack frame is allocated for the -recursive instance of factorial, and is decallocated after that +recursive instance of factorial, and is deallocated 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. @@ -810,7 +810,7 @@ More generally, if the last action of a function is a call to another 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 +primitives 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 @@ -1377,7 +1377,7 @@ integers, as well as a private field \code{g} which contains the \code{gcd} of the constructor arguments. These members are inaccessible outside class \code{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 +order to ensure that numerator and denominator are always in normalized form. \paragraph{Creating and Accessing Objects} @@ -1478,7 +1478,7 @@ that clients do not have to be rewritten because of that change. Consider the task of writing a class for sets of integer numbers with two operations, \code{incl} and \code{contains}. \code{(s incl x)} -should return a new set which contains the element \code{x} togther +should return a new set which contains the element \code{x} together with all the elements of set \code{s}. \code{(s contains x)} should return true if the set \code{s} contains the element \code{x}, and should return \code{false} otherwise. The interface of such sets is @@ -1750,7 +1750,7 @@ trait Nat { def - (that: Nat): Nat; } \end{lstlisting} -To implement the operations of class \code{Nat}, we define a subobject +To implement the operations of class \code{Nat}, we define a sub-object \code{Zero} and a subclass \code{Succ} (for successor). Each number \code{N} is represented as \code{N} applications of the \code{Succ} constructor to \code{Zero}: @@ -2027,7 +2027,7 @@ would be added. Hence, one can now construct expression trees a bit more concise Sum(Sum(Number(1), Number(2)), Number(3)) \end{lstlisting} \item Case classes and case objects -implicity come with implementations of methods +implicitly come with implementations of methods \code{toString}, \code{equals} and \code{hashCode}, which override the methods with the same name in class \code{AnyRef}. The implementation of these methods takes in each case the structure of a member of a @@ -2056,7 +2056,7 @@ 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 \code{hashCode} does. \item -Case classes implicity come with nullary accessor methods which +Case classes implicitly come with nullary accessor methods which retrieve the constructor arguments. In our example, \code{Number} would obtain an accessor method \begin{lstlisting} @@ -2418,7 +2418,7 @@ val s = new EmptySet[java.io.File] $\mbox{\sl parameter bound}$ Ord[java.io.File]. \end{lstlisting} To conclude the discussion of type parameter -bounds, here is the defintion of trait \code{Ord} in scala. +bounds, here is the definition of trait \code{Ord} in scala. \begin{lstlisting} package scala; trait Ord[t <: Ord[t]]: t { @@ -2519,7 +2519,7 @@ class Array[+a] { $\mbox{\sl appears in contravariant position.}$ } \end{lstlisting} -So far, so good. Intuitively, the compiler was correect in rejecting +So far, so good. Intuitively, the compiler was correct in rejecting the \code{update} method in a co-variant class because \code{update} potentially changes state, and therefore undermines the soundness of co-variant subtyping. @@ -2580,7 +2580,7 @@ often suggest a useful generalization of the contested method. \section{Least Types} Scala does not allow one to parameterize objects with types. That's -why we orginally defined a generic class \code{EmptyStack[a]}, even +why we originally defined a generic class \code{EmptyStack[a]}, even though a single value denoting empty stacks of arbitrary type would do. For co-variant stacks, however, one can use the following idiom: \begin{lstlisting} @@ -2677,14 +2677,14 @@ follows. \begin{lstlisting} def divmod(x: int, y: int) = Pair(x / y, x % y) \end{lstlisting} -How are elements of tuples acessed? Since tuples are case classes, +How are elements of tuples accessed? Since tuples are case classes, there are two possibilities. One can either access a tuple's fields using the names of the constructor parameters \lstinline@_$i$@, as in the following example: \begin{lstlisting} val xy = divmod(x, y); System.out.println("quotient: " + x._1 + ", rest: " + x._2); \end{lstlisting} -Or one uses pattern matching on tuples, as in the following erample: +Or one uses pattern matching on tuples, as in the following example: \begin{lstlisting} divmod(x, y) match { case Pair(n, d) => @@ -3153,7 +3153,7 @@ computation over lists, like: \item extracting from a list all elements satisfying a criterion. \item combine the elements of a list using some operator. \end{itemize} -Functional programming languages enable programmers to write eneral +Functional programming languages enable programmers to write general functions which implement patterns like this by means of higher order functions. We now discuss a set of commonly used higher-order functions, which are implemented as methods in class \code{List}. @@ -3176,7 +3176,7 @@ abstract class List[a] { ... case x :: xs => f(x) :: xs.map(f) } \end{lstlisting} -Using \code{map}, \code{scaleList} can be more consisely written as follows. +Using \code{map}, \code{scaleList} can be more concisely written as follows. \begin{lstlisting} def scaleList(xs: List[double], factor: double) = xs map (x => x * factor) @@ -3237,7 +3237,7 @@ This pattern is generalized to the \code{filter} method of class \code{List}: case x :: xs => if (p(x)) x :: xs.filter(p) else xs.filter(p) } \end{lstlisting} -Using \code{filter}, \code{posElems} can be more consisely written as +Using \code{filter}, \code{posElems} can be more concisely written as follows. \begin{lstlisting} def posElems(xs: List[int]): List[int] = @@ -3260,7 +3260,7 @@ To illustrate the use of \code{forall}, consider the question whether a number if prime. Remember that a number $n$ is prime of it can be divided without remainder only by one and itself. The most direct translation of this definition would test that $n$ divided by all -numbers from 2 upto and excluding itself gives a non-zero +numbers from 2 up to and excluding itself gives a non-zero remainder. This list of numbers can be generated using a function \code{List.range} which is defined in object \code{List} as follows. \begin{lstlisting} @@ -3270,7 +3270,7 @@ object List { ... if (from >= end) Nil else from :: range(from + 1, end); \end{lstlisting} For example, \code{List.range(2, n)} -generates the list of all integers from 2 upto and excluding $n$. +generates the list of all integers from 2 up to and excluding $n$. The function \code{isPrime} can now simply be defined as follows. \begin{lstlisting} def isPrime(n: int) = @@ -3301,7 +3301,7 @@ def product(xs: List[int]): int = xs match { case y :: ys => y * product(ys) } \end{lstlisting} -But we can also use the generaliztion of this program scheme embodied +But we can also use the generalization of this program scheme embodied in the \code{reduceLeft} method of class \code{List}. This method inserts a given binary operator between adjacent elements of a given list. E.g.\ @@ -3919,7 +3919,7 @@ constructions for dealing with lists. But sometimes the level of abstraction required by these functions makes a program hard to understand. -To help understandbility, Scala has a special notation which +To help understandability, Scala has a special notation which simplifies common patterns of applications of higher-order functions. This notation builds a bridge between set-comprehensions in mathematics and for-loops in imperative languages such as C or @@ -3977,15 +3977,15 @@ be written as follows. For-comprehensions are especially useful for solving combinatorial puzzles. An example of such a puzzle is the 8-queens problem: Given a -standard chessboard, place 8 queens such that no queen is in check from any +standard chess-board, place 8 queens such that no queen is in check from any other (a queen can check another piece if they are on the same -column, row, or diagional). We will now develop a solution to this -problem, generalizing it to chessboards of arbitrary size. Hence, the -problem is to place $n$ queens on a chessboard of size $n \times n$. +column, row, or diagonal). We will now develop a solution to this +problem, generalizing it to chess-boards of arbitrary size. Hence, the +problem is to place $n$ queens on a chess-board of size $n \times n$. To solve this problem, note that we need to place a queen in each row. So we could place queens in successive rows, each time checking that a -newly placed queen is not in queck from any other queens that have +newly placed queen is not in check from any other queens that have already been placed. In the course of this search, it might arrive that a queen to be placed in row $k$ would be in check in all fields of that row from queens in row $1$ to $k-1$. In that case, we need to @@ -4006,7 +4006,7 @@ element for each solution. Now, to place the $k$'the queen, we generate all possible extensions of each previous solution by one more queen. This yields another list of solution lists, this time of length $k$. We continue the process -until we have reached solutions of the size of the chessboard $n$. +until we have reached solutions of the size of the chess-board $n$. This algorithmic idea is embodied in function \code{placeQueens} below: \begin{lstlisting} def queens(n: int): List[List[int]] = { @@ -4041,7 +4041,7 @@ Here is a small example database: \begin{lstlisting} val books: List[Book] = List( Book("Structure and Interpretation of Computer Programs", - List("Abelson, Harald", "Sussman, Gerald J.")), + List("Abelson, Harold", "Sussman, Gerald J.")), Book("Principles of Compiler Design", List("Aho, Alfred", "Ullman, Jeffrey")), Book("Programming in Modula-2", @@ -4184,7 +4184,7 @@ For-comprehensions resemble for-loops in imperative languages, except that they produce a list of results. Sometimes, a list of results is not needed but we would still like the flexibility of generators and filters in iterations over lists. This is made possible by a variant -of the for-comprehension syntax, which excpresses for-loops: +of the for-comprehension syntax, which expresses for-loops: \begin{lstlisting} for ( $s$ ) $e$ \end{lstlisting} @@ -4270,7 +4270,7 @@ theory underlying functional programming. In this chapter, we introduce functions with side effects and study their behavior. We will see that as a consequence we have to -fundamenatlly modify up the substitution model of computation which we +fundamentally modify up the substitution model of computation which we employed so far. \section{Stateful Objects} @@ -4308,7 +4308,7 @@ In Scala, every defined variable has to be initialized at the point of its definition. For instance, the statement ~\code{var x: int;}~ is {\em not} regarded as a variable definition, because the initializer is missing\footnote{If a statement like this appears in a class, it is -instead regarded as a variable declaration, which introcuces +instead regarded as a variable declaration, which introduces abstract access methods for the variable, but does not associate these methods with a piece of state.}. If one does not know, or does not care about, the appropriate initializer, one can use a wildcard @@ -4739,7 +4739,7 @@ inserts the pair \code{(curtime + delay, action)} into the Pair(actiontime, action) :: ag case (first @ Pair(time, act)) :: ag1 => if (actiontime < time) Pair(actiontime, action) :: ag - else first :: insert(ag1) + else first :: insert(ag1) } agenda = insert(agenda) } @@ -4801,7 +4801,7 @@ sum 15 new_value = false \section{Summary} We have seen in this chapter the constructs that let us model state in -Scala -- these are variables, assignments, abd imperative control +Scala -- these are variables, assignments, and imperative control structures. State and Assignment complicate our mental model of computation. In particular, referential transparency is lost. On the other hand, assignment gives us new ways to formulate programs @@ -4812,8 +4812,8 @@ functional programming or programming with assignments works best. 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 +with time can be modeled by changing the state of variables in a +computation. Time changes in the real world thus are modeled 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 @@ -4822,7 +4822,7 @@ 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 +answer is clearly yes: A time-changing quantity is simply modeled by a function \code{f(t)} with a time parameter \code{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 @@ -4928,7 +4928,7 @@ 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 \code{tail} operation. The argument why list-append \code{:::} cannot be adapted to streams is analogous. -Intstead of \code{x :: xs}, one uses \code{Stream.cons(x, xs)} for +Instead of \code{x :: xs}, one uses \code{Stream.cons(x, xs)} for constructing a stream with first element \code{x} and (unevaluated) rest \code{xs}. Instead of \code{xs ::: ys}, one uses the operation \code{xs append ys}. @@ -4938,7 +4938,7 @@ rest \code{xs}. Instead of \code{xs ::: ys}, one uses the operation Iterators are the imperative version of streams. Like streams, iterators describe potentially infinite lists. However, there is no data-structure which contains the elements of an iterator. Instead, -iterators aloow one to step through the sequence, using two abstract methods \code{next} and \code{hasNext}. +iterators allow one to step through the sequence, using two abstract methods \code{next} and \code{hasNext}. \begin{lstlisting} trait Iterator[+a] { def hasNext: boolean; @@ -5035,7 +5035,7 @@ returns all elements of the original iterator that satisfy a criterion \end{lstlisting} In fact, \code{filter} returns instances of a subclass of iterators which are ``buffered''. A \code{BufferedIterator} object is an -interator which has in addition a method \code{head}. This method +iterator which has in addition a method \code{head}. This method returns the element which would otherwise have been returned by \code{head}, but does not advance beyond that element. Hence, the element returned by \code{head} is returned again by the next call to @@ -6514,9 +6514,9 @@ class ComputeServer(n: Int) { val reply = new SyncVar[a](); openJobs.write{ new Job { - type t = a; - def task = p; - def ret(x: a) = reply.set(x); + type t = a; + def task = p; + def ret(x: a) = reply.set(x); } } () => reply.get @@ -6604,7 +6604,7 @@ As a simple example of how mailboxes are used, consider a one-place buffer: \begin{lstlisting} class OnePlaceBuffer { - private val m = new MailBox; // An internal milbox + private val m = new MailBox; // An internal mailbox private case class Empty, Full(x: int); // Types of messages we deal with m send Empty; // Initialization def write(x: int): unit = @@ -6662,10 +6662,10 @@ Otherwise, the message is appended to the linked list of sent messages. if (s1 != null) { s.next = s1.next; s1.elem } else { - val r = insert(lastReceiver, new Receiver { + val r = insert(lastReceiver, new Receiver { def isDefined(msg: Any) = f.isDefinedAt(msg); }); - lastReceiver = r; + lastReceiver = r; r.elem.wait(); r.elem.msg } diff --git a/doc/reference/ReferencePart.tex b/doc/reference/ReferencePart.tex index d6984288e..b54ad4d48 100644 --- a/doc/reference/ReferencePart.tex +++ b/doc/reference/ReferencePart.tex @@ -44,7 +44,7 @@ varid ::= lower {letter $|$ digit} [`_' [id]] id ::= upper {letter $|$ digit} [`_' [id]] | varid | op - | ```string chars`'' + | ```string chars`'' \end{lstlisting} There are three ways to form an identifier. First, an identifier can @@ -54,7 +54,7 @@ letters and digits. This may be followed by an underscore themselves make up an identifier. Second, an identifier can be start with a special character followed by an arbitrary sequence of special characters. Finally, an identifier may also be formed by an arbitrary -string between backquotes (host systems may impose some restrictions +string between back-quotes (host systems may impose some restrictions on which strings are legal for identifiers). As usual, a longest match rule applies. For instance, the string @@ -423,7 +423,7 @@ contravariant in their argument 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 +do they appear explicitly in programs. They are introduced in this report as the internal types of defined identifiers. \subsection{Method Types} @@ -693,7 +693,7 @@ transitive relation that satisfies the following conditions. one has $\mbox{\code{scala.AllRef}} \conforms 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 class type or parameterized type $c$ conforms to any of its base-types, $b$. \item A type projection \lstinline@$T$#$t$@ conforms to \lstinline@$U$#$t$@ if $T$ conforms to $U$. \item A parameterized type ~\lstinline@$T$[$T_1 \commadots T_n$]@~ conforms to @@ -767,7 +767,7 @@ class C extends A[C]; Then the types ~\lstinline@A[Any], A[A[Any]], A[A[A[Any]]], ...@~ form a descending sequence of upper bounds for \code{B} and \code{C}. The least upper bound would be the infinite limit of that sequence, which -does ot exist as a Scala type. Since cases like this are in general +does not exist as a Scala type. Since cases like this are in general impossible to detect, a Scala compiler is free to reject a term which has a type specified as a least upper or greatest lower bound, and that bound would be more complex than some compiler-set @@ -840,7 +840,7 @@ or \code{short} is always implicitly converted to a value of type If an expression $e$ has type $T$ where $T$ does not conform to the expected type $pt$ and $T$ has a member named \lstinline@coerce@ of type -$[]U$ where $U$ does comform to $pt$, then the expression is typed and evaluated is if it was +$[]U$ where $U$ does conform to $pt$, then the expression is typed and evaluated is if it was \lstinline@$e$.coerce@. @@ -877,7 +877,7 @@ 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. It may not be -a value definition, a variable defninition, or an expression. +a value definition, a variable definition, or an expression. \comment{ Every basic definition may introduce several defined names, separated @@ -914,7 +914,7 @@ the type definition \comment{ If an element in such a sequence introduces only the defined name, possibly with some type or value parameters, but leaves out any -aditional parts in the definition, then those parts are implicitly +additional parts in the definition, then those parts are implicitly copied from the next subsequent sequence element which consists of more than just a defined name and parameters. Examples: \begin{itemize} @@ -1360,7 +1360,7 @@ The last value parameter of a parameter section may be suffixed by if a method $m$ with type ~\lstinline@($T_1 \commadots T_n, S$*)$U$@~ is applied to arguments $(e_1 \commadots e_k)$ where $k \geq n$, then $m$ is taken in that application to have type $(T_1 \commadots T_n, S -\commadots S)U$, with $k - n$ occurences of type $S$. +\commadots S)U$, with $k - n$ occurrences of type $S$. \todo{Change to ???: If the method is converted to a function type instead of being applied immediately, a repeated parameter \lstinline@$T$*@ is taken to be ~\lstinline@scala.Seq[$T$]@~ @@ -1601,7 +1601,7 @@ class F extends B with D with E; The mixin base classes and base classes of classes \code{A-F} are given in the following table: \begin{quote}\begin{tabular}{|l|l|l|} \hline - \ & Mixin base classses & Base classes \\ \hline + \ & Mixin base classes & Base classes \\ \hline A & A & A, ScalaObject, AnyRef, Any \\ B & B & B, A, ScalaObject, AnyRef, Any \\ C & C & C, A, ScalaObject, AnyRef, Any \\ @@ -1610,7 +1610,7 @@ E & C, D, E & E, B, C, D, A, ScalaObject, AnyRef, Any \\ F & C, D, E, F & F, B, D, E, C, A, ScalaObject, AnyRef, Any \\ \hline \end{tabular}\end{quote} Note that \code{D} is inherited twice by \code{F}, once directly, the -other time indirectly throgh \code{E}. This is permitted, since +other time indirectly through \code{E}. This is permitted, since \code{D} is a trait. @@ -1773,9 +1773,9 @@ labeled \code{protected}. If $M'$ is not an abstract member, then $M$ must be labeled \code{override}. \item -If $M'$ is labelled \code{abstract} and \code{override}, and $M'$ is a +If $M'$ is labeled \code{abstract} and \code{override}, and $M'$ is a member of the static superclass of the class containing the definition -of $M$, then $M$ must also be labelled \code{abstract} and +of $M$, then $M$ must also be labeled \code{abstract} and \code{override}. \end{itemize} @@ -1852,11 +1852,11 @@ definition. The \code{override} modifier has an additional significance when combined with the \code{abstract} modifier. That modifier combination is only allowed for members of abstract classes. A member -labelled \code{abstract} and \code{override} must override some +labeled \code{abstract} and \code{override} must override some member of the superclass of the class containing the definition. We call a member of a template {\em incomplete} if it is either -abstract (i.e.\ defined by a declaration), or it is labelled +abstract (i.e.\ defined by a declaration), or it is labeled \code{abstract} and \code{override} and it overrides an incomplete member of the template's superclass. @@ -2030,7 +2030,7 @@ This defines a class \code{LinkedList} with an overloaded constructor of type \begin{lstlisting} [a](): LinkedList[a] $\overload$ [a](x: a): LinkedList[a] $\overload$ -[a](x: a, xs: LinkList[a]): LinkedList[a] . +[a](x: a, xs: LinkedList[a]): LinkedList[a] . \end{lstlisting} The second constructor alternative constructs an singleton list, while the third one constructs a list with a given head and tail. @@ -3779,7 +3779,7 @@ abstract sealed class Long extends AnyVal { def coerce: Float // convert to Float def + (that: Double): Double; // double addition - def + (that: Float): Double; // float addtion + def + (that: Float): Double; // float addition def + (that: Long): Long = // long addition /* analogous for -, *, /, % */ @@ -3935,7 +3935,7 @@ case class Tuple$n$[+a_1, ..., +a_n](_1: a_1, ..., _$n$: a_$n$) { } \end{lstlisting} -The implicity imported \code{Predef} object (\sref{cls:predef}) defines +The implicitly imported \code{Predef} object (\sref{cls:predef}) defines the names \code{Pair} as an alias of \code{Tuple2} and \code{Triple} as an alias for \code{Tuple3}. @@ -3979,7 +3979,7 @@ class PartialFunction[-a,+b] extends Function1[a, b] { } \end{lstlisting} -The implicity imported \code{Predef} object (\sref{cls:predef}) defines the name +The implicitly imported \code{Predef} object (\sref{cls:predef}) defines the name \code{Function} as an alias of \code{Function1}. \subsection{Class \large{\code{Array}}}\label{cls:array} @@ -4019,7 +4019,7 @@ module Array { \section{The \large{\code{Predef}} Object}\label{cls:predef} The \code{Predef} module defines standard functions and type aliases -for Scala programs. It is always implicity imported, so that all its +for Scala programs. It is always implicitly imported, so that all its defined members are available without qualification. Here is its definition for the JVM environment. @@ -4076,504 +4076,3 @@ object Predef { } \end{lstlisting} -\appendix -\chapter{Scala Syntax Summary} - -The lexical syntax of Scala is given by the following grammar in EBNF -form. - -\begin{lstlisting} - upper ::= `A' | $\ldots$ | `Z' | `$\Dollar$' | `_' - lower ::= `a' | $\ldots$ | `z' - letter ::= upper | lower - digit ::= `0' | $\ldots$ | `9' - special ::= $\mbox{\rm\em ``all other characters except parentheses ([{}]) and periods''}$ - - op ::= special {special} - varid ::= lower {letter | digit} [`_' [id]] - id ::= upper {letter | digit} [`_' [id]] - | varid - | op - | `\'stringLit - - intLit ::= $\mbox{\rm\em ``as in Java''}$ - floatLit ::= $\mbox{\rm\em ``as in Java''}$ - charLit ::= $\mbox{\rm\em ``as in Java''}$ - stringLit ::= $\mbox{\rm\em ``as in Java''}$ - symbolLit ::= `\'' id - - comment ::= `/*' ``any sequence of characters'' `*/' - | `//' `any sequence of characters up to end of line'' -\end{lstlisting} - -The context-free syntax of Scala is given by the following EBNF -grammar. - -\begin{lstlisting} - Literal ::= intLit - | floatLit - | charLit - | stringLit - | symbolLit - | true - | false - | null - - 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 - | Expr1 - Expr1 ::= if `(' Expr1 `)' Expr [[`;'] else Expr] - | try `{' Block `}' [catch Expr] [finally Expr] - | do Expr [`;'] while `(' Expr ')' - | for `(' Enumerators `)' (do | yield) Expr - | return [Expr] - | throw Expr - | [SimpleExpr `.'] id `=' Expr - | SimpleExpr ArgumentExprs `=' Expr - | PostfixExpr [`:' Type1] - PostfixExpr ::= InfixExpr [id] - InfixExpr ::= PrefixExpr - | InfixExpr id PrefixExpr - PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr - SimpleExpr ::= Literal - | Path - | `(' [Expr] `)' - | BlockExpr - | new Template - | SimpleExpr `.' id - | SimpleExpr TypeArgs - | SimpleExpr ArgumentExprs - ArgumentExprs ::= `(' [Exprs] ')' - | BlockExpr - BlockExpr ::= `{' CaseClause {CaseClause} `}' - | `{' Block `}' - Block ::= {BlockStat `;'} [ResultExpr] - BlockStat ::= Import - | Def - | {LocalModifier} ClsDef - | Expr1 - | - ResultExpr ::= Expr1 - | Bindings `=>' Block - - Enumerators ::= Generator {`;' Enumerator} - Enumerator ::= Generator - | Expr - Generator ::= val Pattern1 `<-' Expr - - CaseClause ::= case Pattern [`if' PostfixExpr] `=>' Block - - Constr ::= StableId [TypeArgs] [`(' [Exprs] `)'] - - Pattern ::= Pattern1 { `|' Pattern1 } - Pattern1 ::= varid `:' Type - | `_' `:' Type - | Pattern2 - Pattern2 ::= [varid `@'] Pattern3 - Pattern3 ::= SimplePattern [ '*' | '?' | '+' ] - | SimplePattern { id SimplePattern } - SimplePattern ::= `_' - | varid - | 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}] `}' - 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 ArgumentExprs - | `{' this ArgumentExprs {`;' BlockStat} `}' - - CompilationUnit ::= [package QualId `;'] {TopStat `;'} TopStat - TopStat ::= {Modifier} ClsDef - | Import - | Packaging - | - Packaging ::= package QualId `{' {TopStat `;'} TopStat `}' - QualId ::= id {`.' id} -\end{lstlisting} - -\chapter{Implementation Status} - -The present Scala compiler does not yet implement all of the Scala -specification. Its currently existing omissions and deviations are -listed below. We are working on a refined implementation that -addresses these issues. -\begin{enumerate} -\item -Unicode support is still limited. At present we only permit Unicode -encodings \verb@\uXXXX@ in strings and backquote-enclosed identifiers. -To define or access a Unicode identifier, you need to put it in -backquotes and use the \verb@\uXXXX@ encoding. -\item -The unicode operator ``$\Rightarrow$'' -(\sref{sec:idents}) is not yet recognized; you need to use the two -character ASCII equivalent ``\code{=>}'' instead. -\item -The current implementation does not yet support run-time types. -All types are erased (\sref{sec:erasure}) during compilation. This means that -the following operations give potentially wrong results. -\begin{itemize} -\item -Type tests and type casts to parameterized types. Here it is only tested -that a value is an instance of the given top-level type constructor. -\item -Type tests and type casts to type parameters and abstract types. Here -it is only tested that a value is an instance of the type parameter's upper bound. -\item -Polymorphic array creation. If \code{t} is a type variable or abstract type, then -\code{new Array[t]} will yield an array of the upper bound of \code{t}. -\end{itemize} -\item -Return expressions are not yet permitted inside an anonymous function -or inside a call-by-name argument (i.e.\ a function argument corresponding to a -\code{def} parameter). -\item -Members of the empty package (\sref{sec:packagings}) cannot yet be -accessed from other source files. Hence, all library classes and -objects have to be in some package. -\item -At present, auxiliary constructors (\sref{sec:constr-defs}) are only permitted -for monomorphic classes. -\item -The \code{Array} class supports as yet only a restricted set of -operations as given in \sref{cls:array}. It is planned to extend that -interface. In particular, arrays will implement the \code{scala.Seq} -trait as well as the methods needed to support for-comprehensions. -\item -At present, all classes used as mixins must be accessible to the Scala -compiler in source form. -\end{enumerate} - -\end{document} - - -\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. -} -\section{Exceptions} -\label{sec:exceptions} - -There is a predefined type \code{Throwable}, as well as functions to -throw and handle values of type \code{Throwable}. These are declared -as follows. - -\begin{lstlisting} - class Throwable { - def throw[a]: a - } - class ExceptOrFinally[a] { - def except (handler: PartialFunction[Throwable,a]): a - def finally (def handler: Unit): a - } - def try [a] (def body: a): ExceptOrFinally[a] -\end{lstlisting} - -The type \code{Throwable} represents exceptions and error objects; it -may be identified with an analogous type of the underlying -implementation such as \code{java.lang.Throwable}. We will in the -following loosely call values of type \code{Throwable} exceptions. - -The \code{throw} method in \code{Throwable} aborts execution of the -thread executing it and passes the thrown exception to the handler -that was most recently installed by a -\code{try} function in the current thread. If no \code{try} method is -active, the thread terminates. - -The \code{try} function executes its body with the given exception -handler. A \code{try} expression comes in two forms. The first form is - -\begin{lstlisting} -try $body$ except $handler$ . -\end{lstlisting} - -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 \code{handler} is defined, -the handler is invoked with the thrown exception as argument. - -The second form of a try expression is - -\begin{lstlisting} -try $body$ finally $handler$ . -\end{lstlisting} - -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 \code{Unit} as result type. -If execution of the handler expression throws an exception, this -exception is propagated out of the \code{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 \code{try} expression. - -\example An example of a try-except expression: - -\begin{lstlisting} -try { - System.in.readString() -} except { - case ex: EndOfFile => "" -} -\end{lstlisting} - -\example An example of a try-finally expression: - -\begin{lstlisting} -file = open (fileName) -if (file != null) { - try { - process (file) - } finally { - file.close - } -} -\end{lstlisting} - -\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 \code{Thread} for run-time threads, -\code{fork} function to spawn off a new thread, -as well as \code{Monitor} and \code{Signal} classes. These are -specified as follows\notyet{Concurrency constructs are}. - - -\begin{lstlisting} -class Thread { $\ldots$ } -def fork (def p: Unit): Thread -\end{lstlisting} - -The \code{fork} function runs its argument computation \code{p} in a -separate thread. It returns the thread object immediately to its -caller. Unhandled exceptions (\sref{sec:exceptions}) thrown during -evaluation of \code{p} abort execution of the forked thread and are -otherwise ignored. - -\begin{lstlisting} -class Monitor { - def synchronized [a] (def e: a): a -} -\end{lstlisting} - -Monitors define a \code{synchronized} method which provides mutual -exclusion between threads. It executes its argument computation -\code{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{lstlisting} -class Signal { - def wait: Unit - def wait(msec: Long): Unit - def notify: Unit - def notifyAll: Unit -} -\end{lstlisting} - -The \code{Signal} class provides the basic means for process -synchronization. The \code{wait} method of a signal suspends the -calling thread until it is woken up by some future invocation of the -signal's \code{notify} or \code{notifyAll} method. The \code{notify} -method wakes up one thread that is waiting for the signal. The -\code{notifyAll} method wakes up all threads that are waiting for the -signal. A second version of the \code{wait} method takes a time-out -parameter (given in milliseconds). A thread calling \code{wait(msec)} -will suspend until unblocked by a \code{notify} or \code{notifyAll} -method, or until the \code{msec} millseconds have passed. - -\subsection{Channels} - -\begin{lstlisting} -class Channel[a] { - def write(x: a): Unit - def read: a -} -\end{lstlisting} - -An object of type \code{Channel[a]} Channels offer a write-operation -which writes data of type \code{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 -\code{Message} class. -There is a special message \code{TIMEOUT} which is used to signal a time-out. -\begin{lstlisting} -class Message -case class TIMEOUT extends Message -\end{lstlisting} -Message spaces implement the following class. -\begin{lstlisting} -class MessageSpace { - def send(msg: Message): Unit - def receive[a](f: PartialFunction1[Message, a]): a - def receiveWithin[a](msec: Long)(f: PartialFunction1[Message, a]): a -} -\end{lstlisting} -The state of a message space consists of a multi-set of messages. -Messages are added to the space using the \code{send} method. Messages -are removed using the \code{receive} method, which is passed a message -processor \code{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 \code{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 \code{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 \code{TIMEOUT} message. - -case class extends { $\ldots$ } - -trait List { } -class Nil -class Cons - -\comment{changes: - Type ::= SimpleType {with SimpleType} [with Refinement] - | class SimpleType - SimpleType ::= SimpleType [TypeArgs] - | `(' [Types] `)' - | - | this -} diff --git a/doc/reference/ScalaRationale.tex b/doc/reference/ScalaRationale.tex index 757bb3331..596119849 100644 --- a/doc/reference/ScalaRationale.tex +++ b/doc/reference/ScalaRationale.tex @@ -22,7 +22,5 @@ Martin Odersky \input{RationalePart} -\bibliographystyle{alpha} -\bibliography{Scala} \end{document} \ No newline at end of file diff --git a/doc/reference/ScalaReference.tex b/doc/reference/ScalaReference.tex index 6794167de..6743cb189 100644 --- a/doc/reference/ScalaReference.tex +++ b/doc/reference/ScalaReference.tex @@ -93,9 +93,12 @@ Matthias Zenger \\[25mm]\ } \input{RationalePart} \part{The Scala Language Specification} + \input{ReferencePart} \bibliographystyle{alpha} \bibliography{Scala} +\input{ReferencePartAppendix} + \end{document} diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index 5dc3f1fd3..966e642c3 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -96,6 +96,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( } def lateEnter(unit: Unit, sym: Symbol): unit = { + //System.out.println("late enter: " + sym + " " + sym.isModule());//DEBUG enterUnit(unit); if (sym.rawFirstInfo().isInstanceOf[SourceCompleter]) { sym.setInfo(Type.ErrorType); diff --git a/test/files/neg/bug95.check b/test/files/neg/bug95.check index 8dd3507cd..d945753a5 100644 --- a/test/files/neg/bug95.check +++ b/test/files/neg/bug95.check @@ -2,14 +2,14 @@ bug95.scala:1: illegal inheritance from sealed class class C extends AnyVal; ^ bug95.scala:1: illegal inheritance; - scala.AnyVal does not conform to scala.ScalaObject's supertype + scala.AnyVal does not conform to scala.ScalaObject's supertype java.lang.Object class C extends AnyVal; ^ bug95.scala:2: illegal inheritance from sealed class class T extends Unit; ^ bug95.scala:2: illegal inheritance; - scala.Unit does not conform to scala.ScalaObject's supertype + scala.Unit does not conform to scala.ScalaObject's supertype java.lang.Object class T extends Unit; ^ four errors found