Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Bikeshedding: syntax of async iteration statement #11

Closed
zenparsing opened this issue Jul 22, 2015 · 20 comments
Closed

Bikeshedding: syntax of async iteration statement #11

zenparsing opened this issue Jul 22, 2015 · 20 comments

Comments

@zenparsing
Copy link
Member

The currently proposed syntax is:

for async (let x of y) {
    // stuff
}

I originally chose that because it sounds nice in a natural language kind of way.

Would it be better to have the async in front, for consistency with async functions?

async for (let x of y) {
    // stuff
}

Thinking ahead to a possible do-async, which would make more sense?

do async {
    // stuff
}

Or

async do {
    // stuff
}

@domenic @bterlson Any opinions here?

@RangerMauve
Copy link

Personally I agree that putting async first and staying consistent with async functions would be better.

@zenparsing
Copy link
Member Author

There's just something weird to me about async for. It doesn't feel right for some reason.

Another option would be:

async function af() {
    for (await let x of y) {
        // Stuff
    }
}

Or

async function af() {
    for await (let x of y) {
        // Stuff
    }
}

@RangerMauve
Copy link

The await keyword makes it seem like the for loop is going to return a promise that's being awaited, which might be a bit confusing.
Having the await inside the brackets definitely seems bit weird since there's already a lot of stuff going in there.
I think the for await () syntax is pretty nice, though.

@zenparsing
Copy link
Member Author

I think I'm going to go with for await () {} for now.

Rationale:

  • The async contextual keyword is not appropriate because async should indicate the introduction of a context in which await may appear.
  • The semantics are that we are awaiting the iteration results, so await makes sense.
  • await for makes it appear that we are awaiting the result of a regular for-of loop.

Thanks @RangerMauve : )

@RangerMauve
Copy link

@zenparsing Awesome, can't wait for this to take off! :D

@benjamn
Copy link
Member

benjamn commented Jul 24, 2015

Just for completeness, what about something like

for (await x of y) {
  // Stuff
}

under the assumption that x is bound as if with let? Is it really that important to support var or undeclared x variables (or const)?

@RangerMauve
Copy link

I think that it'd be better to have only the minimal amount of differences from a regular for of loop.

@benjamingr
Copy link

@benjamn that might give the impression that x is global, maybe

for (await let x of y) {
  // Stuff
}

@benjamingr
Copy link

@zenparsing for the record, Python 3.5 recently introduced async iterators and they went with async for, IIRC that's because it reads like "async for loop" so it's obvious to the reader and reads like English.

@zenparsing
Copy link
Member Author

@benjamingr Thanks for the link.

In Dart it's "await for": https://www.dartlang.org/articles/beyond-async/

@benjamingr
Copy link

@benjamn
Copy link
Member

benjamn commented Jul 25, 2015

Am I right to imagine this loop (or any of the syntaxes that have been proposed)

for await (let x of y) {
  // Stuff
}

would desugar to something like

let iter$0 = y[Symbol.asyncIterator](), record$0;
while (!(record$0 = await iter$0.next()).done) {
  let x = record$0.value;
  // Stuff
}

or am I missing some subtleties?

@benjamn
Copy link
Member

benjamn commented Jul 25, 2015

If I'm right about that desugaring, then the most important thing about this new loop syntax seems to be that it invokes y[Symbol.asyncIterator]() instead of y[Symbol.iterator](), which inclines me to think we should use the async keyword, as in for async (...), so that the await keyword can continue to have one easily understandable interpretation. If this loop were just a for-of loop that awaits each result, then await would be a more appropriate syntax marker, but it's more than that.

@sebmck
Copy link

sebmck commented Jul 25, 2015

async for feels weird since it seems like you should be able to use it in as an expression like async function.

@benjamn
Copy link
Member

benjamn commented Jul 25, 2015

Yeah, that's true. I can also appreciate the argument that for await ( is only legal inside async functions, in roughly the same spirit that await expressions are only legal inside async functions.

I guess I'm sold on for await (. Thanks for letting me help paint the bikeshed!

@groundwater
Copy link

I like for await because so far await must be run within an async function. This simplifies explaining to people

  • "await can only be used inside an async function"
  • vs. "async for and await can only be used inside an async function"

@RangerMauve
Copy link

From the recent discussion I also support for await :D

@eggers
Copy link

eggers commented Dec 2, 2015

I personally like:

await for (const x of asyncIterator) {
  // do stuff...
}

because in the case that asyncIterator has nothing to return you are still awaiting to find out that there is nothing to return. So, you are actually awaiting the for ... of loop.

@zenparsing
Copy link
Member Author

@eggers That's true, but I don't really feel comfortable having to use lookahead to determine whether the "await" is a part of the "for", rather than the unary operator.

@zenparsing
Copy link
Member Author

Closing this one for now, although I'm sure the bikeshedding will come up again : )

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants