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
) andFuture
are essentially monads. - Both can already be used with monadic combinators like
map
orand_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 thanResult<T, Error>
andFuture<T>
, respectively. - Both were first implemented as macro-style
try!(foo)
andawait!(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 prefertry (try foo)
overfoo??
? - Doesn’t any argument against postfix sigil
foo@
imply that in retrospective, we should have ditchedfoo?
in favor offoo.try
?
However, my meta-argument could have the following weak points:
- The seeming symmetry between A and B could be deceptive because
?
is closer totry
than@
(or#
,¡
,$
) is toawait
. - Even if the situation is symmetrical, the “strangeness budget” and “line noise tolerance” are limited so people of B should indeed prefer
foo.try
overfoo?
because of their contingent event of introducing of await first. - The meta-argument is faulty altogether because it involves counterfactual reasoning.