3 ms·
>Why did polling have to be baked into the language? See this comment: https://news.ycombinator.com/item?id=26407440 https://news.ycombinator.com/item?id=26407
by newpavlov 6y ago
>Why did polling have to be baked into the language?
See this comment: https://news.ycombinator.com/item?id=26407440 https://news.ycombinator.com/item?id=26407440
>Meanwhile C and C++ can easily adopt any async system call style because it made no assumptions in the standards about how that would be done.
Do you know about co_await in C++20? AFAIK (I only have a very cursory knowledge about it, so I may be wrong) it also makes some trade-offs, e.g. it requires allocations, while in Rust async tasks can live on stack or statically allocated regions of memory.
Also do not forget that Rust has to ensure memory safety at compile time, while C++ can be much more relaxed about it.
- zelly 6y agoC++20 coroutines are not async in the standard. They are just coroutines. Actually they have no implementation. The user has to write classes to implement the promise type and the awaitable type. You could just as easily write a coroutine library wrapping epoll as you could io_uring. The only thing it does behind your back (other than compile to stackless coroutines) is allocate memory, which also goes for a lot of other things.
- saurik 6y agoIs this not also true of Rust? Are you saying Rust in some sense hardcodes an implementation to await in a way C++ doesn't? (I am not a Rust programmer, but I am very very curious about this and would appreciate any insight; I do program in C++ with co_await daily, with my own promise/task classes.)
- kibwen 6y agoRust's async/await support is not intended as a general replacement of coroutines. In fact, async/await is built on top of coroutines (what Rust calls "generators"), but these are not yet stable. https://github.com/rust-lang/rust/issues/43122 https://github.com/rust-lang/rust/issues/43122
- saurik 6y agoOuch... thanks; I didn't realize the Rust situation was this bad :(. FWIW, I do not look at generators as being what I would want as my interface for working with coroutines, and am very much on board there with the comments from tommythorn. I guess I just have too many decades of experience working with coroutines in various systems I have used :(. https://github.com/rust-lang/rust/issues/43122#issuecomment-716256938 https://github.com/rust-lang/rust/issues/43122#issuecomment-... https://github.com/rust-lang/rust/issues/43122#issuecomment-716265969 https://github.com/rust-lang/rust/issues/43122#issuecomment-...
- steveklabnik 6y agoYou may want to watch/read my talk: https://www.infoq.com/presentations/rust-2019/ https://www.infoq.com/presentations/rust-2019/ I also did a follow up, walking through how you would implement all of the bits: https://www.infoq.com/presentations/rust-async-await/ https://www.infoq.com/presentations/rust-async-await/ TL;DR: rust makes you bring some sort of executor along. You can write your own, you can use someone else's. I have not done enough of a deep dive into what made it into the standard to give you a great line-by-line comparison.
- pjmlp 6y agoWhich makes them quite powerful, as they allow for other kinds of patterns.
- mratsim 6y agoIt requires allocation if the coroutine outlives the scope that created it. Otherwise compiler are free to implement heap allocation elision (which is done in Clang). Now compared to Rust, assuming you have a series of coroutines to process a deferred event, Rust will allocate once for the whole series while C++ would allocate once per coroutine to store them in the reactor/proactor.
- steveklabnik 6y agoRust never implicitly allocates, even with async/await. I have written Rust programs on a microcontroller with no heap, using async/await for it.
- mratsim 6y agoI don't think I've implied that allocation in Rust was implicit but that's a fair point.
- steveklabnik 6y agoYou said > Rust will allocate once for the whole series which, it will not. It is true that some executors will do a single allocation for the whole series, but that is not done by Rust, nor is required. That's all!