summaryrefslogtreecommitdiff
path: root/doc/reference
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2004-05-07 14:40:38 +0000
committerMartin Odersky <odersky@gmail.com>2004-05-07 14:40:38 +0000
commit9711cb5539092c237801a0e600957ae3934bb938 (patch)
tree4fd4d0899c8cf8a8cc9fbc197aaf4bbccb9e95de /doc/reference
parenta91be3f08aeb22cb54c47b1f7380cef471c91739 (diff)
downloadscala-9711cb5539092c237801a0e600957ae3934bb938.tar.gz
scala-9711cb5539092c237801a0e600957ae3934bb938.tar.bz2
scala-9711cb5539092c237801a0e600957ae3934bb938.zip
*** empty log message ***
Diffstat (limited to 'doc/reference')
-rw-r--r--doc/reference/ReferencePart.tex198
-rw-r--r--doc/reference/ReferencePartAppendix.tex56
2 files changed, 193 insertions, 61 deletions
diff --git a/doc/reference/ReferencePart.tex b/doc/reference/ReferencePart.tex
index 811fbe90a8..f023a8c45f 100644
--- a/doc/reference/ReferencePart.tex
+++ b/doc/reference/ReferencePart.tex
@@ -68,7 +68,7 @@ There are three 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. This may be followed by an underscore
`\lstinline@_@' character and another string of characters that by
-themselves make up an identifier. Second, an identifier can be started
+themselves make up an identifier. Second, an identifier can 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 back-quotes (host systems may impose some restrictions
@@ -124,7 +124,7 @@ The tokens which cannot legally start a statement
are the following delimiters and reserved words:
\begin{lstlisting}
catch else extends finally with yield
-, . ; : = => <- <: >: # @ ) ] }
+, . ; : = => <- <: <% >: # @ ) ] }
\end{lstlisting}
\section{Literals}
@@ -885,11 +885,13 @@ When used in an expression, a value of type \code{byte}, \code{char},
or \code{short} is always implicitly converted to a value of type
\code{int}.
-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 conform to $pt$, then the expression is typed and evaluated is if it was
-\lstinline@$e$.coerce@.
+%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 conform to $pt$, then the expression is typed and evaluated is if it was
+%\lstinline@$e$.coerce@.
+Implicit conversions can also be user-defined. This is expained in
+Chapter~\ref{sec:views}.
\chapter{Basic Declarations and Definitions}
\label{sec:defs}
@@ -1228,8 +1230,9 @@ new Pair[Int, Int](1, 2) .
\section{Type Parameters}
\syntax\begin{lstlisting}
- TypeParamClause ::= `[' TypeParam {`,' TypeParam} `]'
- TypeParam ::= [`+' | `-'] TypeDcl
+ TypeParamClause ::= `[' VarTypeParam {`,' VarTypeParam} `]'
+ VarTypeParam ::= [`+' | `-'] TypeParam
+ TypeParam ::= id [>: Type] [<: Type | <% Type]
\end{lstlisting}
@@ -1378,7 +1381,7 @@ FunDcl ::= FunSig {`,' FunSig} `:' Type
Def ::= def FunDef
FunDef ::= FunSig {`,' FunSig} [`:' Type] `=' Expr
FunSig ::= id [FunTypeParamClause] {ParamClause}
-FunTypeParamClause ::= `[' TypeDcl {`,' TypeDcl} `]'
+FunTypeParamClause ::= `[' TypeParam {`,' TypeParam} `]'
ParamClause ::= `(' [Param {`,' Param}] `)'
Param ::= [def] id `:' Type [`*']
\end{lstlisting}
@@ -3762,6 +3765,183 @@ type of all patterns is the type of the qualifier of \code{match}.
In the example above, the expected type of the patterns \code{Nil} and
\code{x :: xs1} would be \code{List[a]}, the type of \code{xs}.
+\chapter{Views}\label{sec:views}
+
+Views are user-defined, implicit coercions that are automatically
+inserted by the compiler.
+
+\section{View Definition}
+
+A view definition is a normal function definition with one value
+parameter where the name of the defined function is \code{view}.
+
+\example
+
+\begin{lstlisting}
+def view(xs: String): List[char] =
+ if (xs.length() == 0) List()
+ else xs.charAt(0) :: xs.substring(1);
+\end{lstlisting}
+
+This defines an implicit coercion function from strings to lists of
+characters.
+
+\section{View Application}
+
+View applications are inserted implicitly in two situations.
+\begin{enumerate}
+\item
+Around an expression $e$ of type $T$, if $T$ does not conform to the
+expression's expected type $PT$.
+\item
+In a selection $e.m$ with $e$ of type $T$, if the selector $m$ does not
+denote a member of $T$.
+\end{enumerate}
+In the first case, a view method \code{view} is searched which is
+applicable to $e$ and whose result type conforms to $PT$.
+If such a method is found, the expression $e$ is converted to
+\lstinline@view($e$)@.
+
+In the second case, a view method \code{view} is searched which is
+applicable to $e$ and whose result contains a member named $m$.
+If such a method is found, the selection $e.m$ is converted to
+\lstinline@view($e$).m@
+
+\section{Finding Views}\label{sec:finding-views}
+
+Searching a view which is applicable to an expression $e$ of type $T$
+is a three-step process.
+\begin{enumerate}
+\item
+First, the set $\VV$ of available views is determined. $\VV$ is the
+smallest set such that:
+\begin{enumerate}
+\item
+If a unary method called \code{view} is accessible without qualifier
+anywhere on the path of the program tree that leads from $e$ to the
+root of the tree (describing the whole compilation unit), then that
+method is in the set $\AA$. Methods are accessible without qualifier
+because they are locally defined in an enclosing scope, or imported
+into an enclosing scope, or inherited by an enclosing class.
+\item
+If a unary method called \code{view} is a member of an object $C$ such
+that there is a base class $C$ of $T$ with the same name as the object
+and defined in the same scope, then that method is in the set $\AA$.
+\end{enumerate}
+\item
+Then, among all the methods in $\AA$ the set of all applicable views
+$\BB$ is determined. A view method is applicable if it can be applied
+to values of type $T$, and another condition is satisfied which
+depends on the context of the view application:
+\begin{enumerate}
+\item
+If the view is a conversion to a given prototype $PT$, then the view's
+result type must conform to $PT$.
+\item
+If the view is a conversion in a selection with member $m$, then the
+view's result type must contain a member named $m$.
+\end{enumerate}
+Note that in the determining of view applicability, we do not permit
+further views to be inserted. I.e.\ a view is applicable to an
+expression $e$ of type $T$ if it can be applied to $e$, without a
+further view conversion of $e$ to the view's formal parameter type.
+Likewise, a view's result type must conform to a given prototype
+directly, no second view conversion is allowed.
+\item
+It is an error is the set of applicable views $\BB$ is empty. For
+non-empty $\BB$, the view method which is most specific
+(\sref{sec:overloaded-refs}) in $\BB$ is selected. It is an error if
+no most specific view exists, or if it is not unique.
+\end{enumerate}
+
+\example
+
+Consider the following situation.
+\begin{lstlisting}
+class A;
+class B extends A;
+class C;
+object B {
+ def view(x: B): C = ...
+}
+object Test with Application {
+ def view(x: A): C = ...
+ val x: C = new B;
+}
+\end{lstlisting}
+For the expression ~\code{new B}~ there are two available views. The
+view defined in object \code{B} is available since its associated
+class is (a superclass of) the expression's type \code{B}. The view
+defined in object \code{Test} is available since it is accessible
+without qualification at the point of the expression ~\code{new
+B}. Both views are also applicable since they map values of type
+\code{B} to results of type \code{C}. However, the view defined in
+object \code{B} is more specific than the view defined in object
+\code{Test}. Hence, the last statement in the example above is
+implicitly augmented to
+\begin{lstlisting}
+val x: C = B.view(new B)
+\end{lstlisting}
+
+\section{View-Bounds}
+
+\syntax\begin{lstlisting}
+ TypeParam ::= id [>: Type] [<% Type]
+\end{lstlisting}
+
+A type parameter \code{a} may have a view bound \lstlisting@a <% T@
+instead of a regular upper bound \lstlisting@a <: T@. In that case the
+type parameter may be instantiated to any type \code{S} which is
+convertible by application of a view method to the view bound
+\code{T}. Here, we assume there exists an always available identity
+view method
+\begin{lstlisting}
+def view[a](x: a): a = x .
+\end{lstlisting}
+Hence, the type parameter \code{a} can always be instantiated to
+subtypes of the view bound \code{T}, just as if \code{T} was a regular
+upper bound.
+
+Methods or classes with view-bounded type parameters implicitly take
+view functions as parameters. For every view-bounded type parameter
+\lstinline@a <% T@ one adds an implicit value parameter
+\lstinline@view: a => T@. When instantiating the type parameter
+\code{a} to some type \code{S}, the most specific applicable view
+method from type \code{S} to type \code{T} is selected, according to
+the rules of \sref{sec:finding-views}. This method is then passed as
+actual argument to the corresponding view parameter.
+
+Implicit view parameters of a method or class are then taken as
+available view methods in its body.
+
+\example
+trait Comparable[a] {
+ def < (x: a)
+}
+def view(x: String): Comparable[String] {
+}
+
+
+
+
+
+
+
+
+
+There is one such view function
+parameter for every view bounded type parameter.
+
+
+
+In that case, the regular upper
+bound of the
+
+
+
+If $C$ is a base class of $T$ and there exists
+
+
\chapter{Top-Level Definitions}
\label{sec:topdefs}
diff --git a/doc/reference/ReferencePartAppendix.tex b/doc/reference/ReferencePartAppendix.tex
index 98b9e6ecc0..2775166ac8 100644
--- a/doc/reference/ReferencePartAppendix.tex
+++ b/doc/reference/ReferencePartAppendix.tex
@@ -127,9 +127,10 @@ grammar.
| XmlPattern
Patterns ::= Pattern {`,' Pattern}
- TypeParamClause ::= `[' TypeParam {`,' TypeParam} `]'
- FunTypeParamClause ::= `[' TypeDcl {`,' TypeDcl} `]'
- TypeParam ::= [`+' | `-'] TypeDcl
+ TypeParamClause ::= `[' VarTypeParam {`,' VarTypeParam} `]'
+ FunTypeParamClause ::= `[' TypeParam {`,' TypeParam} `]'
+ VarTypeParam ::= [`+' | `-'] TypeParam
+ TypeParam ::= id [>: Type] [<: Type | <% Type]
ParamClause ::= `(' [Param {`,' Param}] `)'
Param ::= [def] id `:' Type [`*']
Bindings ::= id [`:' Type1]
@@ -200,55 +201,6 @@ grammar.
|
Packaging ::= package QualId `{' {TopStat `;'} TopStat `}'
QualId ::= id {`.' id}
-
- XmlExpr ::= Element {Element}
-
- XmlPattern ::= ElementPattern {ElementPattern}
- Element ::= EmptyElemTag
- | STag Content ETag
-
- EmptyElemTag ::= `<' Name {S Attribute} [S] `/>'
-
- STag ::= `<' Name {S Attribute} [S] `>'
- ETag ::= `</' Name [S] '>'
- Content ::= [CharData] {Content1 [CharData]}
- Content1 ::= Element
- | Reference
- | Comment
- | ScalaExpr
- Attribute ::= Name Eq AttValue
- AttValue ::= `"' {CharQ | CharRef} `"'
- | `'' {CharA | CharRef} `''
- | ScalaExp
-
- ScalaExpr ::= `{' expr `}'
-
- CharData ::= { CharNoRef }
- $\mbox{\rm\em without}$ {CharNoRef}`{'CharB {CharNoRef}
- $\mbox{\rm\em and without}$ {CharNoRef}`]]>'{CharNoRef}
-
- BaseChar, Char, Comment, CombiningChar, Ideographic, NameChar, S, Reference
- ::= $\mbox{\rm\em ``as in W3C XML''}$
-
- Char1 ::= Char $\mbox{\rm\em without}$ `<' | `&'
- CharQ ::= Char1 $\mbox{\rm\em without}$ `"'
- CharA ::= Char1 $\mbox{\rm\em without}$ `''
- CharB ::= Char1 $\mbox{\rm\em without}$ '{'
-
- Name ::= XNameStart {NameChar}
-
- XNameStart ::= `_' | BaseChar | Ideographic
- $\mbox{\rm\em (as in W3C XML, but without }$ `:'
-
- ElemPattern ::= EmptyElemTagP
- | STagP ContentP ETagP
-
- EmptyElemTagP ::= '<' Name [S] '/>'
- STagP ::= '<' Name [S] '>'
- ETagP ::= '</' Name [S] '>'
- ContentP ::= [CharData] {(ElemPattern|ScalaPatterns) [CharData]}
- ScalaPatterns ::= '{' patterns '}'
-
\end{lstlisting}
\chapter{Implementation Status}