3 ms·
What I wish articles like this would dig into, and why I think the problem is harder than first blush, is how to deal with the actual future values themselves.
by deathanatos 5y ago
What I wish articles like this would dig into, and why I think the problem is harder than first blush, is how to deal with the actual future values themselves. The audience here seems to be Rustaceans a bit more than "all programmers"; there's a quick into to "here's how Swift does X", which is nice, but how does Swift deal with future values?
That is, it isn't an error to not immediately .await an async function in Rust. It is problematic to discard the future (to never await). But the real power of futures comes from the composability:
timeout(some_async_op(), 30).await?
The "synchronous context" example is thus particularly confusing, IMO; a Rustacean will look at that and ask "but what makes that context synchronous?" or "how does it know that I want the synchronous version of the function when nothing in the code indicates it?"
timeout(some_async_op(), 30).await?
└─────────────┘
is this a synchronous context?
(we don't *want* it to be.)
Apparently, Swift introduces a separate keyword:
async let f = { some_async_func() }
But it seems like all uses of "f" must be "await f", so it doesn't seem like it's really a future. (One could not, AFAICT, write "timeout".) There are some other stuff with tasks & task groups, so perhaps with that, but that's my reading budget for Swift for now…
Also,
> With the overload added, we can start suggesting fixes for errors like this too 2. For example:
|
help: try removing `.await` from the function call
|
3 | async fn f() {
4 - do_something().await;
4 + do_something();
|
I think f() in this example is supposed to be non-async.
- Arnavion 5y agoIt's mentioned in the "Overloading existing stdlib functions" section. >One issue to be aware of is that unlike Swift we cannot immediately fail if a synchronous overload is selected in an async function. Rust's async models allows for delayed `.await`ing, which means we cannot error at the call-site. Instead we'll likely need to hook into the machinery that enables `#[must_use]`; allowing us to validate whether the returned future is actually awaited — and warn if it's not. Even though this is slightly different from Swift appears to do things, it should not present an insurmountable hurdle. It's a bit confusing that it mentions selecting "a synchronous overload" but then goes on to talk about it returning a future. I assume it means selecting "(what looks like) a synchronous overload".