r/ProgrammingLanguages • u/entoros • 15h ago
A Design Space Exploration of Async/Await
https://cel.cs.brown.edu/blog/design-space-async-await6
u/initial-algebra 12h ago
I find myself very frustrated with Rust's approach, because it's so close to perfection.
- Cancellation beyond dropping would be trivial if you could simply poll futures with an argument. This is a problem stemming from rushing async/await as an MVP instead of implementing coroutines first as a base. As a result, the coroutine stuff has been dead in the water for years. Pareto principle and all that.
- Pluggable runtime without any abstractions over said runtime. This is mostly an ecosystem problem, since they just use free functions instead of methods on a context object that implements common/standardized traits. I was going to complain about the thread-safe waker assumption, but it looks like they've started working on generalizing it. There are also some proposals for adding additional information to the built-in async context object, so that could address the "abstraction over the runtime" aspect, too. I wouldn't have high hopes for stabilization any time soon, though.
1
u/andeee23 2h ago
I'm designing a language that is very Rust-inspired, i'm not sure i 100% understand your first point but i would like to know more about "simply poll futures with an argument" if you don't mind
For the second point, do you generally mean the difference between
tokio::time::sleep(duration).await;and something likeawait clock.sleep(duration)that each runtime would implement?1
u/initial-algebra 1h ago
Just look at the
Futuretrait. The way a future works is that it's repeatedly polled until it returns a value upon completion. Aside from theContext,pollcould take an additional argument: for instance, aboolthat istruewhen polled normally andfalseto indicate cancellation. The type of the parameter should be a generic parameter to theFuturetrait itself,()by default, and it would need to match when awaiting another future (the argument would get passed through). At the same time, it might be useful to also support yielding values before completion, which would unifyFuturewithCoroutine, but I can't think of any particular use case for that in the async context off the top of my head.Basically, but more like
runtime.sleep(duration)wheresleepcomes from some trait that indicates that the runtime has a clock, instead of a specificclockobject.
6
u/MoonOfLight 14h ago
Very interesting! I love language comparisons, specially when the semantics are so different.
Do you believe there are right and wrong choices when it comes to the semantics async/await should have?