Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: docs/language/dartLangSpec.tex

Issue 1010433002: Assorted fixes to async: yield may suspend in async* methods; yield* skips emptysequences; definiti… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 \newcommand{\code}[1]{{\sf #1}} 8 \newcommand{\code}[1]{{\sf #1}}
9 \title{Dart Programming Language Specification \\ 9 \title{Dart Programming Language Specification \\
10 {\large Version 1.9}} 10 {\large Version 1.9}}
(...skipping 3074 matching lines...) Expand 10 before | Expand all | Expand 10 after
3085 3085
3086 $(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$ 3086 $(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$
3087 is 3087 is
3088 3088
3089 $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow T _0$, where $T_0$ is the static type of $e$. 3089 $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow T _0$, where $T_0$ is the static type of $e$.
3090 3090
3091 \LMHash{} 3091 \LMHash{}
3092 The static type of a function literal of the form 3092 The static type of a function literal of the form
3093 3093
3094 $(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])$ \ASYNC{} $=> e$ 3094 $(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])$ \ASYNC{} $=> e$
3095 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Future<flatten(T_0)>$, where $T_0$ is the static type of $e$ and $flatten(T) = flatten(S)$ if $T = Future<S>$, and $T$ otherwise. 3095 is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarro w Future<flatten(T_0)>$, where $T_0$ is the static type of $e$ and $flatten(T)$ is defined as follows:
3096
3097 If $T = Future<S>$ then $flatten(T) = flatten(S)$.
3098
3099 Otherwise if $T <: Future$ then let $S$ be a type such that $T << Future<S>$ an d for all $R$, if $T << Future<R>$ then $S << R$.
3100
3101 \rationale{
3102 This ensures that $Future<S>$ is the most specific instantiation of \cd{Future} that is a super type of $T$.
3103 }
3104
3105 Then $flatten(T) = S$.
3106
3107 In any other circumstance, $flatten(T) = T$.
3108
3109
3096 3110
3097 \rationale{ 3111 \rationale{
3098 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}. 3112 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}.
3113
3114 The exception to that would be a type $X$ that extended or implemented \code{Fu ture}. In that case, the result type only one unwrapping takes place. As an exam ple of why this is done, consider
Paul Berry 2015/03/18 21:05:53 Nit: it looks like "the result type" was inserted
3115
3116 \cd{\CLASS{} C$<$T$>$ \IMPLEMENTS{} Future$<$C$<$C$<$T$>>>$ \ldots }
3117
3118 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.
3119
3099 } 3120 }
3100 3121
3101 3122
3102 \LMHash{} 3123 \LMHash{}
3103 The static type of a function literal of the form 3124 The static type of a function literal of the form
3104 3125
3105 $(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$ 3126 $(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$
3106 is 3127 is
3107 3128
3108 $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow T_0$, where $T_0$ is the static type of $e$. 3129 $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow T_0$, where $T_0$ is the static type of $e$.
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3521 } 3542 }
3522 3543
3523 \LMHash{} 3544 \LMHash{}
3524 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t. 3545 The iterable implementation must comply with the contract of \code{Iterable} and should not take any steps identified as exceptionally efficient in that contrac t.
3525 3546
3526 \commentary { 3547 \commentary {
3527 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example. 3548 The contract explicitly mentions a number of situations where certain iterables could be more efficient than normal. For example, by precomputing their length. Normal iterables must iterate over their elements to determine their length. Thi s is certainly true in the case of a synchronous generator, where each element i s computed by a function. It would not be acceptable to pre-compute the results of the generator and cache them, for example.
3528 } 3549 }
3529 3550
3530 \LMHash{} 3551 \LMHash{}
3531 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()} on it, execution of the body of $f$ will begin. When $f$ terminates, $j$ is positioned after its last element, so that i ts current value is \NULL{} and the current call to \code{moveNext()} on $j$ ret urns false, as will all further calls. 3552 When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin . When $f$ terminates, $j$ is positioned after its last element, so that its cur rent value is \NULL{} and the current call to \code{moveNext()} on $j$ returns f alse, as will all further calls.
3532 3553
3533 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ. 3554 Each iterator starts a separate computation. If the \SYNC* function is impure, t he sequence of values yielded by each iterator may differ.
3534 3555
3535 \commentary{ 3556 \commentary{
3536 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when 3557 One can derive more than one iterator from a given iterable. Note that operati ons on the iterable itself can create distinct iterators. An example would be \c ode{length}. It is conceivable that different iterators might yield sequences o f different length. The same care needs to be taken when writing \SYNC* function s as when
3537 writing an \code{Iterator} class. In particular, it should handle multiple 3558 writing an \code{Iterator} class. In particular, it should handle multiple
3538 simultaneous iterators gracefully. If the iterator depends on external state 3559 simultaneous iterators gracefully. If the iterator depends on external state
3539 that might change, it should check that the state is still valid after every 3560 that might change, it should check that the state is still valid after every
3540 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't). 3561 yield (and maybe throw a \code{ConcurrentModificationError} if it isn't).
3541 } 3562 }
(...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after
5906 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function. 5927 Next, $o$ is added to the iterable or stream associated with the immediately enc losing function.
5907 5928
5908 \LMHash{} 5929 \LMHash{}
5909 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of t he innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$ . If $h$ is undefined, the immediately enclosing function terminates. 5930 If the enclosing function $m$ is marked \ASYNC* and the stream $u$ associated wi th $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of t he innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$ . If $h$ is undefined, the immediately enclosing function terminates.
5910 5931
5911 \rationale{ 5932 \rationale{
5912 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses. 5933 The stream associated with an asynchronous generator could be canceled by any co de with a reference to that stream at any point where the generator was passivat ed. Such a cancellation constitutes an irretrievable error for the generator. A t this point, the only plausible action for the generator is to clean up after i tself via its \FINALLY{} clauses.
5913 } 5934 }
5914 5935
5915 \LMHash{} 5936 \LMHash{}
5937 Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) the n the enclosing function may suspend.
5938
5939 \rationale {
5940 If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the enclosing str eam to run and access the data in the stream. The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we al low the enclosing function to be suspended when a new value is added to its asso ciated stream. However, it is not essential (and in fact, can be quite costly) t o suspend the function on every \YIELD{}. The implementation is free to decide h ow often to suspend the enclosing function. The only requirement is that consume rs are not blocked indefinitely.
5941 }
5942
5943
5944 \LMHash{}
5916 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then: 5945 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then:
5917 \begin{itemize} 5946 \begin{itemize}
5918 \item 5947 \item
5919 Execution of the function $m$ immediately enclosing $s$ is suspended until the m ethod \code{moveNext()} is invoked upon the iterator used to initiate the curren t invocation of $m$. 5948 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$.
5920 \item 5949 \item
5921 The current call to \code{moveNext()} returns \TRUE. 5950 The current call to \code{moveNext()} returns \TRUE.
5922 \end{itemize} 5951 \end{itemize}
5923 5952
5924 \LMHash{} 5953 \LMHash{}
5925 It is a compile-time error if a yield statement appears in a function that is no t a generator function. 5954 It is a compile-time error if a yield statement appears in a function that is no t a generator function.
5926 5955
5927 \LMHash{} 5956 \LMHash{}
5928 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: 5957 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:
5929 \begin{itemize} 5958 \begin{itemize}
(...skipping 10 matching lines...) Expand all
5940 \LMHash{} 5969 \LMHash{}
5941 The {\em yield-each statement} adds a series of values to the result of a gener ator function (\ref{functions}). 5970 The {\em yield-each statement} adds a series of values to the result of a gener ator function (\ref{functions}).
5942 5971
5943 \begin{grammar} 5972 \begin{grammar}
5944 {\bf yieldEachStatement:} 5973 {\bf yieldEachStatement:}
5945 \YIELD* expression `{\escapegrammar ;}' 5974 \YIELD* expression `{\escapegrammar ;}'
5946 . 5975 .
5947 \end{grammar} 5976 \end{grammar}
5948 5977
5949 \LMHash{} 5978 \LMHash{}
5950 Execution of a statement s of the form \code{\YIELD* $e$;} proceeds as follows: 5979 Execution of a statement $s$ of the form \code{\YIELD* $e$;} proceeds as follow s:
5951 5980
5952 \LMHash{} 5981 \LMHash{}
5953 First, the expression $e$ is evaluated to an object $o$. If the immediately encl osing function $m$ is synchronous, then it is a dynamic error if the class of $o $ does not implement \code{Iterable}. If $m$ asynchronous, then it is a dynamic error if the class of $o$ does not implement \code{Stream}. Next, for each elem ent $x$ of $o$: 5982 First, the expression $e$ is evaluated to an object $o$.
5983
5984 \LMHash{}
5985 If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), th en:
5986 \begin{enumerate}
5987 \item It is a dynamic error if the class of $o$ does not implement \code{Iterabl e}. Otherwise
5988 \item The method \cd{iterator} is invoked upon $o$ returning an object $i$.
5989 \item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Other wise
5990 \item The getter \cd{current} is invoked on $i$. If the invocation raises an exc eption $ex$, execution of $s$ throws $ex$. Otherwise, the result $x$ of the gett er invocation is added to the iterable associated with $m$.
5991 Execution of the function $m$ immediately enclosing $s$ is suspended until the n ullary method \code{moveNext()} is invoked upon the iterator used to initiate th e current invocation of $m$, at which point execution of $s$ continues at \ref{m oveNext}.
5992 \item
5993 The current call to \code{moveNext()} returns \TRUE.
5994 \end{enumerate}
5995
5996 \LMHash{}
5997 If $m$ is marked \ASYNC* (\ref{functions}), then:
5998 \begin{itemize}
5999 \item It is a dynamic error if the class of $o$ does not implement \code{Stream }. Otherwise
6000 \item For each element $x$ of $o$:
5954 \begin{itemize} 6001 \begin{itemize}
5955 \item 6002 \item
5956 If $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m $ has been paused, then execution of $m$ is suspended until $u$ is resumed or c anceled. 6003 If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled.
6004 \item
6005 If the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FI NALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induced by $c$. If $h$ is define d, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates.
5957 \item 6006 \item
5958 $x$ is added to the iterable or stream associated with $m$ in the order it appe ars in $o$. 6007 Otherwise, $x$ is added to the stream associated with $m$ in the order it appea rs in $o$. The function $m$ may suspend.
5959 \item 6008 \end{itemize}
5960 If $m$ is marked \ASYNC* and the stream $u$ associated with $m$ has been cancele d, then let $c$ be the \FINALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined, let $h$ be the handler induce d by $c$. If $h$ is defined, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates. 6009 \item If the stream $o$ is done, execution of $s$ is complete.
5961 \end{itemize} 6010 \end{itemize}
5962 6011
5963 \LMHash{}
5964 If the enclosing function is marked \SYNC* (\ref{functions}) then:
5965 \begin{itemize}
5966 \item
5967 Execution of the function $m$ immediately enclosing $s$ is suspended until the m ethod \code{moveNext()} is invoked upon the iterator used to initiate the curren t invocation of $m$.
5968 \item
5969 The current call to \code{moveNext()} returns \TRUE.
5970 \end{itemize}
5971 6012
5972 \LMHash{} 6013 \LMHash{}
5973 It is a compile-time error if a yield-each statement appears in a function that is not a generator function. 6014 It is a compile-time error if a yield-each statement appears in a function that is not a generator function.
5974 6015
5975 \LMHash{} 6016 \LMHash{}
5976 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}. 6017 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing funct ion. It is a static type warning if $T$ may not be assigned to the declared ret urn type of $f$. If $f$ is synchronous it is a static type warning if $T$ may not be assigned to \code{Iterable}. If $f$ is asynchronous it is a static type warning if $T$ may not be assigned to \code{Stream}.
5977 6018
5978 6019
5979 \subsection{ Assert} 6020 \subsection{ Assert}
5980 \LMLabel{assert} 6021 \LMLabel{assert}
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after
7383 7424
7384 The invariant that each normative paragraph is associated with a line 7425 The invariant that each normative paragraph is associated with a line
7385 containing the text \LMHash{} should be maintained. Extra occurrences 7426 containing the text \LMHash{} should be maintained. Extra occurrences
7386 of \LMHash{} can be added if needed, e.g., in order to make 7427 of \LMHash{} can be added if needed, e.g., in order to make
7387 individual \item{}s in itemized lists addressable. Each \LM.. command 7428 individual \item{}s in itemized lists addressable. Each \LM.. command
7388 must occur on a separate line. \LMHash{} must occur immediately 7429 must occur on a separate line. \LMHash{} must occur immediately
7389 before the associated paragraph, and \LMLabel must occur immediately 7430 before the associated paragraph, and \LMLabel must occur immediately
7390 after the associated \section{}, \subsection{} etc. 7431 after the associated \section{}, \subsection{} etc.
7391 7432
7392 ---------------------------------------------------------------------- 7433 ----------------------------------------------------------------------
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698