Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>Why did polling have to be baked into the language?

See this comment: 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.



C++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.


Is 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.)


Rust'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


Ouch... 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-...

https://github.com/rust-lang/rust/issues/43122#issuecomment-...


You may want to watch/read my talk: 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/

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.


Which makes them quite powerful, as they allow for other kinds of patterns.


It 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.


Rust never implicitly allocates, even with async/await. I have written Rust programs on a microcontroller with no heap, using async/await for it.


I don't think I've implied that allocation in Rust was implicit but that's a fair point.


You 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!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: