A final proposal for await syntax

Before bringing yet another argument in an already heated debate, I want to express first how much I appreciate the amazing work done by the Rust language team! I am looking forward to use this elegant way of writing asynchronous code and I am fine with the syntax, whichever wins in the end.

My point below is based on the remarkable similarity of await and try. This observation has already been stated many times, e.g., in https://internals.rust-lang.org/t/await-syntax-discussion-summary/9914/13 and https://internals.rust-lang.org/t/on-why-await-shouldnt-be-a-method/10010/38. To summarize:

  • Both Result (Option) and Future are essentially monads.
  • Both can already be used with monadic combinators like map or and_then.
  • Both try and async/await allow to write code in imperative style, as if the subcalls could not fail and were synchronous, seemingly computing with T directly rather than Result<T, Error> and Future<T>, respectively.
  • Both were first implemented as macro-style try!(foo) and await!(foo).

Based on aforementioned observation, I would like to bring a kind of meta-argument: In our universe A, try!(foo) was replaced by the postfix sigil notation foo?. Later we discuss the replacement for await!(foo). Imagine a mirror universe B, which is like our A, except that Future with async/await came before Result with try. Imagine further that in B, for whatever reason, await!(foo) has been replaced by foo@ (or foo# or foo¡ or foo$). Later the people of B vigorously discuss by which to replace try!(foo). The official final proposal is foo.try, while some prefer the variants try foo, foo.try!(), foo?try, or foo?.

Most of the arguments pro or against each variant of await in A should directly translate to an argument pro or against the respective variant of try in B and vice-versa.

  • Would the proponents of await foo also prefer try (try foo) over foo???
  • Doesn’t any argument against postfix sigil foo@ imply that in retrospective, we should have ditched foo? in favor of foo.try?

However, my meta-argument could have the following weak points:

  • The seeming symmetry between A and B could be deceptive because ? is closer to try than @ (or #, ¡, $) is to await.
  • Even if the situation is symmetrical, the “strangeness budget” and “line noise tolerance” are limited so people of B should indeed prefer foo.try over foo? because of their contingent event of introducing of await first.
  • The meta-argument is faulty altogether because it involves counterfactual reasoning.
9 Likes