-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Specify yield*
and await for
in more detail.
#1527
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,7 +104,7 @@ | |
% - Add requirement that the iterator of a for-in statement must have | ||
% type `Iterator`. | ||
% - Clarify which constructors are covered by the section 'Constant | ||
% Constructors' and removed confusing redundancy in definiton of | ||
% Constructors' and removed confusing redundancy in definition of | ||
% potentially constant expressions. | ||
% - Integrate the feature specification of collection literal elements | ||
% (aka UI-as-code). | ||
|
@@ -1717,7 +1717,7 @@ \subsection{Function Declarations} | |
with the built-in identifier \STATIC{}. | ||
|
||
\LMHash{}% | ||
When we say that a function $f_1$ \Index{forwards} to another function $f_2$, | ||
When we say that a function $f_1$ \Index{forwards} to another function $f_2$, | ||
we mean that invoking $f_1$ causes $f_2$ to be executed | ||
with the same arguments and/or receiver as $f_1$, | ||
and returns the result of executing $f_2$ to the caller of $f_1$, | ||
|
@@ -1952,7 +1952,7 @@ \subsubsection{Optional Formals} | |
callers from outside the library where it was defined. | ||
If a method outside the library overrode a method with a private optional name, | ||
it would not be a subtype of the original method. | ||
The static checker would of course flag such situations, | ||
The static checker would of course flag such situations, | ||
but the consequence would be that adding a private named formal would break | ||
clients outside the library in a way they could not easily correct.% | ||
} | ||
|
@@ -3432,7 +3432,7 @@ \subsubsection{Generative Constructors} | |
\commentary{% | ||
This means that formal parameters, including initializing formals, | ||
must have distinct names, and that initializing formals | ||
are in scope for the initializer list, | ||
are in scope for the initializer list, | ||
but they are not in scope for the body of the constructor. | ||
When a formal parameter introduces a local variable into two scopes, | ||
it is still one variable and hence one storage location. | ||
|
@@ -5230,7 +5230,7 @@ \subsection{Mixin Classes} | |
% to be compile-time errors. | ||
|
||
\commentary{% | ||
It is an error, for example, if $M$ contains a member declaration $d$ | ||
It is an error, for example, if $M$ contains a member declaration $d$ | ||
which overrides a member signature $m$ in the interface of $S$, | ||
but which is not a correct override of $m$ | ||
(\ref{correctMemberOverrides}).% | ||
|
@@ -8254,7 +8254,7 @@ \subsection{Constants} | |
% be computed statically without running user code. | ||
|
||
% A validly typed potentially constant expression can still fail when evaluated. | ||
% If that happens in a const invociation, it's a compile-time error. | ||
% If that happens in a const invocation, it's a compile-time error. | ||
|
||
\LMHash{}% | ||
It is a compile-time error if an expression is required to be | ||
|
@@ -13772,7 +13772,7 @@ \subsubsection{Sending Messages} | |
Messages are sent by invoking specific methods in the Dart libraries; there is no specific syntax for sending a message. | ||
|
||
\commentary{% | ||
In other words, the methods supporting sending messages | ||
In other words, the methods supporting sending messages | ||
embody primitives of Dart that are not accessible to ordinary code, | ||
much like the methods that spawn isolates.% | ||
} | ||
|
@@ -16880,13 +16880,13 @@ \subsection{If} | |
|
||
\rationale{% | ||
Under reasonable scope rules such code is problematic. | ||
If we assume that \code{v} is declared | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems my "remove trailing spaces on save" has caught some dangling spaces. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This PR might then need to be rebased: The current version of dartLangSpec.tex (34c4e1a) does not contain any trailing spaces. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trailing spaces are bad, m'kay? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Certainly! I'm saying that there are no trailing spaces in But this means that removing trailing spaces in this PR will not remove any trailing spaces from the result of landing this PR (they're gone already), it will just make the merging operation a bit more complex. I was worried that this kind of "fix something that has been fixed" change could in some situations give rise to a reversal: A line here and there could suddenly be edited back to an earlier version, because it has been changed in this PR, and it contains the old text in this PR (minus that trailing space). So That's the reason why I suggested doing a |
||
in the scope of the method \code{main()}, | ||
then when \code{somePredicate} is false, | ||
If we assume that \code{v} is declared | ||
in the scope of the method \code{main()}, | ||
then when \code{somePredicate} is false, | ||
\code{v} will be uninitialized when accessed. | ||
The cleanest approach would be to require a block following the test, | ||
The cleanest approach would be to require a block following the test, | ||
rather than an arbitrary statement. | ||
However, this goes against long standing custom, | ||
However, this goes against long standing custom, | ||
undermining Dart's goal of familiarity. | ||
Instead, we choose to insert a block, introducing a scope, | ||
around the statement following the predicate | ||
|
@@ -17141,7 +17141,7 @@ \subsubsection{Asynchronous For-in} | |
It is a compile-time error if a traditional for loop (\ref{forLoop}) is prefixed by the \AWAIT{} keyword. | ||
|
||
\rationale{% | ||
An asynchronous loop would make no sense within a synchronous function, | ||
An asynchronous loop would make no sense within a synchronous function, | ||
for the same reasons that an await expression makes no sense | ||
in a synchronous function.% | ||
} | ||
|
@@ -18083,7 +18083,8 @@ \subsection{Yield-Each} | |
if the class of $o$ is not a subtype of \code{Iterable<$T_f$>}. | ||
Otherwise | ||
\item | ||
The method \code{iterator} is invoked upon $o$ returning an object $i$. | ||
The getter \code{iterator} is invoked upon $o$ returning an object $i$. | ||
Otherwise | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the word There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, the phrase Wouldn't it be more like other parts of the specification if we use (We do say it like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I should follow the norm here. |
||
\item | ||
\label{moveNext} The \code{moveNext} method of $i$ is invoked on it | ||
with no arguments. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And |
||
|
@@ -18117,35 +18118,76 @@ \subsection{Yield-Each} | |
It is a dynamic type error if the class of $o$ | ||
is not a subtype of \code{Stream<$T_f$>}. | ||
Otherwise | ||
\item | ||
If the stream associated with $m$ has been cancelled, | ||
then execution of $s$ completes by returning without a value. | ||
\commentary{In this case, the \code{\YIELD*} operation does | ||
not begin to listen to the stream $o$.} | ||
Otherwise | ||
\item | ||
The $o$ stream is listened to by invoking \code{$v_o$.listen} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is. |
||
with system provided arguments, | ||
where $v_o$ is a fresh variable referencing the stream $o$. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ACK. Much better, yes. |
||
Let $u$ be the stream subscription returned by the call to | ||
\code{$p$.listen} and let $v$ be a fresh variable bound to $u$. | ||
\item | ||
If the stream associated with $m$ is paused, then $u$ is immediately | ||
paused as if by invoking \code{$v$.pause} with no arguments. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if it throws? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The default semantic fallback is that if some sub-part of the semantics of a construct throws, so does the construct itself unless otherwise stated. In this case, nothing otherwise is stated, so if Now, should it work like that? Probably yes. It's possible to be obnoxious about the exiting. Say: label: try {
yield whatnot;
} finally {
break label;
} This will swallow any control flow trying to leave the |
||
\item{} | ||
If the stream associated with $m$ has been cancelled, then | ||
$u$ is cancelled by executing \code{await $v$.cancel();}. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it more straightforward to say There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ACK. Evaluating an expression is cleaner. |
||
If this execution does not throw, the execution of $s$ | ||
completes by returning without a value. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds like we could have commentary saying that it is an unexpected anomaly if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, |
||
% This can only happen if a call to "listen" or "pause" above has | ||
% side effects which cancels the stream of $m$. | ||
\item | ||
The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), | ||
if any, is paused. | ||
\item | ||
The $o$ stream is listened to, creating a subscription $s$, | ||
and for each event $x$, or error $e$ with stack trace $t$, of $s$: | ||
Execution of $m$ is suspended. | ||
While $m$ is suspended, the following reactions happen if $u$ delivers | ||
an event or if the stream associated with $m$ is paused, resumed or cancelled. | ||
\commentary{It is unspecified what happens if $u$ delivers events | ||
before $m$ is suspended or after $m$ is resumed, or if $u$ delivers events | ||
after a call to \code{$v$.cancel} or a call to \code{$v$.pause} which has | ||
not been followed by a call to \code{$v$.resume}, or after having delivered | ||
a done event.} | ||
% Such events should be ignored. | ||
\begin{itemize} | ||
\item | ||
If the stream $u$ associated with $m$ has been paused, | ||
then execution of $m$ is suspended until $u$ is resumed or canceled. | ||
If the stream associated with $m$ becomes paused, | ||
then $u$ is paused by executing \code{$v$.pause();}. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly to line 18138, this could be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ACK. |
||
It is unspecified what happens if this execution throws. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be a friendly gesture to the practical developer to mention in commentary that a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. |
||
% The error can be passed to \code{Zone.current.handleUncaughtError}. | ||
\item | ||
If the stream $u$ associated with $m$ has been canceled, | ||
then $s$ is canceled by evaluating \code{\AWAIT{} v.cancel()} | ||
where $v$ is a fresh variable referencing the stream subscription $s$. | ||
Then, if the cancel completed normally, | ||
the stream execution of $s$ returns without an object | ||
(\ref{statementCompletion}). | ||
If the stream associated with $m$ is resumed after being paused, | ||
then $u$ is resumed as by executing \code{$v$.resume();}. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could again be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ACK |
||
It is unspecified what happens if this execution throws. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, commentary could mention that this is an anomaly. Isn't that true, too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Absolutely. If |
||
% The error can be passed to \code{Zone.current.handleUncaughtError}. | ||
\item | ||
If the stream associated with $m$ is cancelled, | ||
then $u$ is also cancelled as by executing \code{await $v$.cancel();}. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And what if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preferably, the code calling Maybe I should go back to the drawing board and be explicit about everything. Calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
How about landing this one in approximately the current form, and then considering an additional revision in a separate PR? |
||
|
||
At some future time, execution of $m$ resumes. If the execution above | ||
completed by throwing an error \metavar{er} and stack trace \metavar{st}, | ||
then execution of $s$ completes by throwing \metavar{er} | ||
and stack trace \metavar{st}. | ||
Otherwise, execution of $s$ completes by returning without a value. | ||
\item | ||
Otherwise, $x$, or $e$ with $t$, are added to | ||
the stream associated with $m$ in the order they appear in $o$. | ||
\commentary{% | ||
Note that a dynamic error occurs if $x$ is added | ||
and the dynamic type of $x$ is not a subtype of | ||
the element type of said stream.% | ||
} | ||
The function $m$ may suspend. | ||
If $u$ emits a data event with value $x$, | ||
then if the runtime type of $x$ is not a subtype of $T_v$, | ||
then the stream associated with $m$ emits a dynamic type error. | ||
Otherwise the stream associated with $m$ immediately emits | ||
a data event with value $x$. | ||
\item | ||
If $u$ emits an error event with error \metavar{er} | ||
and stack trace \metavar{st}, | ||
then the stream associated with $m$ immediately emits an error event | ||
with error \metavar{er} and stack trace \metavar{st}. | ||
\item | ||
If $u$ closes \commentary{(by emitting a done event)}, | ||
then execution of $m$ resumes and execution of $s$ completes normally. | ||
\end{itemize} | ||
\item | ||
If the stream $o$ is done, execution of $s$ completes normally. | ||
\end{itemize} | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well fix
and removed
-->, and remove
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well spotted.