There was a bit of a discussion on Reddit about the await!
macro itself. I’m gonna relay the points here in case the Reddit thread goes boom.
The idea is to get rid of the await!
macro/possible future keyword and use the ? operator. It essentially relies on the fact that a Future
is a monad. We can compare it to an Option<T>
, which is also a monad, and with the Try
trait will soon get operator ? support.
You can use monadic bind with Option<T>
via the .and_then
method:
let this_is_an_option = Some(5);
let answer = this_is_an_option
.and_then(|x| if x % 2 == 0 { Some(2 * x) } else { None });
return answer;
However, this can be rewritten with the ? operator like so:
let this_is_an_option = Some(5);
let answer = this_is_an_option?;
return if answer % 2 == 0 { Some(2 * answer) } else { None });
Turns out that Future
s also have a monadic bind called .and_then
:
let this_is_a_future = client.get("https://www.rust-lang.org");
let answer = this_is_a_future
.and_then(|x| if x.is_valid() { Some(x.body) } else { None });
return answer;
So instead of writing this with the current await!
macro:
let this_is_a_future = client.get("https://www.rust-lang.org");
let answer = await!(this_is_a_future)?;
return if answer.is_valid() { Some(answer.body) } else { None };
We could try to extend the await functionality into the ? operator, like so:
let this_is_a_future = client.get("https://www.rust-lang.org");
let answer = this_is_a_future?;
return if answer.is_valid() { Some(answer.body) } else { None };
There are some questions about that, however. For example, the coroutine returns a Result
, so things like ??
might become usual, which is a bit weird. There’s also the fact that Try
as it currently is might not be able to include coroutine functions, so we would either have to change the Try
trait to support them, or create a new Try
trait specifically for async functions. I don’t know what the best course of action is here, because I’m not very knowledgeable on the internals right now, but that might be something worth looking at.