Skip to content

Tracking issue for async/await (RFC 2394) #50547

Closed
@withoutboats

Description

@withoutboats
Contributor

This is the tracking issue for RFC 2394 (rust-lang/rfcs#2394), which adds async and await syntax to the language.

I will be spearheading the implementation work of this RFC, but would appreciate mentorship as I have relatively little experience working in rustc.

TODO:

  • Implement
    Document

Unresolved questions:

Activity

added
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.
T-langRelevant to the language team
C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
on May 8, 2018
rpjohnst

rpjohnst commented on May 8, 2018

@rpjohnst
Contributor

The discussion here seems to have died down, so linking it here as part of the await syntax question: https://internals.rust-lang.org/t/explicit-future-construction-implicit-await/7344

withoutboats

withoutboats commented on May 9, 2018

@withoutboats
ContributorAuthor

Implementation is blocked on #50307.

Pzixel

Pzixel commented on May 10, 2018

@Pzixel

About syntax: I'd really like to have await as simple keyword. For example, let's look on a concern from the blog:

We aren’t exactly certain what syntax we want for the await keyword. If something is a future of a Result - as any IO future likely to be - you want to be able to await it and then apply the ? operator to it. But the order of precedence to enable this might seem surprising - await io_future? would await first and ? second, despite ? being lexically more tightly bound than await.

I agree here, but braces are evil. I think it's easier to remember that ? has lower precedence than await and end with it:

let foo = await future?

It's easier to read, it's easier to refactor. I do believe it's the better approach.

let foo = await!(future)?

Allows to better understand an order in which operations are executed, but imo it's less readable.

I do believe that once you get that await foo? executes await first then you have no problems with it. It's probably lexically more tied, but await is on the left side and ? is on the right one. So it's still logical enough to await first and handle Result after it.


If any disagreement exist, please express them so we can discuss. I don't understanda what's silent downvote stands for. We all wish good to the Rust.

alexreg

alexreg commented on May 10, 2018

@alexreg
Contributor

I have mixed views on await being a keyword, @Pzixel. While it certainly has an aesthetic appeal, and is perhaps more consistent, given async is a keyword, "keyword bloat" in any language is a real concern. That said, does having async without await even make any sense, feature wise? If it does, perhaps we can leave it as is. If not, I'd lean towards making await a keyword.

Nemo157

Nemo157 commented on May 10, 2018

@Nemo157
Member

I think it's easier to remember that ? has lower precedence than await and end with it

It might be possible to learn that and internalise it, but there's a strong intuition that things that are touching are more tightly bound than things that are separated by whitespace, so I think it would always read wrong on first glance in practice.

It also doesn't help in all cases, e.g. a function that returns a Result<impl Future, _>:

let foo = await (foo()?)?;
rpjohnst

rpjohnst commented on May 10, 2018

@rpjohnst
Contributor

The concern here is not simply "can you understand the precedence of a single await+?," but also "what does it look like to chain several awaits." So even if we just picked a precedence, we would still have the problem of await (await (await first()?).second()?).third()?.

A summary of the options for await syntax, some from the RFC and the rest from the RFC thread:

  • Require delimiters of some kind: await { future }? or await(future)? (this is noisy).
  • Simply pick a precedence, so that await future? or (await future)? does what is expected (both of these feel surprising).
  • Combine the two operators into something like await? future (this is unusual).
  • Make await postfix somehow, as in future await? or future.await? (this is unprecedented).
  • Use a new sigil like ? did, as in future@? (this is "line noise").
  • Use no syntax at all, making await implicit (this makes suspension points harder to see). For this to work, the act of constructing a future must also be made explicit. This is the subject of the internals thread I linked above.

That said, does having async without await even make any sense, feature wise?

@alexreg It does. Kotlin works this way, for example. This is the "implicit await" option.

alexreg

alexreg commented on May 10, 2018

@alexreg
Contributor

@rpjohnst Interesting. Well, I'm generally for leaving async and await as explicit features of the language, since I think that's more in the spirit of Rust, but then I'm no expert on asynchronous programming...

Pzixel

Pzixel commented on May 10, 2018

@Pzixel

@alexreg async/await is really nice feature, as I work with it on day-to-day basis in C# (which is my primary language). @rpjohnst classified all possibilities very well. I prefer the second option, I agree on others considerations (noisy/unusual/...). I have been working with async/await code for last 5 years or something, it's really important to have such a flag keywords.

@rpjohnst

So even if we just picked a precedence, we would still have the problem of await (await (await first()?).second()?).third()?.

In my practice you never write two await's in one line. In very rare cases when you need it you simply rewrite it as then and don't use await at all. You can see yourself that it's much harder to read than

let first = await first()?;
let second = await first.second()?;
let third = await second.third()?;

So I think it's ok if language discourages to write code in such manner in order to make the primary case simpler and better.

hero away future await? looks interesting although unfamiliar, but I don't see any logical counterarguments against that.

356 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-coroutinesArea: CoroutinesAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @ry@steveklabnik@ZhangHanDong@qnighy@seanmonstar

      Issue actions

        Tracking issue for async/await (RFC 2394) · Issue #50547 · rust-lang/rust