Postfix Sigil for async-await

I’ve read this paper and the argument against postfix sigil is merely familiarity:

We also have consensus among the lang team that some degree of familiarity with the syntax of this feature in other languages is important. In particular, we note that this feature has come to be identified with the addition of two new language forms: an async operator and an await operator, to the point that the feature itself is referred to simply as "async/await.”

This argument is unfair, since a similar unorthodox/unfamiliar syntax is taken into consideration: .await (seriously, it is so weird that I created an account on this forum to argue against it).

Another argument that I heard against postfix sigil is that Rust team want to avoid introducing new syntax. The thing is avoiding new syntax only makes sense when the feature is not something drastically different, but async transforms an straightforward and intuitive control flow into something very different. It must not be the same syntax.

The paper states that since virtually every language has use async/await in pair, it is unusual to use things other than await. But why must we use async or any keyword for that matter? Leave it be, a function that returns Future should also support postfix sigil, just like a function that returns Result or Option also support ?.

// no needs for async
// return type is enough
fn foo() -> impl Future<...> {
  get_future()@.abc.def@
}

// it is similar to ? syntax
// in which it requires no special keyword
// just return type
fn bar() -> Result<...> {
  get_result()?.abc.def?
}
1 Like

That’s a misunderstanding: async converts the function into a state machine (and also converts the return type into a Future and wires up the waker/executioner). When an async fn is called, this state machine closure is just initialized and the function immediately returns, without yet running it.

By contrast, a fn that just returns a Future, but is not async, would not get transformed this way and immediately execute when called. As such it cannot be suspended, and thus can’t have await points inside. You would need to return an async block (async { ... }) instead.

6 Likes