Osaka.rs – Rust async without the noise
aep.github.ioThis post is full of misinformation. Reposting my reply from Reddit:
> what the futures.rs authors decided to do: cram futures.rs into std and add an entire language feature to hide the bloat behind a code generator.
First the post establishes a problem with `futures-rs`- combinators and their associated binary bloat. Then in this quote it assumes that the bloat will carry over to the std-based futures used for async/await, even though the express purpose of std futures and async/await is to replace combinators with exactly what the author wants- generators.
> the rust equivalent would be slightly uglier, because generators can’t have continuation arguments
The next thing it assumes will carry over is the thread-local executor. (Or that's how I read it; it's a little unclear- maybe it means tokio's default executor?) But this complaint also doesn't apply to async/await, which has converted to an executor argument (`Waker`) to `Future::poll`, which is again exactly what the author wants- a continuation argument to the generator.
> its in no way fancy, but has two significant advantages over async/await. Firstly, it emits a generator without a specific execution engine.
>
> Secondly, Result just works as intended. There’s no need to wrap it in FutureResult because no such type exists.
>
> Lastly, sync is just: [polling and yielding in a loop] so anything that returns Ready/Again is sync. There is no task queue, no singleton, nothing ‘magic’.
These last criticisms of futures and async/await are the most baffling. Futures have always been agnostic to the execution engine, even in the 0.1 form, to a greater degree than osaka. The std version of futures already just uses `Result`. And `await` is just polling and yielding in a loop. The task queue is osaka's `yield poll.again(..)`, the (actually non-)singleton is osaka's `poll` argument, and the "magic" is that `poll` is only accessible from manual `Future::poll` impls.
This all seems like very surface-level stuff to me- hardly something that would prevent anyone from using async/await on embedded. The execution model is identical. I saw [this tweet](https://twitter.com/arvidep/status/1092818400798298114) saying "you cannot create a push based executor" and [this tweet](https://twitter.com/arvidep/status/1092823133390864385) saying "any [Future-based] alternatives need to look like tokio," but it's unclear to me exactly what is changing here, compared to existing embedded uses of async/await.
And copying from mine, regarding binary size:
So, https://github.com/polachok/fahrenheit is a toy executor that's trying to emulate tokio. It's still not really written for size; it assumes you have an OS, so it's also a bit bigger than you might do for true embedded. Its server example ends up being ~300k.
I also tried https://github.com/mgattozzi/async-await-class, which doesn't work with the OS, and is pretty basic. It's a bit outdated (` nightly-2018-08-18 `), also not written for size, but it ends up being ~155k.
Finally, https://github.com/Nemo157/embrio-rs is explicitly for embedded. Its "hello" example weighs in at ~38k.
The entire section "What’s up with async in rust" lists an example of futures combinators and blames tokio for it. The post is seriously confused.
This guy is so into himself, the first thing he does is ask for pull-requests to fix his typos because he can't be bothered to proofread.