I agree that Rust async is currently in a somewhat awkward state.
Don't get me wrong, it's usable and many projects use it to great effect.
But there are a few important features like async trait methods (blocked by HKT), async closures, async drop, and (potentially) existential types, that seem to linger. The unresolved problems around Pin are the most worrying aspect.
The ecosystem is somewhat fractured, partially due to a lack of commonly agreed abstractions, partially due to language limitations.
There also sadly seems to be a lack of leadership and drive to push things forward.
I'm ambivalent about the rushing aspect. Yes, async was pushed out the door. Partially due to heavy pressure from Google/Fuchsia and a large part of the userbase eagerly .awaiting stabilization.
Without stabilizing when they did, we very well might still not have async on stable for years to come. At some point you have to ship, and the benefits for the ecosystem can not be denied. It remains to be seen if the design is boxed into a suboptimal corner; I'm cautiously optimistic.
But what I disagree with is that polling was a mistake. It is what distinguishes Rusts implementation, and provides significant benefits. A completion model would require a heavier, standardized runtime and associated inefficiencies like extra allocations and indirection, and prevent efficiencies that emerge with polling. Being able to just locally poll futures without handing them off to a runtime, or cheaply dropping them, are big benefits.
Completion is the right choice for languages with a heavy runtime. But I don't see how having the Rust dictate completion would make io_uring wrapping more efficient than implementing the same patterns in libraries.
UX and convenience is a different topic. Rust async will never be as easy to use as Go, or async in languages like Javascript/C#. To me the whole point of Rust is providing as high-level, safe abstractions as possible, without constraining the ability to achieve maximum efficiency . (how well that goal is achieved, or hindered by certain design patterns that are more or less dictated by the language design is debatable, though)
>A completion model would require a heavier, standardized runtime and associated inefficiencies like extra allocations and indirection, and prevent efficiencies that emerge with polling.
You are not the first person who uses such arguments, but I don't see why they would be true. In my understanding both models would use approximately the same FSMs, but which would interact differently with a runtime (i.e. instead of registering a waker, you would register an operation on a buffer which is part of the task state). Maybe I am missing something, so please correct me if I am wrong in a reply to this comment: https://news.ycombinator.com/item?id=26407824
Don't get me wrong, it's usable and many projects use it to great effect.
But there are a few important features like async trait methods (blocked by HKT), async closures, async drop, and (potentially) existential types, that seem to linger. The unresolved problems around Pin are the most worrying aspect.
The ecosystem is somewhat fractured, partially due to a lack of commonly agreed abstractions, partially due to language limitations.
There also sadly seems to be a lack of leadership and drive to push things forward.
I'm ambivalent about the rushing aspect. Yes, async was pushed out the door. Partially due to heavy pressure from Google/Fuchsia and a large part of the userbase eagerly .awaiting stabilization.
Without stabilizing when they did, we very well might still not have async on stable for years to come. At some point you have to ship, and the benefits for the ecosystem can not be denied. It remains to be seen if the design is boxed into a suboptimal corner; I'm cautiously optimistic.
But what I disagree with is that polling was a mistake. It is what distinguishes Rusts implementation, and provides significant benefits. A completion model would require a heavier, standardized runtime and associated inefficiencies like extra allocations and indirection, and prevent efficiencies that emerge with polling. Being able to just locally poll futures without handing them off to a runtime, or cheaply dropping them, are big benefits.
Completion is the right choice for languages with a heavy runtime. But I don't see how having the Rust dictate completion would make io_uring wrapping more efficient than implementing the same patterns in libraries.
UX and convenience is a different topic. Rust async will never be as easy to use as Go, or async in languages like Javascript/C#. To me the whole point of Rust is providing as high-level, safe abstractions as possible, without constraining the ability to achieve maximum efficiency . (how well that goal is achieved, or hindered by certain design patterns that are more or less dictated by the language design is debatable, though)