Considerations for writing a loop over a Stream as it relates to await syntax.
JavaScript uses this syntax:
for await (elem of stream) {
// ...
}
It makes sense to use await in the syntax (as opposed to async), because its an await point.
All syntaxes we're considering present some problems. Note that this is a part of the loop syntax, not the pattern. A stream is not equivalent to an iterator of futures because the future lifetimes are tied to the borrow in next (though the output of the future currently cannot be).
I think (unsurprisingly) this syntax favors prefix. At very least I think it favors a space based syntax. Its hard for me to imagine a syntax like:
for elem.await in stream
When the .await
is not a part of the pattern construction. Maybe other people differ. (I would find even odder the method and macro like postfix syntaxes, since they are very clearly intended to mimic expressions and this is not an expression at all).
However, even the prefix syntax has some quirks. If we had both await and await?, we'd probably want both to work here as well:
for await? elem in stream
On the face of it, this is fine. However, there is an interesting quirk if we ever allow ?
in patterns, as we've long discussed. That would make this valid:
for await elem? in stream
Unlike expressions, this actually works and does what the user wants (that is, it awaits and then ?s). So in this position for await? elem
and for await elem?
would mean the same thing, whereas in an expression context they don't.
I'm assuming that we consider at least some degree of syntactic consistency between await expressions and stream loops a virtue. There's an argument to be made that if they can't be completely consistent they should be highly inconsistent (which would favor combining a postfix expression syntax with the prefix loop syntax).
Since syntaxes like .await
are abandoning a lot of precedent, we could do something really unorthodox like this and have the .await be applied to the for keyword:
for.await elem in stream
Follow up comment on this point:
Streams are equivalent to a streaming iterator of future, that is, roughly this impl is plausible:
So an alternative option would be to find a way that for loops can be backwards compatibly extended to work on streaming iterators, make await (as well as ?) a part of the pattern syntax, and just treat all streams as streaming iterators of futures.
Doing this I think would have no impact on prefix/postfix, because both could be made to work consistently with the way they work in expressions (by defining the same precedence).