# Await Syntax Discussion Summary

**URL:** <https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914>\
**Category:** language design\
**Created:** [April 29, 2019, 9:55pm UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914 "2019-04-29T21:55:54Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![H2CO3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/h2co3/32/2849_2.png) [@H2CO3](https://internals.rust-lang.org/u/H2CO3)\
**Post date:** [April 30, 2019, 8:30am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/43 "2019-04-30T08:30:10Z")

</div>

Actually, making it an attribute proc-macro sitting in `std` could be even better because it wouldn’t force the particular syntax on those who don’t want to use it, but it would still make it possible for proponents to take advantage of it.

---

<div class="post-metadata">

**Author:** ![K900](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/k900/32/5481_2.png) [@K900](https://internals.rust-lang.org/u/K900)\
**Post date:** [April 30, 2019, 8:39am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/44 "2019-04-30T08:39:09Z")

</div>

Another opinionated Redditor here, reposting my Reddit comment:

I actually really like `.await!()` - it’s distinct from everything else, and opens up a design space for postfix macros ( `.try!()` ? `.trace!()` ? Yes please!). What really worries me is the 1.37 deadline - postfix macros seem like a big, potentially scary feature in their own right, and with a deadline this tight, I’m worried it’ll get discounted based on the amount of work required.

---

<div class="post-metadata">

**Author:** ![NeoLegends](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/neolegends/32/1805_2.png) [@NeoLegends](https://internals.rust-lang.org/u/NeoLegends)\
**Post date:** [April 30, 2019, 9:10am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/45 "2019-04-30T09:10:25Z")

</div>

I would also like to voice my support for stabilizing the current form of the `await!()` macro before settling on an actual sugared syntax.

It seems like there is a substantial amount of people that disagree with the choice of "options to discard" the lang team has made (specifically postfix sigil seems to get quite some love). This leads me to believe that the whole syntax-case feels rushed and that we might settle for something sub-optimal here.

> The writeup mentions that there is agreement on not taking this path, but I don’t see elaboration on why.

I, too, would like to see why this choice was made. I'd rather stabilize async/await as a language feature and then settle for a final syntax than the other way around. If you think about it, that's also exactly what happened with Rusts error handling story. The fundamental traits and structs have been there for a long time before the `?` operator was introduced.

---

<div class="post-metadata">

**Author:** ![bzar0](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bzar0/32/5482_2.png) [@bzar0](https://internals.rust-lang.org/u/bzar0)\
**Post date:** [April 30, 2019, 9:39am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/46 "2019-04-30T09:39:24Z")

</div>

Can’t read the document at work, but was a general postfix function call operator suggested? A simple sugar for transforming `foo.bar().baz?|>await!` or something into `await!(foo.bar().baz?)`? It could be a generally usable operator to be used with single-parameter functions and macros.

---

<div class="post-metadata">

**Author:** ![dan\_t](https://avatars.discourse-cdn.com/v4/letter/d/eada6e/32.png) [@dan\_t](https://internals.rust-lang.org/u/dan_t)\
**Post date:** [April 30, 2019, 9:41am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/47 "2019-04-30T09:41:02Z")

</div>

How much which argument of the prefix/postfix await syntax weights, also seems to depend quite a bit how await will be used in the field.

I have the feeling that await has to be used a bit more in the field to get a really good idea how to weight the arguments.

Therefore I somehow like the idea of just stabilizing the await! macro for now, and after a bit more experience has been gained, to look again at the await syntax.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [April 30, 2019, 9:48am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/48 "2019-04-30T09:48:47Z")

</div>

I didn’t partake in the write-up. Some of my views are congruent with it, some are not, and some things I feel need elaboration. So here are my own views in relation to said write-up.

> <https://gist.github.com/Centril/2a8888444c8952fb1ba9617a4031a472>

---

<div class="post-metadata">

**Author:** ![elahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elahn/32/1652_2.png) [@elahn](https://internals.rust-lang.org/u/elahn)\
**Post date:** [April 30, 2019, 10:26am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/50 "2019-04-30T10:26:09Z")

</div>

I'm not convinced postfix `.keyword` is problematic. The `.` operator means "do this on the type returned by the previous expression." Syntax highlighting makes it visually distinct, notifying users "this is not a field."

I'm happy with `.await`, but I suspect consensus on that to be contentious at best.

> [@nicoburns](#):
>
> I still favour postfix macro syntax `.await!()` , as I believe that this could lead to a very clear and consistent syntax if this is later developed into a more general feature (and it also works well if a general postfix macro feature is not developed). And macro syntax already conveys the idea that “this does something non-trivial”. However, `@await` , `.await!` , `!await` , etc would all be acceptable to me.

Yes. Several people have mentioned `.await!` which is my favourite, along with the "postfix macro" explanation and forward-compatibility. Ideally, empty parens would be optional for all function-like macros, e.g. `unreachable!` And so `.await!` would look like, behave like and could be explained as a built-in postfix macro, regardless of whether they're added as a general feature.

Hypothetically, a postfix macro would take "the previous expression" as input, transform it and can modify the control flow, which matches the behaviour of `.await!`

> [@Centril](#):
>
> I disagree with the rationale that calling the feature "async/await" implies the syntax must have the keyword `await` in it. Async/await is in my view primarily about semantics, ease of use, and looking more like synchronous code. The main reason I see against some postfix sigil is that it is harder to spot. However, we did find that `?` was acceptable to read (and `await` is in my view less side-effecting control flow than `?` is). In my view the hard-to-spot issue isn't make or break for `foo#?` .

I agree with [Centril's views](https://gist.github.com/Centril/2a8888444c8952fb1ba9617a4031a472), especially about composability and chaining. I'm also happy with postfix sigils, e.g. `foo()#?` or `foo()@?`.

> [@K900](#):
>
> What really worries me is the 1.37 deadline - postfix macros seem like a big, potentially scary feature in their own right, and with a deadline this tight, I’m worried it’ll get discounted based on the amount of work required.

We can be forward-compatible with postfix macros without deciding whether they'll be added to the language. This is not a blocker.

---

<div class="post-metadata">

**Author:** ![newpavlov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/newpavlov/32/3290_2.png) [@newpavlov](https://internals.rust-lang.org/u/newpavlov)\
**Post date:** [April 30, 2019, 10:31am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/51 "2019-04-30T10:31:03Z")

</div>

> [@elahn](#):
>
> Syntax highlighting makes it visually distinct, notifying users “this is not a field.”

I don't think we should rely on syntax highlighting while designing language features.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [April 30, 2019, 10:32am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/52 "2019-04-30T10:32:29Z")

</div>

Note that `.await!()` cannot be implemented as a macro in the literal sense (details, see [https://github.com/rust-lang/rust/issues/51751](https://github.com/rust-lang/rust/issues/51751) and [https://github.com/rust-lang/rust/issues/51719](https://github.com/rust-lang/rust/issues/51719)) . It would need to be special cased in the parser and to keep `await` as a keyword it cannot even interact with name resolution.

---

<div class="post-metadata">

**Author:** ![dan\_t](https://avatars.discourse-cdn.com/v4/letter/d/eada6e/32.png) [@dan\_t](https://internals.rust-lang.org/u/dan_t)\
**Post date:** [April 30, 2019, 10:34am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/53 "2019-04-30T10:34:26Z")

</div>

> However, you are not forced to chain just because you can. In my view, being forced to introduce names for temporaries that are not semantically important is not helpful. It makes users introduce bad names. Naming is a hard task in general and users should not be forced to do if it it isn't necessary. I think forcing temporary `let` bindings also makes users keep more things in their head (because there are more bindings in scope that can be used). Moreover temporaries encourage longer functions, due to the increased number of bindings. I generally believe that we should try to facilitate short functions and discourage longer ones.

Temporaries can increase the readability of code, even if there's no need for them, by highlighting one step in the computation. The longer a chain the more context you have to keep.

Also there's no simple correlation between the length of a function and its readability.

---

<div class="post-metadata">

**Author:** ![vlthr](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vlthr/32/6972_2.png) [@vlthr](https://internals.rust-lang.org/u/vlthr)\
**Post date:** [April 30, 2019, 10:38am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/54 "2019-04-30T10:38:18Z")

</div>

Thanks to the language team for this great write-up. The rust community is lucky to have you.

I came in with the assumption that a prefix syntax (i.e. the _Order of Operations Solution_) was the way to go, based mostly on familiarity with other async-friendly languages. After reading, I’m now leaning more towards one of the postfix syntaxes, for the following reasons:

- Orthogonality.
- The strongest case for the _Order of Operations Solution_ as I see it is that it is familiar to many programmers already. But I would argue this familiarity transfers well to any other syntax that uses the “await” name (as opposed to a sigil syntax).
- I found the “Weirdness Budget” argument persuasive, and think it should be a main factor in the consideration. However, I worry that optimizing for the lowest weirdness cost today may end up causing more weirdness in the future. Because postfix syntax seems to compose more orthogonally with other language features, it seems less likely to conflict with future changes to the language.

Among the suggested postfix syntaxes, the `.await!()` postfix macro style stands out to me as the most interesting, assuming the concept of a postfix macro could be made more general.

- Because a postfix `.await()` method call syntax does not behave like a normal method, it may be confusing to users. A postfix macro call communicates the behavior more clearly.
- If `.await!()` could be implemented as a standard postfix macro without special keywords or behavior, that seems like a win to me. Maybe that even opens up the possibility for library authors to build upon it in the future.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [April 30, 2019, 10:44am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/55 "2019-04-30T10:44:21Z")

</div>

> [@dan\_t](#):
>
> Temporaries can increase the readability of code, even if there’s no need for them, by highlighting one step in the computation.

I generally disagree. A temporary, unless quickly shadowed, adds to the overall state of the scope and all descendant scopes. In particular, if you add a temporary to the top scope you add the most state. This becomes even worse when the whole function does not fit in the screen when reviewing.

> [@dan\_t](#):
>
> The longer a chain the more context you have to keep.

That's true. However, on average, chains are simply not that long to amount to a notable amount of context. A chain also builds upon the thing it is chained on, thus reducing the speed of context build-up. Partially because of this, iterator chains are in my view a good example of conveying a lot of information quickly in a way that can be understood quickly as compared to a version with a lot of temporaries.

> [@dan\_t](#):
>
> Also there’s no simple correlation between the length of a function and its readability.

Simple? No. I do definitely feel that long and especially _deep_ functions are harder to review and understand. Splitting up functions also lends itself to breaking things up into logical units such that you don't have to fully understand the implementation details of the called function.

---

<div class="post-metadata">

**Author:** ![K900](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/k900/32/5481_2.png) [@K900](https://internals.rust-lang.org/u/K900)\
**Post date:** [April 30, 2019, 10:59am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/56 "2019-04-30T10:59:40Z")

</div>

> [@elahn](#):
>
> I’m not convinced postfix `.keyword` is problematic. The `.` operator means “do this on the type returned by the previous expression.” Syntax highlighting makes it visually distinct, notifying users “this is not a field.”

I feel like the `.` operator means "access this property of the type". This is not _exactly_ the case in Rust, but it's close enough to generally not matter. `.await` then becomes _really_ special, and not in a good way - it looks like it could be attribute access, but the attribute name itself is "magic".

> [@elahn](#):
>
> We can be forward-compatible with postfix macros without deciding whether they’ll be added to the language. This is not a blocker.

It's not just specification/stabilization work that worries me here, it's also the actual implementation of it in the compiler - AFAICT there's basically no support for anything like this in the compiler anywhere, so it'll have to be built from scratch.

---

<div class="post-metadata">

**Author:** ![vonZuben](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vonzuben/32/12034_2.png) [@vonZuben](https://internals.rust-lang.org/u/vonZuben)\
**Post date:** [April 30, 2019, 11:04am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/57 "2019-04-30T11:04:28Z")

</div>

Has there been a proposal for an Await trait?

I have googled around and can’t find any indication if there has been any consideration for await as a new trait in the standard library. If there was a new Await trait with an await method, then we get postfix notation without any weirdness because it doesn’t have to be a keyword anymore.

Also, I think that an Await trait could have a trivial impl for anything implementing the Future trait.

---

<div class="post-metadata">

**Author:** ![magnet](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/magnet/32/4742_2.png) [@magnet](https://internals.rust-lang.org/u/magnet)\
**Post date:** [April 30, 2019, 11:05am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/58 "2019-04-30T11:05:27Z")

</div>

Nice document and nice discussion. Thinking of Niko’s “third way” recent blog post, here are some random thoughts.

Postfix macros would be cool in general, but I believe await should be a first class feature that does not rely on macros (to provide good error messages).

In general if we had postfix macros, prefixed by (e.g) `@` instead of postfixed by `!`, we could have `foo@ok` (similar to a reverted `?` that early returns `Ok`) and `foo@await` (extra parameters optional). That would open new possibilities in the design space for cool, 3rd party language extensions that play well.

Back to await. I’ve used the await! macro for 6 months now and mandatory delimiters work fine, however the postfix syntax seems just as usable and would indeed help remove a bunch of parentheses.

I would really prefer if the `.` sigil was not used though. Java uses `.class` as a special field that returns the class and I found that feature very confusing the first time I encountered it, even though it was not altering control flow. My experience in other languages with synthetic fields is that they never stop feeling weird.

Long story short, I think the solution chosen should:

- favor orthogonality (no baked in interaction with other features)
- not look like a field access or a method call
- be first-class / not include extra disambiguation sigils such as `!` in macros.

If postfix macros are to be a thing one day, `@await` could be first hardcoded and then retrofitted as a postfix macro with custom error messages.

About single-sigil postfix await, I think they make sense. I hear the argument about the strangeness budget and a big reason I never wanted to really learn Perl is that the code looked like a monkey had repeatedly hit the keyboard.

At the same time, if Rust is to become a strong contender in async programming (and it’s bound to be) it really makes sense for it to have a dedicated sigil / shorthand to make the code as close as possible to blocking code. No one ever accused Erlang to use `!` for message sending (or that was long ago).

---

<div class="post-metadata">

**Author:** ![K900](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/k900/32/5481_2.png) [@K900](https://internals.rust-lang.org/u/K900)\
**Post date:** [April 30, 2019, 11:05am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/59 "2019-04-30T11:05:36Z")

</div>

I think the issue here is that `await` in pretty much any form requires fancy codegen to work (because it also becomes a yield point, etc), so making it a trait method won’t work.

---

<div class="post-metadata">

**Author:** ![vonZuben](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vonzuben/32/12034_2.png) [@vonZuben](https://internals.rust-lang.org/u/vonZuben)\
**Post date:** [April 30, 2019, 11:13am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/60 "2019-04-30T11:13:52Z")

</div>

What if the trait method await was just a wrapper around whatever other thing is necessary for codegen (such as the existing macro)

---

<div class="post-metadata">

**Author:** ![K900](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/k900/32/5481_2.png) [@K900](https://internals.rust-lang.org/u/K900)\
**Post date:** [April 30, 2019, 11:14am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/61 "2019-04-30T11:14:20Z")

</div>

I’m very much not into this, FWIW. It’s spooky action at _a lot_ of distance.

---

<div class="post-metadata">

**Author:** ![elahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elahn/32/1652_2.png) [@elahn](https://internals.rust-lang.org/u/elahn)\
**Post date:** [April 30, 2019, 11:17am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/62 "2019-04-30T11:17:44Z")

</div>

> [@K900](#):
>
> It’s not just specification/stabilization work that worries me here, it’s also the actual implementation of it in the compiler - AFAICT there’s basically no support for anything like this in the compiler anywhere, so it’ll have to be built from scratch.

Although at the language level it'd look and behave like a postfix macro, it would not be implemented that way. As far as I can tell, `.await!()` or `.await!` would not add significant implementation work over any other await syntax. See Centril's comment:

> [@Centril](#):
>
> Note that `.await!()` cannot be implemented as a macro in the literal sense (details, see [async/await errors should not discuss "yield statements" · Issue #51751 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/51751) and [Prevent await from creating a generator · Issue #51719 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/51719)) . It would need to be special cased in the parser and to keep `await` as a keyword it cannot even interact with name resolution.

---

<div class="post-metadata">

**Author:** ![K900](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/k900/32/5481_2.png) [@K900](https://internals.rust-lang.org/u/K900)\
**Post date:** [April 30, 2019, 11:19am UTC](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/63 "2019-04-30T11:19:21Z")

</div>

> [@elahn](#):
>
> Although at the language level it’d look and behave like a postfix macro, it would not be implemented that way. As far as I can tell, `.await!()` or `.await!` would not add significant implementation work over any other await syntax. See Centril’s comment:

Oh yes, I know, but at least there's framework in the compiler for prefix operators and such, and `.await!()` is a very new kind of syntax.

[Previous page](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914.md?page=2)

[Next page](https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914.md?page=4)
