A key question right now is, can we have an implementation where the heap allocations that occur here don't have to? It's not 100% clear.
A key question right now is, can we have an implementation where the heap allocations that occur here don't have to? It's not 100% clear.
I think Rust clearly has an advantage here: since lifetimes are well-defined concept in the language itself, it should also be well-defined whether a generator can be allocated on the stack. Of course, I'm probably missing some hairy edge cases here.
Another aspect I found interesting was the ability to define custom code which runs every time a certain coroutine is suspended, or returns. In my reading, this allows for the coroutine to e.g. manage its own membership in a resume queue.
Tokio tackles this problem differently, but is this more powerful than Rust coroutines? Is there a mechanism by which a generic type could be used to wrap a generator and provide this functionality in a similar way? Asking partly as a point of conversation, and partly as someone who isn't fully steeped in Rust's type system yet.
https://boats.gitlab.io/blog/post/2018-01-25-async-i-self-re... and the two follow up posts are the latest thinking on this topic, and by latest, I mean "posted in the last few days". This is cutting-edge stuff!
The intention is for this stuff to support Tokio; that is, generators make asyc/await work, which lets you write futures code more easily, to be run with Tokio.
The lifetime binding tricks feel reminiscent of template metaprogramming-fu in C++, though the parts that have to be reasoned about past the standard library seem smaller and cleaner.
In Rust, it feels like we are leveraging our cleverness to accomplish a higher order of expression than what’s possible in other imperative languages today. In 20 years, maybe we’ll be talking about a promising new language concept that reminds of how exciting Rust lifetimes were back in 2018 :)
On the other hand, "stackful coroutines" and "coroutines" without a qualifier often refers things with dynamically growing stacks.
It seems to me that the C++ Coroutines refer to the former, which likely complicates the terminology further.
Being stackless is an implementation detail, even if a relevant one.