OLD | NEW |
1 \documentclass{article} | 1 \documentclass{article} |
2 \usepackage{epsfig} | 2 \usepackage{epsfig} |
3 \usepackage{color} | 3 \usepackage{color} |
4 \usepackage{dart} | 4 \usepackage{dart} |
5 \usepackage{bnf} | 5 \usepackage{bnf} |
6 \usepackage{hyperref} | 6 \usepackage{hyperref} |
7 \usepackage{lmodern} | 7 \usepackage{lmodern} |
| 8 \usepackage[T1]{fontenc} |
8 \newcommand{\code}[1]{{\sf #1}} | 9 \newcommand{\code}[1]{{\sf #1}} |
9 \title{Dart Programming Language Specification \\ | 10 \title{Dart Programming Language Specification \\ |
10 {4th edition draft}\\ | 11 {4th edition draft}\\ |
11 {\large Version 1.14}} | 12 {\large Version 1.14}} |
12 | 13 |
13 % For information about Location Markers (and in particular the | 14 % For information about Location Markers (and in particular the |
14 % commands \LMHash and \LMLabel), see the long comment at the | 15 % commands \LMHash and \LMLabel), see the long comment at the |
15 % end of this file. | 16 % end of this file. |
16 | 17 |
17 \begin{document} | 18 \begin{document} |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 \LMHash{} | 208 \LMHash{} |
208 If a declaration $d$ named $n$ is in the namespace induced by a scope $S$, then
$d$ {\em hides} any declaration named $n$ that is available in the lexically en
closing scope of $S$. | 209 If a declaration $d$ named $n$ is in the namespace induced by a scope $S$, then
$d$ {\em hides} any declaration named $n$ that is available in the lexically en
closing scope of $S$. |
209 | 210 |
210 \commentary { | 211 \commentary { |
211 A consequence of these rules is that it is possible to hide a type with a method
or variable. | 212 A consequence of these rules is that it is possible to hide a type with a method
or variable. |
212 Naming conventions usually prevent such abuses. Nevertheless,the following progr
am is legal: | 213 Naming conventions usually prevent such abuses. Nevertheless,the following progr
am is legal: |
213 } | 214 } |
214 | 215 |
215 \begin{dartCode} | 216 \begin{dartCode} |
216 \CLASS{} HighlyStrung \{ | 217 \CLASS{} HighlyStrung \{ |
217 String() $=>$ "?"; | 218 String() => "?"; |
218 \} | 219 \} |
219 \end{dartCode} | 220 \end{dartCode} |
220 | 221 |
221 \LMHash{} | 222 \LMHash{} |
222 Names may be introduced into a scope by declarations within the scope or by ot
her mechanisms such as imports or inheritance. | 223 Names may be introduced into a scope by declarations within the scope or by ot
her mechanisms such as imports or inheritance. |
223 | 224 |
224 \rationale{ | 225 \rationale{ |
225 The interaction of lexical scoping and inheritance is a subtle one. Ultimately,
the question is whether lexical scoping takes precedence over inheritance or vi
ce versa. Dart chooses the former. | 226 The interaction of lexical scoping and inheritance is a subtle one. Ultimately,
the question is whether lexical scoping takes precedence over inheritance or vi
ce versa. Dart chooses the former. |
226 | 227 |
227 Allowing inherited names to take precedence over locally declared names can crea
te unexpected situations as code evolves. Specifically, the behavior of code in
a subclass can change without warning if a new name is introduced in a supercla
ss. Consider: | 228 Allowing inherited names to take precedence over locally declared names can crea
te unexpected situations as code evolves. Specifically, the behavior of code in
a subclass can change without warning if a new name is introduced in a supercla
ss. Consider: |
228 } | 229 } |
229 | 230 |
230 \begin{dartCode} | 231 \begin{dartCode} |
231 \LIBRARY{} L1; | 232 \LIBRARY{} L1; |
232 \CLASS{} S \{\} | 233 \CLASS{} S \{\} |
233 | 234 |
234 \LIBRARY{} L2; | 235 \LIBRARY{} L2; |
235 \IMPORT{} `L1.dart'; | 236 \IMPORT{} `L1.dart'; |
236 foo() =$>$ 42; | 237 foo() => 42; |
237 \CLASS{} C \EXTENDS{} S\{ bar() =$>$ foo();\} | 238 \CLASS{} C \EXTENDS{} S\{ bar() => foo();\} |
238 \end{dartCode} | 239 \end{dartCode} |
239 | 240 |
240 \rationale{Now assume a method \code{foo()} is added to \code{S}. } | 241 \rationale{Now assume a method \code{foo()} is added to \code{S}. } |
241 | 242 |
242 \begin{dartCode} | 243 \begin{dartCode} |
243 \LIBRARY{} L1; | 244 \LIBRARY{} L1; |
244 \CLASS{} S \{foo() =$>$ 91;\} | 245 \CLASS{} S \{foo() => 91;\} |
245 \end{dartCode} | 246 \end{dartCode} |
246 | 247 |
247 \rationale{ | 248 \rationale{ |
248 If inheritance took precedence over the lexical scope, the behavior of \code{C}
would change in an unexpected way. Neither the author of \code{S} nor the author
of \code{C} are necessarily aware of this. In Dart, if there is a lexically vis
ible method \code{foo()}, it will always be called. | 249 If inheritance took precedence over the lexical scope, the behavior of \code{C}
would change in an unexpected way. Neither the author of \code{S} nor the author
of \code{C} are necessarily aware of this. In Dart, if there is a lexically vis
ible method \code{foo()}, it will always be called. |
249 | 250 |
250 Now consider the opposite scenario. We start with a version of \code{S} that con
tains \code{foo()}, but do not declare \code{foo()} in library \code{L2}. Again
, there is a change in behavior - but the author of \code{L2} is the one who int
roduced the discrepancy that effects their code, and the new code is lexically v
isible. Both these factors make it more likely that the problem will be detected
. | 251 Now consider the opposite scenario. We start with a version of \code{S} that con
tains \code{foo()}, but do not declare \code{foo()} in library \code{L2}. Again
, there is a change in behavior - but the author of \code{L2} is the one who int
roduced the discrepancy that effects their code, and the new code is lexically v
isible. Both these factors make it more likely that the problem will be detected
. |
251 | 252 |
252 These considerations become even more important if one introduces constructs suc
h as nested classes, which might be considered in future versions of the languag
e. | 253 These considerations become even more important if one introduces constructs suc
h as nested classes, which might be considered in future versions of the languag
e. |
253 | 254 |
254 Good tooling should of course endeavor to inform programmers of such situations
(discreetly). For example, an identifier that is both inherited and lexically vi
sible could be highlighted (via underlining or colorization). Better yet, tight
integration of source control with language aware tools would detect such change
s when they occur. | 255 Good tooling should of course endeavor to inform programmers of such situations
(discreetly). For example, an identifier that is both inherited and lexically vi
sible could be highlighted (via underlining or colorization). Better yet, tight
integration of source control with language aware tools would detect such change
s when they occur. |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 \LMHash{} | 564 \LMHash{} |
564 All functions have a signature and a body. The signature describes the formal pa
rameters of the function, and possibly its name and return type. A function bod
y is either: | 565 All functions have a signature and a body. The signature describes the formal pa
rameters of the function, and possibly its name and return type. A function bod
y is either: |
565 \begin{itemize} | 566 \begin{itemize} |
566 \item A block statement (\ref{blocks}) containing the statements (\ref{stateme
nts}) executed by the function, optionally marked with one of the modifiers: \AS
YNC, \ASYNC* or \SYNC*. In this case, if the last statement of a function is not
a return statement (\ref{return}), the statement \code{\RETURN{};} is implicitl
y appended to the function body. | 567 \item A block statement (\ref{blocks}) containing the statements (\ref{stateme
nts}) executed by the function, optionally marked with one of the modifiers: \AS
YNC, \ASYNC* or \SYNC*. In this case, if the last statement of a function is not
a return statement (\ref{return}), the statement \code{\RETURN{};} is implicitl
y appended to the function body. |
567 | 568 |
568 \rationale{ | 569 \rationale{ |
569 Because Dart is optionally typed, we cannot guarantee that a function that does
not return a value will not be used in the context of an expression. Therefore,
every function must return a value. A \RETURN{} without an expression returns \N
ULL{}. For generator functions, the situation is more subtle. See further discus
sion in section \ref{return}. | 570 Because Dart is optionally typed, we cannot guarantee that a function that does
not return a value will not be used in the context of an expression. Therefore,
every function must return a value. A \RETURN{} without an expression returns \N
ULL{}. For generator functions, the situation is more subtle. See further discus
sion in section \ref{return}. |
570 } | 571 } |
571 | 572 |
572 OR | 573 OR |
573 \item of the form \code{=$>$ $e$} which is equivalent to a body of the form \c
ode{\{\RETURN{} $e$;\}} or the form \code{\ASYNC{} =$>$ $e$} which is equivalent
to a body of the form \code{\ASYNC{} \{\RETURN{} $e$;\}}. \rationale{The other
modifiers do not apply here, because they apply only to generators, discussed be
low, and generators do not allow the form \code{\RETURN{} $e$}; values are added
to the generated stream or iterable using \YIELD{} instead.} | 574 \item of the form \code{=> $e$} which is equivalent to a body of the form \cod
e{\{\RETURN{} $e$;\}} or the form \code{\ASYNC{} => $e$} which is equivalent to
a body of the form \code{\ASYNC{} \{\RETURN{} $e$;\}}. \rationale{The other modi
fiers do not apply here, because they apply only to generators, discussed below,
and generators do not allow the form \code{\RETURN{} $e$}; values are added to
the generated stream or iterable using \YIELD{} instead.} |
574 | 575 |
575 \end{itemize} | 576 \end{itemize} |
576 | 577 |
577 \LMHash{} | 578 \LMHash{} |
578 A function is {\em asynchronous} if its body is marked with the \ASYNC{} or \ASY
NC* modifier. Otherwise the function is {\em synchronous}. A function is a {\em
generator} if its body is marked with the \SYNC* or \ASYNC* modifier. | 579 A function is {\em asynchronous} if its body is marked with the \ASYNC{} or \ASY
NC* modifier. Otherwise the function is {\em synchronous}. A function is a {\em
generator} if its body is marked with the \SYNC* or \ASYNC* modifier. |
579 | 580 |
580 \commentary{ | 581 \commentary{ |
581 Whether a function is synchronous or asynchronous is orthogonal to whether it is
a generator or not. Generator functions are a sugar for functions that produce
collections in a systematic way, by lazily applying a function that {\em generat
es} individual elements of a collection. Dart provides such a sugar in both the
synchronous case, where one returns an iterable, and in the asynchronous case, w
here one returns a stream. Dart also allows both synchronous and asynchronous fu
nctions that produce a single value. | 582 Whether a function is synchronous or asynchronous is orthogonal to whether it is
a generator or not. Generator functions are a sugar for functions that produce
collections in a systematic way, by lazily applying a function that {\em generat
es} individual elements of a collection. Dart provides such a sugar in both the
synchronous case, where one returns an iterable, and in the asynchronous case, w
here one returns a stream. Dart also allows both synchronous and asynchronous fu
nctions that produce a single value. |
582 } | 583 } |
583 | 584 |
584 \LMHash{} | 585 \LMHash{} |
585 It is a compile-time error if an \ASYNC, \ASYNC* or \SYNC* modifier is attached
to the body of a setter or constructor. | 586 It is a compile-time error if an \ASYNC, \ASYNC* or \SYNC* modifier is attached
to the body of a setter or constructor. |
586 | 587 |
587 \rationale{ | 588 \rationale{ |
588 An asynchronous setter would be of little use, since setters can only be used in
the context of an assignment (\ref{assignment}), and an assignment expression a
lways evaluates to the value of the assignment's right hand side. If the setter
actually did its work asynchronously, one might imagine that one would return a
future that resolved to the assignment's right hand side after the setter did it
s work. However, this would require dynamic tests at every assignment, and so wo
uld be prohibitively expensive. | 589 An asynchronous setter would be of little use, since setters can only be used in
the context of an assignment (\ref{assignment}), and an assignment expression a
lways evaluates to the value of the assignment's right hand side. If the setter
actually did its work asynchronously, one might imagine that one would return a
future that resolved to the assignment's right hand side after the setter did it
s work. However, this would require dynamic tests at every assignment, and so wo
uld be prohibitively expensive. |
589 | 590 |
590 An asynchronous constructor would, by definition, never return an instance of th
e class it purports to construct, but instead return a future. Calling such a be
ast via \NEW{} would be very confusing. If you need to produce an object asynchr
onously, use a method. | 591 An asynchronous constructor would, by definition, never return an instance of th
e class it purports to construct, but instead return a future. Calling such a be
ast via \NEW{} would be very confusing. If you need to produce an object asynchr
onously, use a method. |
591 | 592 |
592 One could allow modifiers for factories. A factory for \code{Future} could be mo
dified by \ASYNC{}, a factory for \code{Stream} could be modified by \ASYNC* and
a factory for \code{Iterable} could be modified by \SYNC*. No other scenario ma
kes sense because the object returned by the factory would be of the wrong type.
This situation is very unusual so it is not worth making an exception to the ge
neral rule for constructors in order to allow it. | 593 One could allow modifiers for factories. A factory for \code{Future} could be mo
dified by \ASYNC{}, a factory for \code{Stream} could be modified by \ASYNC* and
a factory for \code{Iterable} could be modified by \SYNC*. No other scenario ma
kes sense because the object returned by the factory would be of the wrong type.
This situation is very unusual so it is not worth making an exception to the ge
neral rule for constructors in order to allow it. |
593 } | 594 } |
594 \LMHash{} | 595 \LMHash{} |
595 It is a static warning if the declared return type of a function marked \ASYNC{}
is not a supertype of \code{Future$<$\mbox{$T$}$>$} for some type $T$. | 596 It is a static warning if the declared return type of a function marked \ASYNC{}
is not a supertype of \code{Future<\mbox{$T$}>} for some type $T$. |
596 It is a static warning if the declared return type of a function marked \SYNC* i
s not a supertype of \code{Iterable$<$\mbox{$T$}$>$} for some type $T$. | 597 It is a static warning if the declared return type of a function marked \SYNC* i
s not a supertype of \code{Iterable<\mbox{$T$}>} for some type $T$. |
597 It is a static warning if the declared return type of a function marked \ASYNC*
is not a supertype of \code{Stream$<$\mbox{$T$}$>$} for some type $T$. | 598 It is a static warning if the declared return type of a function marked \ASYNC*
is not a supertype of \code{Stream<\mbox{$T$}>} for some type $T$. |
598 | 599 |
599 \subsection{Function Declarations} | 600 \subsection{Function Declarations} |
600 \LMLabel{functionDeclarations} | 601 \LMLabel{functionDeclarations} |
601 | 602 |
602 \LMHash{} | 603 \LMHash{} |
603 A {\em function declaration} is a function that is neither a member of a class n
or a function literal. Function declarations include {\em library functions}, wh
ich are function declarations | 604 A {\em function declaration} is a function that is neither a member of a class n
or a function literal. Function declarations include {\em library functions}, wh
ich are function declarations |
604 %(including getters and setters) | 605 %(including getters and setters) |
605 at the top level of a library, and {\em local functions}, which are function dec
larations declared inside other functions. Library functions are often referred
to simply as top-level functions. | 606 at the top level of a library, and {\em local functions}, which are function dec
larations declared inside other functions. Library functions are often referred
to simply as top-level functions. |
606 | 607 |
607 \LMHash{} | 608 \LMHash{} |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 It is a compile-time error if a class has an instance member and a static member
with the same name. | 925 It is a compile-time error if a class has an instance member and a static member
with the same name. |
925 % It is a compile-time error if a generic (\ref{generics}) class declares a memb
er with the same name as one of its type parameters. | 926 % It is a compile-time error if a generic (\ref{generics}) class declares a memb
er with the same name as one of its type parameters. |
926 | 927 |
927 \commentary{Here are simple examples, that illustrate the difference between ``h
as a member'' and ``declares a member''. For example, \code{B} {\em declares} on
e member named \code{f}, but {\em has} two such members. The rules of inheritanc
e determine what members a class has. | 928 \commentary{Here are simple examples, that illustrate the difference between ``h
as a member'' and ``declares a member''. For example, \code{B} {\em declares} on
e member named \code{f}, but {\em has} two such members. The rules of inheritanc
e determine what members a class has. |
928 } | 929 } |
929 | 930 |
930 \begin{dartCode} | 931 \begin{dartCode} |
931 \CLASS{} A \{ | 932 \CLASS{} A \{ |
932 \VAR{} i = 0; | 933 \VAR{} i = 0; |
933 \VAR{} j; | 934 \VAR{} j; |
934 f(x) =$>$ 3; | 935 f(x) => 3; |
935 \} | 936 \} |
936 | 937 |
937 \CLASS{} B \EXTENDS{} A \{ | 938 \CLASS{} B \EXTENDS{} A \{ |
938 int i = 1; // getter i and setter i= override versions from A | 939 int i = 1; // getter i and setter i= override versions from A |
939 \STATIC{} j; // compile-time error: static getter \& setter conflict with | 940 \STATIC{} j; // compile-time error: static getter \& setter conflict with |
940 //instance getter \& setter | 941 //instance getter \& setter |
941 | 942 |
942 /* compile-time error: static method conflicts with instance method */ | 943 /* compile-time error: static method conflicts with instance method */ |
943 \STATIC{} f(x) =$>$ 3; | 944 \STATIC{} f(x) => 3; |
944 \} | 945 \} |
945 \end{dartCode} | 946 \end{dartCode} |
946 | 947 |
947 \LMHash{} | 948 \LMHash{} |
948 It is a compile time error if a class $C$ declares a member with the same name a
s $C$. It is a compile time error if a generic class declares a type variable wi
th the same name as the class or any of its members or constructors. | 949 It is a compile time error if a class $C$ declares a member with the same name a
s $C$. It is a compile time error if a generic class declares a type variable wi
th the same name as the class or any of its members or constructors. |
949 | 950 |
950 \subsection{Instance Methods} | 951 \subsection{Instance Methods} |
951 \LMLabel{instanceMethods} | 952 \LMLabel{instanceMethods} |
952 | 953 |
953 \LMHash{} | 954 \LMHash{} |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 relationalOperator; | 990 relationalOperator; |
990 `=='; | 991 `=='; |
991 bitwiseOperator | 992 bitwiseOperator |
992 . | 993 . |
993 \end{grammar} | 994 \end{grammar} |
994 | 995 |
995 \LMHash{} | 996 \LMHash{} |
996 An operator declaration is identified using the built-in identifier (\ref{identi
fierReference}) \OPERATOR{}. | 997 An operator declaration is identified using the built-in identifier (\ref{identi
fierReference}) \OPERATOR{}. |
997 | 998 |
998 \LMHash{} | 999 \LMHash{} |
999 The following names are allowed for user-defined operators: \code{$<$, $>$, $<$=
, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$, []=, [], \~{}.} | 1000 The following names are allowed for user-defined operators: \code{<, >, <=, >=,
==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$, []=, [], \~{}.} |
1000 | 1001 |
1001 | 1002 |
1002 \LMHash{} | 1003 \LMHash{} |
1003 It is a compile-time error if the arity of the user-declared operator \code{[]=}
is not 2. It is a compile-time error if the arity of a user-declared operator w
ith one of the names: \code{ $<$, $>$, $<$=, $>$=, ==, -, +, \~{}/, /, *, \%,
$|$, \^{}, \&, $<<$, $>>$, []} is not 1. It is a compile-time error if the arity
of the user-declared operator \code{-} is not 0 or 1. | 1004 It is a compile-time error if the arity of the user-declared operator \code{[]=}
is not 2. It is a compile-time error if the arity of a user-declared operator w
ith one of the names: \code{ <, >, <=, >=, ==, -, +, \~{}/, /, *, \%, $|$, \^{
}, \&, $<<$, $>>$, []} is not 1. It is a compile-time error if the arity of the
user-declared operator \code{-} is not 0 or 1. |
1004 | 1005 |
1005 \commentary{ | 1006 \commentary{ |
1006 The \code{-} operator is unique in that two overloaded versions are permitted. I
f the operator has no arguments, it denotes unary minus. If it has an argument,
it denotes binary subtraction. | 1007 The \code{-} operator is unique in that two overloaded versions are permitted. I
f the operator has no arguments, it denotes unary minus. If it has an argument,
it denotes binary subtraction. |
1007 } | 1008 } |
1008 | 1009 |
1009 \LMHash{} | 1010 \LMHash{} |
1010 The name of the unary operator \code{-} is \code{unary-}. | 1011 The name of the unary operator \code{-} is \code{unary-}. |
1011 | 1012 |
1012 \rationale{ | 1013 \rationale{ |
1013 This device allows the two methods to be distinguished for purposes of method lo
okup, override and reflection. | 1014 This device allows the two methods to be distinguished for purposes of method lo
okup, override and reflection. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 \item $m$ overrides a concrete member, or | 1139 \item $m$ overrides a concrete member, or |
1139 \item $C$ has a \cd{noSuchMethod()} method distinct from the one declared in cla
ss \cd{Object}. | 1140 \item $C$ has a \cd{noSuchMethod()} method distinct from the one declared in cla
ss \cd{Object}. |
1140 \end{itemize} | 1141 \end{itemize} |
1141 | 1142 |
1142 \rationale { | 1143 \rationale { |
1143 We wish to warn if one declares a concrete class with abstract members. However,
code like the following should work without warnings: | 1144 We wish to warn if one declares a concrete class with abstract members. However,
code like the following should work without warnings: |
1144 } | 1145 } |
1145 | 1146 |
1146 \begin{dartCode} | 1147 \begin{dartCode} |
1147 class Base \{ | 1148 class Base \{ |
1148 int get one =$>$ 1; | 1149 int get one => 1; |
1149 \} | 1150 \} |
1150 | 1151 |
1151 abstract class Mix \{ | 1152 abstract class Mix \{ |
1152 int get one; | 1153 int get one; |
1153 int get two =$>$ one + one; | 1154 int get two => one + one; |
1154 \} | 1155 \} |
1155 | 1156 |
1156 class C extends Base with Mix \{ \} | 1157 class C extends Base with Mix \{ \} |
1157 \end{dartCode} | 1158 \end{dartCode} |
1158 | 1159 |
1159 \rationale{At run time, the concrete method \cd{one} declared in \cd{Base} will
be executed, and no problem should arise. Therefore no warning should be issued
and so we suppress warnings if a corresponding concrete member exists in the hie
rarchy. } | 1160 \rationale{At run time, the concrete method \cd{one} declared in \cd{Base} will
be executed, and no problem should arise. Therefore no warning should be issued
and so we suppress warnings if a corresponding concrete member exists in the hie
rarchy. } |
1160 | 1161 |
1161 \subsection{Instance Variables} | 1162 \subsection{Instance Variables} |
1162 \LMLabel{instanceVariables} | 1163 \LMLabel{instanceVariables} |
1163 | 1164 |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 \item An abstract class may provide a constant constructor that utilizes the con
stant constructor of another class. | 1494 \item An abstract class may provide a constant constructor that utilizes the con
stant constructor of another class. |
1494 \item A redirecting factory constructors avoids the need for forwarders to repea
t the default values for formal parameters in their signatures. | 1495 \item A redirecting factory constructors avoids the need for forwarders to repea
t the default values for formal parameters in their signatures. |
1495 %\item A generic factory class that aggregates factory constructors for types it
does not implement can still have its type arguments passed correctly. | 1496 %\item A generic factory class that aggregates factory constructors for types it
does not implement can still have its type arguments passed correctly. |
1496 \end{itemize} | 1497 \end{itemize} |
1497 | 1498 |
1498 %An example of the latter point: | 1499 %An example of the latter point: |
1499 %} | 1500 %} |
1500 | 1501 |
1501 | 1502 |
1502 %\begin{dartCode} | 1503 %\begin{dartCode} |
1503 %\CLASS{} W$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { W(w) {...} ...} | 1504 %\CLASS{} W<T> \IMPLEMENTS{} A<T> { W(w) {...} ...} |
1504 %\CLASS{} X$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { X(x) {...} ...} | 1505 %\CLASS{} X<T> \IMPLEMENTS{} A<T> { X(x) {...} ...} |
1505 %\CLASS{} Y$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Y(y) {...} ...} | 1506 %\CLASS{} Y<T> \IMPLEMENTS{} A<T> { Y(y) {...} ...} |
1506 %\CLASS{} Z$<$T$>$ \IMPLEMENTS{} A$<$T$>$ { Z(z) {...} ...} | 1507 %\CLASS{} Z<T> \IMPLEMENTS{} A<T> { Z(z) {...} ...} |
1507 | 1508 |
1508 | 1509 |
1509 %\CLASS{} F$<$T$>$ { // note that F does not implement A | 1510 %\CLASS{} F<T> { // note that F does not implement A |
1510 % \STATIC{} F$<$T$>$ idw(w) $=>$ \NEW{} W$<$T$>$(w); // illegal - T not in sco
pe in idw | 1511 % \STATIC{} F<T> idw(w) => \NEW{} W<T>(w); // illegal - T not in scope in idw |
1511 % \FACTORY{} F.idx(x) $=>$ \NEW{} X$<$T$>$(x); | 1512 % \FACTORY{} F.idx(x) => \NEW{} X<T>(x); |
1512 % \FACTORY{} F.idy(y) $=>$ \NEW{} Y$<$T$>$(y); | 1513 % \FACTORY{} F.idy(y) => \NEW{} Y<T>(y); |
1513 % \STATIC{} F idz(z) $=>$ \NEW{} Z(z); // does not capture the type argument | 1514 % \STATIC{} F idz(z) => \NEW{} Z(z); // does not capture the type argument |
1514 %} | 1515 %} |
1515 | 1516 |
1516 %\CLASS{} A$<$T$>${ | 1517 %\CLASS{} A<T>{ |
1517 % \FACTORY{} A.idw(w) $=>$ F$<$T$>$.idw(w); | 1518 % \FACTORY{} A.idw(w) => F<T>.idw(w); |
1518 %// illegal - cannot pass type parameter to static method | 1519 %// illegal - cannot pass type parameter to static method |
1519 % \FACTORY{} A.idx(x) $=> \NEW{} $F$<$T$>$.idx(x); // works, but allocates a gr
atuitous instance of F | 1520 % \FACTORY{} A.idx(x) $=> \NEW{} $F<T>.idx(x); // works, but allocates a gratui
tous instance of F |
1520 % \FACTORY{} A.idy(y) = Y$<$T$>$; // works | 1521 % \FACTORY{} A.idy(y) = Y<T>; // works |
1521 % \FACTORY{} A.idz(z) $=>$ F.idz(z); // wrong - returns Z$<$Dynamic$>$; no way
to pass type argument | 1522 % \FACTORY{} A.idz(z) => F.idz(z); // wrong - returns Z<Dynamic>; no way to pas
s type argument |
1522 } | 1523 } |
1523 %\end{dartCode} | 1524 %\end{dartCode} |
1524 | 1525 |
1525 \LMHash{} | 1526 \LMHash{} |
1526 It is a compile-time error if $k$ is prefixed with the \CONST{} modifier but $k^
\prime$ is not a constant constructor (\ref{constantConstructors}). | 1527 It is a compile-time error if $k$ is prefixed with the \CONST{} modifier but $k^
\prime$ is not a constant constructor (\ref{constantConstructors}). |
1527 | 1528 |
1528 \LMHash{} | 1529 \LMHash{} |
1529 It is a static warning if the function type of $k^\prime$ is not a subtype of th
e type of $k$. | 1530 It is a static warning if the function type of $k^\prime$ is not a subtype of th
e type of $k$. |
1530 | 1531 |
1531 \commentary{ | 1532 \commentary{ |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1749 It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies an
enumerated type (\ref{enums}), a malformed type or a deferred type (\ref{stati
cTypes}) as a superclass. | 1750 It is a compile-time error if the \EXTENDS{} clause of a class $C$ specifies an
enumerated type (\ref{enums}), a malformed type or a deferred type (\ref{stati
cTypes}) as a superclass. |
1750 % too strict? Do we e want extends List<Undeclared> to work as List<dynamic>? | 1751 % too strict? Do we e want extends List<Undeclared> to work as List<dynamic>? |
1751 | 1752 |
1752 \commentary{ The type parameters of a generic class are available in the lexical
scope of the superclass clause, potentially shadowing classes in the surroundin
g scope. The following code is therefore illegal and should cause a compile-time
error: | 1753 \commentary{ The type parameters of a generic class are available in the lexical
scope of the superclass clause, potentially shadowing classes in the surroundin
g scope. The following code is therefore illegal and should cause a compile-time
error: |
1753 } | 1754 } |
1754 | 1755 |
1755 \begin{dartCode} | 1756 \begin{dartCode} |
1756 class T \{\} | 1757 class T \{\} |
1757 | 1758 |
1758 /* Compilation error: Attempt to subclass a type parameter */ | 1759 /* Compilation error: Attempt to subclass a type parameter */ |
1759 class G$<$T$>$ extends T \{\} | 1760 class G<T> extends T \{\} |
1760 | 1761 |
1761 \end{dartCode} | 1762 \end{dartCode} |
1762 | 1763 |
1763 | 1764 |
1764 \LMHash{} | 1765 \LMHash{} |
1765 A class $S$ is {\em a superclass} of a class $C$ iff either: | 1766 A class $S$ is {\em a superclass} of a class $C$ iff either: |
1766 \begin{itemize} | 1767 \begin{itemize} |
1767 \item $S$ is the superclass of $C$, or | 1768 \item $S$ is the superclass of $C$, or |
1768 \item $S$ is a superclass of a class $S^{\prime}$ and $S^{\prime}$ is a supercla
ss of $C$. | 1769 \item $S$ is a superclass of a class $S^{\prime}$ and $S^{\prime}$ is a supercla
ss of $C$. |
1769 \end{itemize} | 1770 \end{itemize} |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2165 The declaration of an enum of the form \code{metadata \ENUM{} E \{ id$_0$, \ldot
s id$_{n-1}$\};} | 2166 The declaration of an enum of the form \code{metadata \ENUM{} E \{ id$_0$, \ldot
s id$_{n-1}$\};} |
2166 has the same effect as a class declaration | 2167 has the same effect as a class declaration |
2167 | 2168 |
2168 \begin{dartCode} | 2169 \begin{dartCode} |
2169 metadata \CLASS{} E \{ | 2170 metadata \CLASS{} E \{ |
2170 \FINAL{} int index; | 2171 \FINAL{} int index; |
2171 \CONST{} E(\THIS{}.index); | 2172 \CONST{} E(\THIS{}.index); |
2172 \STATIC{} \CONST{} E id$_0$ = \CONST{} E(0); | 2173 \STATIC{} \CONST{} E id$_0$ = \CONST{} E(0); |
2173 $\ldots$ | 2174 $\ldots$ |
2174 \STATIC{} \CONST{} E id$_{n-1}$ = const E(n - 1); | 2175 \STATIC{} \CONST{} E id$_{n-1}$ = const E(n - 1); |
2175 \STATIC{} \CONST{} List$<$E$>$ values = const $<$E$>$[id$_0 \ldots $ id$_{n-1}
$]; | 2176 \STATIC{} \CONST{} List<E> values = const <E>[id$_0 \ldots $ id$_{n-1}$]; |
2176 String toString() =$>$ \{ 0: `E.id$_0$', $\ldots$, n-1: `E.id$_{n-1}$'\}[index
] | 2177 String toString() => \{ 0: `E.id$_0$', $\ldots$, n-1: `E.id$_{n-1}$'\}[index] |
2177 \} | 2178 \} |
2178 \end{dartCode} | 2179 \end{dartCode} |
2179 | 2180 |
2180 \commentary { | 2181 \commentary { |
2181 It is also a compile-time error to subclass, mix-in or implement an enum or to e
xplicitly instantiate an enum. These restrictions are given in normative form i
n sections \ref{superclasses}, \ref{superinterfaces}, \ref{mixinApplication} and
\ref{instanceCreation} as appropriate. | 2182 It is also a compile-time error to subclass, mix-in or implement an enum or to e
xplicitly instantiate an enum. These restrictions are given in normative form i
n sections \ref{superclasses}, \ref{superinterfaces}, \ref{mixinApplication} and
\ref{instanceCreation} as appropriate. |
2182 } | 2183 } |
2183 | 2184 |
2184 \section{Generics} | 2185 \section{Generics} |
2185 \LMLabel{generics} | 2186 \LMLabel{generics} |
2186 | 2187 |
(...skipping 19 matching lines...) Expand all Loading... |
2206 | 2207 |
2207 \rationale{ | 2208 \rationale{ |
2208 The restriction is necessary since a type variable has no meaning in the context
of a static member, because statics are shared among all instantiations of a ge
neric. However, a type variable may be referenced from an instance initializer,
even though \THIS{} is not available. | 2209 The restriction is necessary since a type variable has no meaning in the context
of a static member, because statics are shared among all instantiations of a ge
neric. However, a type variable may be referenced from an instance initializer,
even though \THIS{} is not available. |
2209 } | 2210 } |
2210 | 2211 |
2211 \commentary{ | 2212 \commentary{ |
2212 Because type parameters are in scope in their bounds, we support F-bounded quant
ification (if you don't know what that is, don't ask). This enables typechecking
code such as: | 2213 Because type parameters are in scope in their bounds, we support F-bounded quant
ification (if you don't know what that is, don't ask). This enables typechecking
code such as: |
2213 } | 2214 } |
2214 | 2215 |
2215 \begin{dartCode} | 2216 \begin{dartCode} |
2216 \INTERFACE{} Ordered$<$T$>$ \{ | 2217 \INTERFACE{} Ordered<T> \{ |
2217 operator $>$ (T x); | 2218 operator > (T x); |
2218 \} | 2219 \} |
2219 | 2220 |
2220 \CLASS{} Sorter$<$T \EXTENDS{} Ordered$<$T$>>$ \{ | 2221 \CLASS{} Sorter<T \EXTENDS{} Ordered<T$>>$ \{ |
2221 sort(List$<$T$>$ l) {... l[n] $<$ l[n+1] ...} | 2222 sort(List<T> l) {... l[n] < l[n+1] ...} |
2222 \} | 2223 \} |
2223 | 2224 |
2224 \end{dartCode} | 2225 \end{dartCode} |
2225 | 2226 |
2226 \commentary{ | 2227 \commentary{ |
2227 Even where type parameters are in scope there are numerous restrictions at this
time: | 2228 Even where type parameters are in scope there are numerous restrictions at this
time: |
2228 \begin{itemize} | 2229 \begin{itemize} |
2229 \item A type parameter cannot be used to name a constructor in an instance creat
ion expression (\ref{instanceCreation}). | 2230 \item A type parameter cannot be used to name a constructor in an instance creat
ion expression (\ref{instanceCreation}). |
2230 \item A type parameter cannot be used as a superclass or superinterface (\ref{su
perclasses}, \ref{superinterfaces}, \ref{interfaceSuperinterfaces}). | 2231 \item A type parameter cannot be used as a superclass or superinterface (\ref{su
perclasses}, \ref{superinterfaces}, \ref{interfaceSuperinterfaces}). |
2231 \item A type parameter cannot be used as a generic type. | 2232 \item A type parameter cannot be used as a generic type. |
2232 \end{itemize} | 2233 \end{itemize} |
2233 | 2234 |
2234 The normative versions of these are given in the appropriate sections of this s
pecification. Some of these restrictions may be lifted in the future. | 2235 The normative versions of these are given in the appropriate sections of this s
pecification. Some of these restrictions may be lifted in the future. |
2235 } | 2236 } |
2236 | 2237 |
2237 %The {\em induced type set}, $S$, of a parameterized type $T$ is the set consist
ing of | 2238 %The {\em induced type set}, $S$, of a parameterized type $T$ is the set consist
ing of |
2238 %\begin{itemize} | 2239 %\begin{itemize} |
2239 %\item The supertypes of any type in $S$. | 2240 %\item The supertypes of any type in $S$. |
2240 %\item The type arguments of any parameterized type in $S$. | 2241 %\item The type arguments of any parameterized type in $S$. |
2241 %\end{itemize} | 2242 %\end{itemize} |
2242 | 2243 |
2243 %Let $P$ be the instantiation of a generic type with its own type parameters. It
is a compile-time error if the induced type set of $P$ is not finite. | 2244 %Let $P$ be the instantiation of a generic type with its own type parameters. It
is a compile-time error if the induced type set of $P$ is not finite. |
2244 | 2245 |
2245 %\rationale {A typical recursive type declaration such as} | 2246 %\rationale {A typical recursive type declaration such as} |
2246 | 2247 |
2247 %\begin{dartCode} | 2248 %\begin{dartCode} |
2248 %\CLASS{} B$<$S$>$ \{\} | 2249 %\CLASS{} B<S> \{\} |
2249 %\CLASS{} D$<$T$>$ \EXTENDS{} B$<$D$<$T$>>$ \{\} | 2250 %\CLASS{} D<T> \EXTENDS{} B<D<T$>>$ \{\} |
2250 %\end{dartCode} | 2251 %\end{dartCode} |
2251 | 2252 |
2252 %\rationale{ | 2253 %\rationale{ |
2253 %poses no problem under this rule. The instantiation \cd{D$<$T$>$} has an induce
d | 2254 %poses no problem under this rule. The instantiation \cd{D<T>} has an induced |
2254 %set consisting of: \cd{B$<$D$<$T$>>$, Object, D$<$T$>$, T}. However, the follow
ing variant | 2255 %set consisting of: \cd{B<D<T$>>$, Object, D<T>, T}. However, the following vari
ant |
2255 %} | 2256 %} |
2256 | 2257 |
2257 %\begin{dartCode} | 2258 %\begin{dartCode} |
2258 %\CLASS{} B$<$S$>$ \{\} | 2259 %\CLASS{} B<S> \{\} |
2259 %\CLASS{} D$<$T$>$ \EXTENDS{} B$<$D$<$D$<$T$>>>$ \{\} | 2260 %\CLASS{} D<T> \EXTENDS{} B<D<D<T$>>>$ \{\} |
2260 %\end{dartCode} | 2261 %\end{dartCode} |
2261 | 2262 |
2262 %\rationale{ | 2263 %\rationale{ |
2263 %is disallowed. Consider again the instantiation \cd{D$<$T$>$}. It leads to the | 2264 %is disallowed. Consider again the instantiation \cd{D<T>}. It leads to the |
2264 %superclass \cd{B$<$D$<$D$<$T$>>>$}, and so adds \cd{D$<$D$< $T$>>$} to the indu
ced set. The latter in turn leads to \cd{B$<$D$<$D$<$D$<$T$>>>>$} and \cd{D$<$D
$<$D$<$T$>>>$} | 2265 %superclass \cd{B<D<D<T$>>>$}, and so adds \cd{D<D$< $T$>>$} to the induced set.
The latter in turn leads to \cd{B<D<D<D<T$>>>>$} and \cd{D<D<D<T$>>>$} |
2265 %and so on ad infinitum.} | 2266 %and so on ad infinitum.} |
2266 | 2267 |
2267 %\commentary{ | 2268 %\commentary{ |
2268 %The above requirement does not preclude the use of arbitrary recursive types in
the body of a generic class. } | 2269 %The above requirement does not preclude the use of arbitrary recursive types in
the body of a generic class. } |
2269 %A generic has a type parameter scope. The enclosing scope of a type parameter s
cope of a generic G is the enclosing scope of G. | 2270 %A generic has a type parameter scope. The enclosing scope of a type parameter s
cope of a generic G is the enclosing scope of G. |
2270 | 2271 |
2271 | 2272 |
2272 %class T {...} | 2273 %class T {...} |
2273 | 2274 |
2274 %class G<T> extends T; | 2275 %class G<T> extends T; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2453 \item A constant constructor invocation (\ref{const}) that is not qualified by a
deferred prefix. | 2454 \item A constant constructor invocation (\ref{const}) that is not qualified by a
deferred prefix. |
2454 \item A constant list literal (\ref{lists}). | 2455 \item A constant list literal (\ref{lists}). |
2455 \item A constant map literal (\ref{maps}). | 2456 \item A constant map literal (\ref{maps}). |
2456 \item A simple or qualified identifier denoting a top-level function (\ref{funct
ions}) or a static method (\ref{staticMethods}) that is not qualified by a defer
red prefix. | 2457 \item A simple or qualified identifier denoting a top-level function (\ref{funct
ions}) or a static method (\ref{staticMethods}) that is not qualified by a defer
red prefix. |
2457 \item A parenthesized expression \code{($e$)} where $e$ is a constant expression
. | 2458 \item A parenthesized expression \code{($e$)} where $e$ is a constant expression
. |
2458 \item An expression of the form \code{identical($e_1$, $e_2$)} where $e_1$ and $
e_2$ are constant expressions and \code{identical()} is statically bound to the
predefined dart function \code{identical()} discussed above (\ref{objectIdent
ity}). | 2459 \item An expression of the form \code{identical($e_1$, $e_2$)} where $e_1$ and $
e_2$ are constant expressions and \code{identical()} is statically bound to the
predefined dart function \code{identical()} discussed above (\ref{objectIdent
ity}). |
2459 \item An expression of one of the forms \code{$e_1$ == $e_2$} or \code{$e_1$ !
= $e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numer
ic, string or boolean value or to \NULL{}. | 2460 \item An expression of one of the forms \code{$e_1$ == $e_2$} or \code{$e_1$ !
= $e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numer
ic, string or boolean value or to \NULL{}. |
2460 \item An expression of one of the forms \code{!$e$}, \code{$e_1$ \&\& $e_2$} or
\code{$e_1 || e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that e
valuate to a boolean value. | 2461 \item An expression of one of the forms \code{!$e$}, \code{$e_1$ \&\& $e_2$} or
\code{$e_1 || e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that e
valuate to a boolean value. |
2461 \item An expression of one of the forms \~{}$e$, $e_1$ \^{} $e_2$, \code{$e_1$ \
& $e_2$}, $e_1 | e_2$, $e_1 >> e_2$ or $e_1 << e_2$, where $e$, $e_1$ and $e_2
$ are constant expressions that evaluate to an integer value or to \NULL{}. | 2462 \item An expression of one of the forms \~{}$e$, $e_1$ \^{} $e_2$, \code{$e_1$ \
& $e_2$}, $e_1 | e_2$, $e_1 >> e_2$ or $e_1 << e_2$, where $e$, $e_1$ and $e_2
$ are constant expressions that evaluate to an integer value or to \NULL{}. |
2462 \item An expression of the form \code{$e_1 + e_2$} where $e_1$ and $e_2$ are con
stant expressions that evaluate to a numeric or string value or to \NULL{}. | 2463 \item An expression of the form \code{$e_1 + e_2$} where $e_1$ and $e_2$ are con
stant expressions that evaluate to a numeric or string value or to \NULL{}. |
2463 \item An expression of one of the forms \code{$-e$}, \code{$e_1$ - $e_2$}, \code
{$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e_2$}, \code{$e_1 >
e_2$}, \code{$e_1 < e_2$}, \code{$e_1$ $>$= $e_2$}, \code{$e_1$ $<$= $e_2$} o
r \code{$e_1$ \% $e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions th
at evaluate to a numeric value or to \NULL{}. | 2464 \item An expression of one of the forms \code{$-e$}, \code{$e_1$ - $e_2$}, \code
{$e_1$ * $e_2$}, \code{$e_1$ / $e_2$,} \code{$e_1$ \~{}/ $e_2$}, \code{$e_1 >
e_2$}, \code{$e_1 < e_2$}, \code{$e_1$ >= $e_2$}, \code{$e_1$ <= $e_2$} or \c
ode{$e_1$ \% $e_2$}, where $e$, $e_1$ and $e_2$ are constant expressions that e
valuate to a numeric value or to \NULL{}. |
2464 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $
e_3$ are constant expressions and $e_1$ evaluates to a boolean value. | 2465 \item An expression of the form \code{$e_1$?$e_2$:$e3$} where $e_1$, $e_2$ and $
e_3$ are constant expressions and $e_1$ evaluates to a boolean value. |
2465 \item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are co
nstant expressions. | 2466 \item An expression of the form \code{$e_1 ?? e_2$} where $e_1$ and $e_2$ are co
nstant expressions. |
2466 \item An expression of the form \code{$e$.length} where $e$ is a constant expres
sion that evaluates to a string value. | 2467 \item An expression of the form \code{$e$.length} where $e$ is a constant expres
sion that evaluates to a string value. |
2467 \end{itemize} | 2468 \end{itemize} |
2468 | 2469 |
2469 % null in all the expressions | 2470 % null in all the expressions |
2470 | 2471 |
2471 % designed so constants do not depend on check diode being on or not. | 2472 % designed so constants do not depend on check diode being on or not. |
2472 | 2473 |
2473 \LMHash{} | 2474 \LMHash{} |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3146 | 3147 |
3147 In any other circumstance, $flatten(T) = T$. | 3148 In any other circumstance, $flatten(T) = T$. |
3148 | 3149 |
3149 | 3150 |
3150 | 3151 |
3151 \rationale{ | 3152 \rationale{ |
3152 We collapse multiple layers of futures into one. If $e$ evaluates to a future $f
$, the future will not invoke its \code{then()} callback until f completes to a
non-future value, and so the result of an await is never a future, and the resul
t of an async function will never have type \code{Future$<X>$} where $X$ itself
is an invocation of \code{Future}. | 3153 We collapse multiple layers of futures into one. If $e$ evaluates to a future $f
$, the future will not invoke its \code{then()} callback until f completes to a
non-future value, and so the result of an await is never a future, and the resul
t of an async function will never have type \code{Future$<X>$} where $X$ itself
is an invocation of \code{Future}. |
3153 | 3154 |
3154 The exception to that would be a type $X$ that extended or implemented \code{Fu
ture}. In that case, only one unwrapping takes place. As an example of why this
is done, consider | 3155 The exception to that would be a type $X$ that extended or implemented \code{Fu
ture}. In that case, only one unwrapping takes place. As an example of why this
is done, consider |
3155 | 3156 |
3156 \cd{\CLASS{} C$<$T$>$ \IMPLEMENTS{} Future$<$C$<$C$<$T$>>>$ \ldots } | 3157 \cd{\CLASS{} C<T> \IMPLEMENTS{} Future<C<C<T$>>>$ \ldots } |
3157 | 3158 |
3158 Here, a naive definition of $flatten$ diverges; there is not even a fixed point.
A more sophisticated definition of $flatten$ is possible, but the existing rule
deals with most realistic examples while remaining relatively simple to underst
and. | 3159 Here, a naive definition of $flatten$ diverges; there is not even a fixed point.
A more sophisticated definition of $flatten$ is possible, but the existing rule
deals with most realistic examples while remaining relatively simple to underst
and. |
3159 | 3160 |
3160 } | 3161 } |
3161 | 3162 |
3162 | 3163 |
3163 \LMHash{} | 3164 \LMHash{} |
3164 The static type of a function literal of the form | 3165 The static type of a function literal of the form |
3165 | 3166 |
3166 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_
{n+k} = d_k\}) => e$ | 3167 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_
{n+k} = d_k\}) => e$ |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3505 \} | 3506 \} |
3506 | 3507 |
3507 \CONST{} A("x"); // compile-time error | 3508 \CONST{} A("x"); // compile-time error |
3508 \CONST{} A(5); // legal | 3509 \CONST{} A(5); // legal |
3509 | 3510 |
3510 | 3511 |
3511 \CLASS{} IntPair \{ | 3512 \CLASS{} IntPair \{ |
3512 \CONST{} IntPair(\THIS{}.x, \THIS{}.y); | 3513 \CONST{} IntPair(\THIS{}.x, \THIS{}.y); |
3513 \FINAL{} int x; | 3514 \FINAL{} int x; |
3514 \FINAL{} int y; | 3515 \FINAL{} int y; |
3515 \OPERATOR *(v) $=>$ \NEW{} IntPair(x*v, y*v); | 3516 \OPERATOR *(v) => \NEW{} IntPair(x*v, y*v); |
3516 \} | 3517 \} |
3517 | 3518 |
3518 \CONST{} A(\CONST{} IntPair(1,2)); // compile-time error: illegal in a subtler w
ay | 3519 \CONST{} A(\CONST{} IntPair(1,2)); // compile-time error: illegal in a subtler w
ay |
3519 \end{dartCode} | 3520 \end{dartCode} |
3520 | 3521 |
3521 \commentary{ | 3522 \commentary{ |
3522 Due to the rules governing constant constructors, evaluating the constructor \co
de{A()} with the argument \code{"x"} or the argument \code{\CONST{} IntPair(1, 2
)} would cause it to throw an exception, resulting in a compile-time error. | 3523 Due to the rules governing constant constructors, evaluating the constructor \co
de{A()} with the argument \code{"x"} or the argument \code{\CONST{} IntPair(1, 2
)} would cause it to throw an exception, resulting in a compile-time error. |
3523 } | 3524 } |
3524 | 3525 |
3525 | 3526 |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3897 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. | 3898 \item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}. |
3898 \end{itemize} | 3899 \end{itemize} |
3899 | 3900 |
3900 and the result of the latter invocation is the result of evaluating $i$. | 3901 and the result of the latter invocation is the result of evaluating $i$. |
3901 | 3902 |
3902 \rationale { | 3903 \rationale { |
3903 It is possible to bring about such a situation by overriding \code{noSuchMethod(
)} with the wrong number of arguments:} | 3904 It is possible to bring about such a situation by overriding \code{noSuchMethod(
)} with the wrong number of arguments:} |
3904 | 3905 |
3905 \begin{code} | 3906 \begin{code} |
3906 \CLASS{} Perverse \{ | 3907 \CLASS{} Perverse \{ |
3907 noSuchMethod(x,y) =$>$ x + y; | 3908 noSuchMethod(x,y) => x + y; |
3908 \} | 3909 \} |
3909 | 3910 |
3910 \NEW{} Perverse.unknownMethod(); | 3911 \NEW{} Perverse.unknownMethod(); |
3911 \end{code} | 3912 \end{code} |
3912 | 3913 |
3913 \commentary{Notice that the wording carefully avoids re-evaluating the receiver
$o$ and the arguments $a_i$. } | 3914 \commentary{Notice that the wording carefully avoids re-evaluating the receiver
$o$ and the arguments $a_i$. } |
3914 | 3915 |
3915 \LMHash{} | 3916 \LMHash{} |
3916 Let $T$ be the static type of $o$. It is a static type warning if $T$ does not
have an accessible (\ref{privacy}) instance member named $m$ unless either: | 3917 Let $T$ be the static type of $o$. It is a static type warning if $T$ does not
have an accessible (\ref{privacy}) instance member named $m$ unless either: |
3917 \begin{itemize} | 3918 \begin{itemize} |
3918 \item | 3919 \item |
3919 $T$ or a superinterface of $T$ is annotated with an annotation denoting a consta
nt identical to the constant \code{@proxy} defined in \code{dart:core}. Or | 3920 $T$ or a superinterface of $T$ is annotated with an annotation denoting a consta
nt identical to the constant \code{@proxy} defined in \code{dart:core}. Or |
3920 \item $T$ is \code{Type}, $e$ is a constant type literal and the class correspo
nding to $e$ has a static getter named $m$. | 3921 \item $T$ is \code{Type}, $e$ is a constant type literal and the class correspo
nding to $e$ has a static getter named $m$. |
3921 \item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Functi
on} is treated as if it has a \code{call} method for any possible signature of \
CALL. The expectation is that any concrete subclass of \code{Function} will impl
ement \CALL. Note that a warning will be issue if this is not the case. Furtherm
ore, any use of \CALL{} on a subclass of \code{Function} that fails to implement
\CALL{} will also provoke a warning, as this exemption is limited to type \code
{Function}, and does not apply to its subtypes. | 3922 \item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Functi
on} is treated as if it has a \code{call} method for any possible signature of \
CALL. The expectation is that any concrete subclass of \code{Function} will impl
ement \CALL. Note that a warning will be issue if this is not the case. Furtherm
ore, any use of \CALL{} on a subclass of \code{Function} that fails to implement
\CALL{} will also provoke a warning, as this exemption is limited to type \code
{Function}, and does not apply to its subtypes. |
3922 } | 3923 } |
3923 \end{itemize} | 3924 \end{itemize} |
3924 | 3925 |
3925 \LMHash{} | 3926 \LMHash{} |
3926 If $T.m$ exists, it is a static type warning if the type $F$ of $T.m$ may not b
e assigned to a function type. If $T.m$ does not exist, or if $F$ is not a funct
ion type, the static type of $fi$ is \DYNAMIC{}; otherwise the static type of $i
$ is the declared return type of $F$. | 3927 If $T.m$ exists, it is a static type warning if the type $F$ of $T.m$ may not b
e assigned to a function type. If $T.m$ does not exist, or if $F$ is not a funct
ion type, the static type of $i$ is \DYNAMIC{}; otherwise the static type of $i$
is the declared return type of $F$. |
3927 | 3928 |
3928 \LMHash{} | 3929 \LMHash{} |
3929 It is a compile-time error to invoke any of the methods of class \cd{Object} on
a prefix object (\ref{imports}) or on a constant type literal that is immediate
ly followed by the token `.'. | 3930 It is a compile-time error to invoke any of the methods of class \cd{Object} on
a prefix object (\ref{imports}) or on a constant type literal that is immediate
ly followed by the token `.'. |
3930 | 3931 |
3931 | 3932 |
3932 \subsubsection{Cascaded Invocations} | 3933 \subsubsection{Cascaded Invocations} |
3933 \LMLabel{cascadedInvocations} | 3934 \LMLabel{cascadedInvocations} |
3934 | 3935 |
3935 \LMHash{} | 3936 \LMHash{} |
3936 A {\em cascaded method invocation} has the form \code{$e$..\metavar{suffix}} | 3937 A {\em cascaded method invocation} has the form \code{$e$..\metavar{suffix}} |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4163 \end{itemize} | 4164 \end{itemize} |
4164 | 4165 |
4165 | 4166 |
4166 \subsubsection{Ordinary Member Closurization} | 4167 \subsubsection{Ordinary Member Closurization} |
4167 \LMLabel{ordinaryMemberClosurization} | 4168 \LMLabel{ordinaryMemberClosurization} |
4168 | 4169 |
4169 \LMHash{} | 4170 \LMHash{} |
4170 Let $o$ be an object, and let $u$ be a fresh final variable bound to $o$. | 4171 Let $o$ be an object, and let $u$ be a fresh final variable bound to $o$. |
4171 The {\em closurization of method $f$ on object $o$} is defined to be equivalent
to: | 4172 The {\em closurization of method $f$ on object $o$} is defined to be equivalent
to: |
4172 \begin{itemize} | 4173 \begin{itemize} |
4173 %\item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$ and $op$ is one of
\code{$<$, $>$, $<$=, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $
>>$} (this precludes closurization of unary -). | 4174 %\item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$ and $op$ is one of
\code{<, >, <=, >=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$} (th
is precludes closurization of unary -). |
4174 %\item $() \{\RETURN{}$ \~{} $u;$\} if $f$ is named \~{}. | 4175 %\item $() \{\RETURN{}$ \~{} $u;$\} if $f$ is named \~{}. |
4175 %\item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named $[]$. | 4176 %\item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named $[]$. |
4176 %\item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named $[]=$. | 4177 %\item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named $[]=$. |
4177 \item | 4178 \item |
4178 \begin{dartCode} | 4179 \begin{dartCode} |
4179 $(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{ | 4180 $(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{ |
4180 \RETURN{} $ u.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ | 4181 \RETURN{} $ u.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ |
4181 \} | 4182 \} |
4182 \end{dartCode} | 4183 \end{dartCode} |
4183 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa
rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4184 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa
rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
(...skipping 20 matching lines...) Expand all Loading... |
4204 } | 4205 } |
4205 | 4206 |
4206 \subsubsection{Super Closurization} | 4207 \subsubsection{Super Closurization} |
4207 \LMLabel{superClosurization} | 4208 \LMLabel{superClosurization} |
4208 | 4209 |
4209 \LMHash{} | 4210 \LMHash{} |
4210 The {\em closurization of method $f$ with respect to superclass $S$} is defined
to be equivalent to: | 4211 The {\em closurization of method $f$ with respect to superclass $S$} is defined
to be equivalent to: |
4211 | 4212 |
4212 \LMHash{} | 4213 \LMHash{} |
4213 \begin{itemize} | 4214 \begin{itemize} |
4214 %\item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$ and $op$ is o
ne of \code{$<$, $>$, $<$=, $>$=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<
<$, $>>$}. | 4215 %\item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$ and $op$ is o
ne of \code{<, >, <=, >=, ==, -, +, /, \~{}/, *, \%, $|$, \^{}, \&, $<<$, $>>$
}. |
4215 %\item $() \{\RETURN{}$ \~{}\SUPER;\} if $f$ is named \~{}. | 4216 %\item $() \{\RETURN{}$ \~{}\SUPER;\} if $f$ is named \~{}. |
4216 %\item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named $[]$. | 4217 %\item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named $[]$. |
4217 %\item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named $[]=$. | 4218 %\item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named $[]=$. |
4218 \item | 4219 \item |
4219 \begin{dartCode} | 4220 \begin{dartCode} |
4220 $(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{ | 4221 $(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{ |
4221 \RETURN{} \SUPER$.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ | 4222 \RETURN{} \SUPER$.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$ |
4222 \} | 4223 \} |
4223 \end{dartCode} | 4224 \end{dartCode} |
4224 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa
rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. | 4225 if $f$ is named $m$ and has required parameters $r_1, \ldots, r_n$, and named pa
rameters $p_1, \ldots, p_k$ with defaults $d_1, \ldots, d_k$. |
(...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5480 \LMHash{} | 5481 \LMHash{} |
5481 Executing a variable declaration statement of one of the forms \VAR{} $v = e;$
, $T$ $v = e; $, \CONST{} $v = e;$, \CONST{} $T$ $v = e;$, \FINAL{} $v = e;$ o
r \FINAL{} $T$ $v = e;$ proceeds as follows: | 5482 Executing a variable declaration statement of one of the forms \VAR{} $v = e;$
, $T$ $v = e; $, \CONST{} $v = e;$, \CONST{} $T$ $v = e;$, \FINAL{} $v = e;$ o
r \FINAL{} $T$ $v = e;$ proceeds as follows: |
5482 | 5483 |
5483 \LMHash{} | 5484 \LMHash{} |
5484 The expression $e$ is evaluated to an object $o$. Then, the variable $v$ is set
to $o$. | 5485 The expression $e$ is evaluated to an object $o$. Then, the variable $v$ is set
to $o$. |
5485 | 5486 |
5486 \LMHash{} | 5487 \LMHash{} |
5487 A variable declaration statement of the form \VAR{} $v;$ is equivalent to \VAR{
} $v = \NULL{};$. A variable declaration statement of the form $T$ $v;$ is equiv
alent to $T$ $v = \NULL{};$. | 5488 A variable declaration statement of the form \VAR{} $v;$ is equivalent to \VAR{
} $v = \NULL{};$. A variable declaration statement of the form $T$ $v;$ is equiv
alent to $T$ $v = \NULL{};$. |
5488 | 5489 |
5489 \commentary{ | 5490 \commentary{ |
5490 This holds regardless of the type $T$. For example, \code{int i;} does not cause
\code{i} to be initialized to zero. Instead, \code{i} is initialized to \NULL{}
, just as if we had written \VAR{} \code{i;} or \code{Object i;} or \code{Collec
tion$<$String$>$ i;}. | 5491 This holds regardless of the type $T$. For example, \code{int i;} does not cause
\code{i} to be initialized to zero. Instead, \code{i} is initialized to \NULL{}
, just as if we had written \VAR{} \code{i;} or \code{Object i;} or \code{Collec
tion<String> i;}. |
5491 } | 5492 } |
5492 | 5493 |
5493 \rationale{ | 5494 \rationale{ |
5494 To do otherwise would undermine the optionally typed nature of Dart, causing typ
e annotations to modify program behavior. | 5495 To do otherwise would undermine the optionally typed nature of Dart, causing typ
e annotations to modify program behavior. |
5495 } | 5496 } |
5496 | 5497 |
5497 %A variable declaration statement of one of the forms $T$ $v;$, $T$ $v = e;$, \C
ONST{} $T$ $v = e;$, or \FINAL{} $T$ $v = e;$ causes a new getter named $v$ wit
h static return type $T$ to be added to the innermost enclosing scope at the poi
nt following the variable declaration statement. The result of executing this ge
tter is the value stored in $v$. | 5498 %A variable declaration statement of one of the forms $T$ $v;$, $T$ $v = e;$, \C
ONST{} $T$ $v = e;$, or \FINAL{} $T$ $v = e;$ causes a new getter named $v$ wit
h static return type $T$ to be added to the innermost enclosing scope at the poi
nt following the variable declaration statement. The result of executing this ge
tter is the value stored in $v$. |
5498 | 5499 |
5499 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e
;$ or \FINAL{} $v = e;$ causes a new getter named $v$ with static return type
\DYNAMIC{} to be added to the innermost enclosing scope at the point following
the variable declaration statement. The result of executing this getter is the
value stored in $v$. | 5500 %A variable declaration statement \VAR{} $v;$, \VAR{} $v = e;$, \CONST{} $v = e
;$ or \FINAL{} $v = e;$ causes a new getter named $v$ with static return type
\DYNAMIC{} to be added to the innermost enclosing scope at the point following
the variable declaration statement. The result of executing this getter is the
value stored in $v$. |
5500 | 5501 |
(...skipping 19 matching lines...) Expand all Loading... |
5520 \end{grammar} | 5521 \end{grammar} |
5521 | 5522 |
5522 \LMHash{} | 5523 \LMHash{} |
5523 A function declaration statement of one of the forms $id$ $signature$ $\{ statem
ents \}$ or $T$ $id$ $signature$ $\{ statements \}$ causes a new function named
$id$ to be added to the innermost enclosing scope. It is a compile-time error to
reference a local function before its declaration. | 5524 A function declaration statement of one of the forms $id$ $signature$ $\{ statem
ents \}$ or $T$ $id$ $signature$ $\{ statements \}$ causes a new function named
$id$ to be added to the innermost enclosing scope. It is a compile-time error to
reference a local function before its declaration. |
5524 | 5525 |
5525 | 5526 |
5526 \commentary{ This implies that local functions can be directly recursive, but no
t mutually recursive. Consider these examples: | 5527 \commentary{ This implies that local functions can be directly recursive, but no
t mutually recursive. Consider these examples: |
5527 } | 5528 } |
5528 | 5529 |
5529 \begin{dartCode} | 5530 \begin{dartCode} |
5530 f(x) =$>$ x++; // a top level function | 5531 f(x) => x++; // a top level function |
5531 top() \{ // another top level function | 5532 top() \{ // another top level function |
5532 f(3); // illegal | 5533 f(3); // illegal |
5533 f(x) $=>$ x $>$ 0? x*f(x-1): 1; // recursion is legal | 5534 f(x) => x > 0? x*f(x-1): 1; // recursion is legal |
5534 g1(x) $=>$ h(x, 1); // error: h is not declared yet | 5535 g1(x) => h(x, 1); // error: h is not declared yet |
5535 h(x, n) $=>$ x $>$ 1? h(x-1, n*x): n; // again, recursion is fine | 5536 h(x, n) => x > 1? h(x-1, n*x): n; // again, recursion is fine |
5536 g2(x) $=>$ h(x, 1); // legal | 5537 g2(x) => h(x, 1); // legal |
5537 | 5538 |
5538 p1(x) $=>$ q(x,x); // illegal | 5539 p1(x) => q(x,x); // illegal |
5539 q1(a, b)$ =>$ a $>$ 0 ? p1(a-1): b; // fine | 5540 q1(a, b)$ =>$ a > 0 ? p1(a-1): b; // fine |
5540 | 5541 |
5541 q2(a, b) $=>$ a $>$ 0 ? p2(a-1): b; // illegal | 5542 q2(a, b) => a > 0 ? p2(a-1): b; // illegal |
5542 p1(x) $=>$ q2(x,x); // fine | 5543 p1(x) => q2(x,x); // fine |
5543 \} | 5544 \} |
5544 \end{dartCode} | 5545 \end{dartCode} |
5545 | 5546 |
5546 \commentary{ | 5547 \commentary{ |
5547 There is no way to write a pair of mutually recursive local functions, because o
ne always has to come before the other is declared. These cases are quite rare,
and can always be managed by defining a pair of variables first, then assigning
them appropriate closures: | 5548 There is no way to write a pair of mutually recursive local functions, because o
ne always has to come before the other is declared. These cases are quite rare,
and can always be managed by defining a pair of variables first, then assigning
them appropriate closures: |
5548 } | 5549 } |
5549 | 5550 |
5550 \begin{dartCode} | 5551 \begin{dartCode} |
5551 top2() \{ // a top level function | 5552 top2() \{ // a top level function |
5552 \VAR{} p, q; | 5553 \VAR{} p, q; |
5553 p = (x) $=>$ q(x,x); | 5554 p = (x) => q(x,x); |
5554 q = (a, b) $=>$ a $>$ 0 ? p(a-1): b; | 5555 q = (a, b) => a > 0 ? p(a-1): b; |
5555 | 5556 |
5556 \} | 5557 \} |
5557 \end{dartCode} | 5558 \end{dartCode} |
5558 | 5559 |
5559 \rationale{ | 5560 \rationale{ |
5560 The rules for local functions differ slightly from those for local variables in
that a function can be accessed within its declaration but a variable can only
be accessed after its declaration. This is because recursive functions are usefu
l whereas recursively defined variables are almost always errors. It therefore
makes sense to harmonize the rules for local functions with those for functions
in general rather than with the rules for local variables. | 5561 The rules for local functions differ slightly from those for local variables in
that a function can be accessed within its declaration but a variable can only
be accessed after its declaration. This is because recursive functions are usefu
l whereas recursively defined variables are almost always errors. It therefore
makes sense to harmonize the rules for local functions with those for functions
in general rather than with the rules for local variables. |
5561 } | 5562 } |
5562 | 5563 |
5563 % elaborate on function identity and equality, runtime type. Likewsie in functio
n expressions (closures) and declarations | 5564 % elaborate on function identity and equality, runtime type. Likewsie in functio
n expressions (closures) and declarations |
5564 | 5565 |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6191 | 6192 |
6192 \commentary{ | 6193 \commentary{ |
6193 In the simplest case, the immediately enclosing function is an ordinary, synchro
nous non-generator, and upon function termination, the current return value is g
iven to the caller. The other possibility is that the function is marked \ASYNC
{}, in which case the current return value is used to complete the future associ
ated with the function invocation. Both these scenarios are specified in section
\ref{functionInvocation}. | 6194 In the simplest case, the immediately enclosing function is an ordinary, synchro
nous non-generator, and upon function termination, the current return value is g
iven to the caller. The other possibility is that the function is marked \ASYNC
{}, in which case the current return value is used to complete the future associ
ated with the function invocation. Both these scenarios are specified in section
\ref{functionInvocation}. |
6194 The enclosing function cannot be marked as generator (i.e, \ASYNC* or \SYNC*), s
ince generators are not allowed to contain a statement of the form \code{\RETURN
{} $e$;} as discussed below. | 6195 The enclosing function cannot be marked as generator (i.e, \ASYNC* or \SYNC*), s
ince generators are not allowed to contain a statement of the form \code{\RETURN
{} $e$;} as discussed below. |
6195 } | 6196 } |
6196 | 6197 |
6197 \LMHash{} | 6198 \LMHash{} |
6198 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct
ion. | 6199 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct
ion. |
6199 | 6200 |
6200 \LMHash{} | 6201 \LMHash{} |
6201 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \
code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to
the declared return type of $f$. Otherwise, it is a static type warning if $T
$ may not be assigned to the declared return type of $f$. | 6202 It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \
code{Future<flatten(T)>} (\ref{functionExpressions}) may not be assigned to the
declared return type of $f$. Otherwise, it is a static type warning if $T$ ma
y not be assigned to the declared return type of $f$. |
6202 | 6203 |
6203 \LMHash{} | 6204 \LMHash{} |
6204 Let $S$ be the runtime type of $o$. In checked mode: | 6205 Let $S$ be the runtime type of $o$. In checked mode: |
6205 \begin{itemize} | 6206 \begin{itemize} |
6206 \item If the body of $f$ is marked \ASYNC{} (\ref{functions}) it is a dynamic t
ype error if $o$ is not \NULL{} (\ref{null}) and \code{Future$<$flatten(S)$>$} i
s not a subtype of the actual return type (\ref{actualTypeOfADeclaration}) of $
f$. | 6207 \item If the body of $f$ is marked \ASYNC{} (\ref{functions}) it is a dynamic t
ype error if $o$ is not \NULL{} (\ref{null}) and \code{Future<flatten(S)>} is no
t a subtype of the actual return type (\ref{actualTypeOfADeclaration}) of $f$. |
6207 \item Otherwise, it is a dynamic type error if $o$ is not \NULL{} and the runtim
e type of $o$ is not a subtype of the actual return type of $f$. | 6208 \item Otherwise, it is a dynamic type error if $o$ is not \NULL{} and the runtim
e type of $o$ is not a subtype of the actual return type of $f$. |
6208 \end{itemize} | 6209 \end{itemize} |
6209 | 6210 |
6210 \LMHash{} | 6211 \LMHash{} |
6211 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$
;} appears in a generative constructor (\ref{generativeConstructors}). | 6212 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$
;} appears in a generative constructor (\ref{generativeConstructors}). |
6212 | 6213 |
6213 \rationale{ | 6214 \rationale{ |
6214 It is quite easy to forget to add the factory prefix for a constructor, accident
ally converting a factory into a generative constructor. The static checker may
detect a type mismatch in some, but not all, of these cases. The rule above help
s catch such errors, which can otherwise be very hard to recognize. There is no
real downside to it, as returning a value from a generative constructor is meani
ngless. | 6215 It is quite easy to forget to add the factory prefix for a constructor, accident
ally converting a factory into a generative constructor. The static checker may
detect a type mismatch in some, but not all, of these cases. The rule above help
s catch such errors, which can otherwise be very hard to recognize. There is no
real downside to it, as returning a value from a generative constructor is meani
ngless. |
6215 } | 6216 } |
6216 | 6217 |
6217 \LMHash{} | 6218 \LMHash{} |
6218 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$
;} appears in a generator function. | 6219 It is a compile-time error if a return statement of the form \code{\RETURN{} $e$
;} appears in a generator function. |
6219 | 6220 |
6220 \rationale{ | 6221 \rationale{ |
6221 In the case of a generator function, the value returned by the function is the i
terable or stream associated with it, and individual elements are added to that
iterable using yield statements, and so returning a value makes no sense. | 6222 In the case of a generator function, the value returned by the function is the i
terable or stream associated with it, and individual elements are added to that
iterable using yield statements, and so returning a value makes no sense. |
6222 } | 6223 } |
6223 | 6224 |
6224 \LMHash{} | 6225 \LMHash{} |
6225 Let $f$ be the function immediately enclosing a return statement of the form \RE
TURN{}; It is a static warning $f$ is neither a generator nor a generative cons
tructor and either: | 6226 Let $f$ be the function immediately enclosing a return statement of the form \RE
TURN{}; It is a static warning $f$ is neither a generator nor a generative cons
tructor and either: |
6226 \begin{itemize} | 6227 \begin{itemize} |
6227 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI
D{} (\ref{typeVoid}) or, | 6228 \item $f$ is synchronous and the return type of $f$ may not be assigned to \VOI
D{} (\ref{typeVoid}) or, |
6228 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co
de{Future$<$Null$>$}. | 6229 \item $f$ is asynchronous and the return type of $f$ may not be assigned to \co
de{Future<Null>}. |
6229 \end{itemize} | 6230 \end{itemize} |
6230 | 6231 |
6231 \commentary{ | 6232 \commentary{ |
6232 Hence, a static warning will not be issued if $f$ has no declared return type, s
ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO
ID{} and to \code{Future$<$Null$>$}. However, any synchronous non-generator func
tion that declares a return type must return an expression explicitly. | 6233 Hence, a static warning will not be issued if $f$ has no declared return type, s
ince the return type would be \DYNAMIC{} and \DYNAMIC{} may be assigned to \VO
ID{} and to \code{Future<Null>}. However, any synchronous non-generator function
that declares a return type must return an expression explicitly. |
6233 } | 6234 } |
6234 \rationale{This helps catch situations where users forget to return a value in a
return statement.} | 6235 \rationale{This helps catch situations where users forget to return a value in a
return statement.} |
6235 | 6236 |
6236 \rationale{ An asynchronous non-generator always returns a future of some sort.
If no expression is given, the future will be completed with \NULL{} and this mo
tivates the requirement above.} \commentary{Leaving the return type of a functio
n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause
no type error. Using \code{Future} or \code{Future$<$Object$>$} is acceptable as
well, but any other type will cause a warning, since \NULL{} has no subtypes.} | 6237 \rationale{ An asynchronous non-generator always returns a future of some sort.
If no expression is given, the future will be completed with \NULL{} and this mo
tivates the requirement above.} \commentary{Leaving the return type of a functio
n marked \ASYNC{} blank will be interpreted as \DYNAMIC{} as always, and cause
no type error. Using \code{Future} or \code{Future<Object>} is acceptable as wel
l, but any other type will cause a warning, since \NULL{} has no subtypes.} |
6237 | 6238 |
6238 \LMHash{} | 6239 \LMHash{} |
6239 A return statement with no expression, \code{\RETURN;} is executed as follows: | 6240 A return statement with no expression, \code{\RETURN;} is executed as follows: |
6240 | 6241 |
6241 \LMHash{} | 6242 \LMHash{} |
6242 If the immediately enclosing function $f$ is a generator, then: | 6243 If the immediately enclosing function $f$ is a generator, then: |
6243 \begin{itemize} | 6244 \begin{itemize} |
6244 \item | 6245 \item |
6245 The current return value is set to \NULL{}. | 6246 The current return value is set to \NULL{}. |
6246 \item | 6247 \item |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6386 The current call to \code{moveNext()} returns \TRUE. | 6387 The current call to \code{moveNext()} returns \TRUE. |
6387 \end{itemize} | 6388 \end{itemize} |
6388 | 6389 |
6389 \LMHash{} | 6390 \LMHash{} |
6390 It is a compile-time error if a yield statement appears in a function that is no
t a generator function. | 6391 It is a compile-time error if a yield statement appears in a function that is no
t a generator function. |
6391 | 6392 |
6392 \LMHash{} | 6393 \LMHash{} |
6393 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct
ion. It is a static type warning if either: | 6394 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct
ion. It is a static type warning if either: |
6394 \begin{itemize} | 6395 \begin{itemize} |
6395 \item | 6396 \item |
6396 the body of $f$ is marked \ASYNC* and the type \code{Stream$<$T$>$} may not be
assigned to the declared return type of $f$. | 6397 the body of $f$ is marked \ASYNC* and the type \code{Stream<T>} may not be assi
gned to the declared return type of $f$. |
6397 \item | 6398 \item |
6398 the body of $f$ is marked \SYNC* and the type \code{Iterable$<$T$>$} may not be
assigned to the declared return type of $f$. | 6399 the body of $f$ is marked \SYNC* and the type \code{Iterable<T>} may not be ass
igned to the declared return type of $f$. |
6399 \end{itemize} | 6400 \end{itemize} |
6400 | 6401 |
6401 | 6402 |
6402 \subsubsection{ Yield-Each} | 6403 \subsubsection{ Yield-Each} |
6403 \LMLabel{yieldEach} | 6404 \LMLabel{yieldEach} |
6404 | 6405 |
6405 \LMHash{} | 6406 \LMHash{} |
6406 The {\em yield-each statement} adds a series of values to the result of a gener
ator function (\ref{functions}). | 6407 The {\em yield-each statement} adds a series of values to the result of a gener
ator function (\ref{functions}). |
6407 | 6408 |
6408 \begin{grammar} | 6409 \begin{grammar} |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6921 | 6922 |
6922 \subsection{Scripts} | 6923 \subsection{Scripts} |
6923 \LMLabel{scripts} | 6924 \LMLabel{scripts} |
6924 | 6925 |
6925 \LMHash{} | 6926 \LMHash{} |
6926 A {\em script} is a library whose exported namespace (\ref{exports}) includes a
top-level member named \code{main}. It is a static warning if the static type
of \code{main} is not assignable to a function type or is a function type with m
ore than two required parameters. | 6927 A {\em script} is a library whose exported namespace (\ref{exports}) includes a
top-level member named \code{main}. It is a static warning if the static type
of \code{main} is not assignable to a function type or is a function type with m
ore than two required parameters. |
6927 | 6928 |
6928 A script $S$ may be executed as follows: | 6929 A script $S$ may be executed as follows: |
6929 | 6930 |
6930 \LMHash{} | 6931 \LMHash{} |
6931 First, $S$ is compiled as a library as specified above. Then, the top-level func
tion \code{main} that is in the exported namespace of $S$ is invoked. If \code{m
ain} has no positional parameters, it is invoked with no arguments. Otherwise if
\code{main} has exactly one positional parameter, it is invoked with a single a
ctual argument whose runtime type implements \code{List$<$String$>$}. Otherwise
\code{main} is invoked with the following two actual arguments: | 6932 First, $S$ is compiled as a library as specified above. Then, the top-level func
tion \code{main} that is in the exported namespace of $S$ is invoked. If \code{m
ain} has no positional parameters, it is invoked with no arguments. Otherwise if
\code{main} has exactly one positional parameter, it is invoked with a single a
ctual argument whose runtime type implements \code{List<String>}. Otherwise \co
de{main} is invoked with the following two actual arguments: |
6932 \begin{enumerate} | 6933 \begin{enumerate} |
6933 \item An object whose runtime type implements \code{List$<$String$>$}. | 6934 \item An object whose runtime type implements \code{List<String>}. |
6934 \item The initial message of the current isolate $i$ as determined by the invoca
tion of \code{Isolate.spawnUri} that spawned $i$. | 6935 \item The initial message of the current isolate $i$ as determined by the invoca
tion of \code{Isolate.spawnUri} that spawned $i$. |
6935 \end{enumerate} | 6936 \end{enumerate} |
6936 | 6937 |
6937 \LMHash{} | 6938 \LMHash{} |
6938 It is a run time error if $S$ does not declare or export either: | 6939 It is a run time error if $S$ does not declare or export either: |
6939 \begin{itemize} | 6940 \begin{itemize} |
6940 \item A top-level function named \code{main}, or | 6941 \item A top-level function named \code{main}, or |
6941 \item A top-level getter named \code{main} that returns a function. | 6942 \item A top-level getter named \code{main} that returns a function. |
6942 \end{itemize} | 6943 \end{itemize} |
6943 | 6944 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7097 %It is a dynamic type error if a malformed type is used in a subtype test. | 7098 %It is a dynamic type error if a malformed type is used in a subtype test. |
7098 In checked mode, it is a dynamic type error if a deferred, malformed or malbound
ed (\ref{parameterizedTypes}) | 7099 In checked mode, it is a dynamic type error if a deferred, malformed or malbound
ed (\ref{parameterizedTypes}) |
7099 type is used in a subtype test. | 7100 type is used in a subtype test. |
7100 | 7101 |
7101 %In production mode, an undeclared type is treated as an instance of type \DYNAM
IC{}. | 7102 %In production mode, an undeclared type is treated as an instance of type \DYNAM
IC{}. |
7102 | 7103 |
7103 \commentary{Consider the following program} | 7104 \commentary{Consider the following program} |
7104 | 7105 |
7105 \begin{dartCode} | 7106 \begin{dartCode} |
7106 \TYPEDEF{} F(bool x); | 7107 \TYPEDEF{} F(bool x); |
7107 f(foo x) $=>$ x; | 7108 f(foo x) => x; |
7108 main() \{ | 7109 main() \{ |
7109 if (f is F) \{ | 7110 if (f is F) \{ |
7110 print("yoyoma"); | 7111 print("yoyoma"); |
7111 \} | 7112 \} |
7112 \} | 7113 \} |
7113 \end{dartCode} | 7114 \end{dartCode} |
7114 | 7115 |
7115 \commentary{ | 7116 \commentary{ |
7116 The type of the formal parameter of $f$ is $foo$, which is undeclared in the lex
ical scope. This will lead to a static type warning. At runtime the program will
print \cd{yoyoma}, because $foo$ is treated as \DYNAMIC{}. | 7117 The type of the formal parameter of $f$ is $foo$, which is undeclared in the lex
ical scope. This will lead to a static type warning. At runtime the program will
print \cd{yoyoma}, because $foo$ is treated as \DYNAMIC{}. |
7117 %fail when executing the type test on the first line of $main()$ because it lead
s to a subtype comparison involving a malformed type ($foo$). | 7118 %fail when executing the type test on the first line of $main()$ because it lead
s to a subtype comparison involving a malformed type ($foo$). |
(...skipping 11 matching lines...) Expand all Loading... |
7129 \commentary{ | 7130 \commentary{ |
7130 Since $i$ is not a type, a static warning will be issue at the declaration of $j
$. However, the program can be executed without incident in production mode beca
use he undeclared type $i$ is treated as \DYNAMIC{}. However, in checked mode, t
he implicit subtype test at the assignment will trigger an error at runtime. | 7131 Since $i$ is not a type, a static warning will be issue at the declaration of $j
$. However, the program can be executed without incident in production mode beca
use he undeclared type $i$ is treated as \DYNAMIC{}. However, in checked mode, t
he implicit subtype test at the assignment will trigger an error at runtime. |
7131 } | 7132 } |
7132 | 7133 |
7133 | 7134 |
7134 \commentary{ | 7135 \commentary{ |
7135 Here is an example involving malbounded types: | 7136 Here is an example involving malbounded types: |
7136 } | 7137 } |
7137 | 7138 |
7138 \begin{dartCode} | 7139 \begin{dartCode} |
7139 \CLASS{} I$<$T \EXTENDS{} num$>$ \{\} | 7140 \CLASS{} I<T \EXTENDS{} num> \{\} |
7140 \CLASS{} J \{\} | 7141 \CLASS{} J \{\} |
7141 | 7142 |
7142 \CLASS{} A$<$T$>$ \IMPLEMENTS{} J, I$<$T$>$ // type warning: T is not a subtype
of num | 7143 \CLASS{} A<T> \IMPLEMENTS{} J, I<T> // type warning: T is not a subtype of num |
7143 \{ ... | 7144 \{ ... |
7144 \} | 7145 \} |
7145 \end{dartCode} | 7146 \end{dartCode} |
7146 | 7147 |
7147 \commentary{Given the declarations above, the following} | 7148 \commentary{Given the declarations above, the following} |
7148 | 7149 |
7149 \begin{dartCode} | 7150 \begin{dartCode} |
7150 I x = \NEW{} A$<$String$>$(); | 7151 I x = \NEW{} A<String>(); |
7151 \end{dartCode} | 7152 \end{dartCode} |
7152 | 7153 |
7153 \commentary{ | 7154 \commentary{ |
7154 will cause a dynamic type error in checked mode, because the assignment requires
a subtype test A$<$String$>$ $<$: I. To show that this holds, we need to show t
hat A$<$String$>$ $<<$ I$<$String$>$, but I$<$String$>$ is a malbounded type, c
ausing the dynamic error. No error is thrown in production mode. Note that | 7155 will cause a dynamic type error in checked mode, because the assignment requires
a subtype test A<String> <: I. To show that this holds, we need to show that A<
String> $<<$ I<String>, but I<String> is a malbounded type, causing the dynamic
error. No error is thrown in production mode. Note that |
7155 } | 7156 } |
7156 | 7157 |
7157 \begin{dartCode} | 7158 \begin{dartCode} |
7158 J x = \NEW{} A$<$String$>$(); | 7159 J x = \NEW{} A<String>(); |
7159 \end{dartCode} | 7160 \end{dartCode} |
7160 | 7161 |
7161 \commentary{ | 7162 \commentary{ |
7162 does not cause a dynamic error, as there is no need to test against \code{I$<$St
ring$>$} in this case. | 7163 does not cause a dynamic error, as there is no need to test against \code{I<Stri
ng>} in this case. |
7163 Similarly, in production mode | 7164 Similarly, in production mode |
7164 } | 7165 } |
7165 | 7166 |
7166 \begin{dartCode} | 7167 \begin{dartCode} |
7167 A x = \NEW{} A$<$String$>$(); | 7168 A x = \NEW{} A<String>(); |
7168 bool b = x is I; | 7169 bool b = x is I; |
7169 \end{dartCode} | 7170 \end{dartCode} |
7170 | 7171 |
7171 \commentary{ | 7172 \commentary{ |
7172 \code{b} is bound to \TRUE, but in checked mode the second line causes a dynamic
type error. | 7173 \code{b} is bound to \TRUE, but in checked mode the second line causes a dynamic
type error. |
7173 } | 7174 } |
7174 | 7175 |
7175 | 7176 |
7176 | 7177 |
7177 \subsection{Type Declarations} | 7178 \subsection{Type Declarations} |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7682 Additive & +, - & Left & 13\\ | 7683 Additive & +, - & Left & 13\\ |
7683 \hline | 7684 \hline |
7684 Shift & $<<$, $>>$& Left & 12\\ | 7685 Shift & $<<$, $>>$& Left & 12\\ |
7685 \hline | 7686 \hline |
7686 Bitwise AND & \& & Left & 11\\ | 7687 Bitwise AND & \& & Left & 11\\ |
7687 \hline | 7688 \hline |
7688 Bitwise XOR & \^{} & Left & 10\\ | 7689 Bitwise XOR & \^{} & Left & 10\\ |
7689 \hline | 7690 \hline |
7690 Bitwise Or & $|$ & Left & 9\\ | 7691 Bitwise Or & $|$ & Left & 9\\ |
7691 \hline | 7692 \hline |
7692 Relational & $<$, $>$, $<=$, $>=$, \AS{}, \IS{}, \IS{}! & None & 8\\ | 7693 Relational & <, >, $<=$, $>=$, \AS{}, \IS{}, \IS{}! & None & 8\\ |
7693 \hline | 7694 \hline |
7694 Equality & ==, != & None & 7\\ | 7695 Equality & ==, != & None & 7\\ |
7695 \hline | 7696 \hline |
7696 Logical AND & \&\& & Left & 6\\ | 7697 Logical AND & \&\& & Left & 6\\ |
7697 \hline | 7698 \hline |
7698 Logical Or & $||$ & Left & 5\\ | 7699 Logical Or & $||$ & Left & 5\\ |
7699 \hline | 7700 \hline |
7700 If-null & ?? & Left & 4\\ | 7701 If-null & ?? & Left & 4\\ |
7701 \hline | 7702 \hline |
7702 Conditional & e1? e2: e3 & Right & 3\\ | 7703 Conditional & e1? e2: e3 & Right & 3\\ |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7874 | 7875 |
7875 The invariant that each normative paragraph is associated with a line | 7876 The invariant that each normative paragraph is associated with a line |
7876 containing the text \LMHash{} should be maintained. Extra occurrences | 7877 containing the text \LMHash{} should be maintained. Extra occurrences |
7877 of \LMHash{} can be added if needed, e.g., in order to make | 7878 of \LMHash{} can be added if needed, e.g., in order to make |
7878 individual \item{}s in itemized lists addressable. Each \LM.. command | 7879 individual \item{}s in itemized lists addressable. Each \LM.. command |
7879 must occur on a separate line. \LMHash{} must occur immediately | 7880 must occur on a separate line. \LMHash{} must occur immediately |
7880 before the associated paragraph, and \LMLabel must occur immediately | 7881 before the associated paragraph, and \LMLabel must occur immediately |
7881 after the associated \section{}, \subsection{} etc. | 7882 after the associated \section{}, \subsection{} etc. |
7882 | 7883 |
7883 ---------------------------------------------------------------------- | 7884 ---------------------------------------------------------------------- |
OLD | NEW |