Live data from Hacker News

My tutorial and take on C++20 coroutines

scs.stanford.edu

71–80 of 144 posts

Re: My tutorial and take on C++20 coroutines

#71
post #54

Earlier quoted context omitted.

As much as I like some replacement candidates, C++ is everywhere, so if you want to do anything related with graphics, machine learning, compiler development, OS drivers ,IoT toolchains, and not having the burden to sort out infrastructure problems by yourself, then C++ is the less painful way to go. Some would say C, but in domains like machine learning, you really don't want to write plain old C for what is running…

Yes, you do not program in C++ because you want to program in C++. You do because a lot of cool, interesting (and yes, well paid) stuff is done in C++. Still, with all its issues, I do quite like the language, but unless you want to work on some industry that is C++-centric, I do not think it is worth learning just for the sake of it.

Same here, I keep referring how C++ was the upgrade path from Turbo Pascal because I never came clear with bare bones C.

Since 2002, it has been a mix of .NET, C++ and Java, with my C++'s usage decreasing since those days, yet it is never zero, there is always a library or OS API to create bindings for.

I also like the language, but I definitely do not fit the culture of every ms and byte counts that they inherited from C.

On the C++ code where I have full control, RTTI, exceptions and STL bounds checking are always enabled, and I am yet to find a project where it mattered to have done otherwise.

Re: My tutorial and take on C++20 coroutines

#72
> C++20 coroutines are implemented as a nice little nugget buried underneath heaps of garbage that you have to wade through to access the nice part. Frankly, I was disappointed by the design, because other recent language changes were more tastefully done, but alas not coroutines. Further obfuscating coroutines is the fact that the C++ standard library doesn’t actually supply the heap of garbage you need to access coroutines, so you actually have to roll your own garbage and then wade through it.

Well, that sounds like more fun than a tax increase.

Re: My tutorial and take on C++20 coroutines

#73

Earlier quoted context omitted.

To clarify what stackless means when you're writing code: * calling into the coroutine from the caller uses the caller's stack (i.e. it just pushes on another stack frame). * the lack of a coroutine stack ("stackful" coroutine) means that the coroutine can only "yield" a value from a single method; it cannot call a function F, and then have F yield back to the original coroutine's caller. * In other words: you can th…

You are right that you are effectively stuck in a single coroutine (non-stack) frame. But you can chain multiple such coroutine frames, because one coroutine can co_await another.

Thanks for this great article! I've been circling my way around understanding coroutines and this really put it in place.

I think this co_awaiting is the most confusing part for folks: in most languages with stackful coroutines, it makes sense how one can

1. call "co_await" on a coroutine at a high-level API boundary 2. have that coroutine execute normal code all the way down to some expensive part (e.g. I/O) 3. at that particular point "deep" down in the expensive parts, that single point can just call "yield" and give control all the way back to the user thread that co_awaited at 1, usually with some special capability in the runtime.

I believe the way you can do this in C++20 concepts is to co_yield a promise all the way back to the originating "co_await" site, but I may be confused about this still...

It's totally clear to me why they didn't choose this for C++: keeping track of some heap-allocated stack frames could prove unwieldy.

I wish more effort went into explaining and promoting coroutines. Right now the advice seems to be "be brave and DIY, or just use cppcoro until we figure this out".

Re: My tutorial and take on C++20 coroutines

#74
post #48
post #18

Part of this is that I’m tired, but it blows my mind how difficult C++ coroutines are as someone who considers themselves decent at C++ (although maybe I’m not) and uses coroutines in other languages. The amount of code needed to do almost nothing is extraordinary, and putting it all together doesn’t seem like you would often get on your first try. I get that new keywords basically can’t be added, but man, that’s pai…

This is all down to not having a "managed runtime", so it has to be shoehorned into the environment available where you have a stack, a heap, and that's basically it.

For me coming from Rust, this just seems way overly complicated to me. Rust's async doesn't even need a heap to work: https://lights0123.com/blog/2020/07/25/async-await-for-avr-w...

Re: My tutorial and take on C++20 coroutines

#75
post #18

Part of this is that I’m tired, but it blows my mind how difficult C++ coroutines are as someone who considers themselves decent at C++ (although maybe I’m not) and uses coroutines in other languages. The amount of code needed to do almost nothing is extraordinary, and putting it all together doesn’t seem like you would often get on your first try. I get that new keywords basically can’t be added, but man, that’s pai…

A part of the tis that the standards committee decided to do a multi phase rollout. They created the core language parts and will hopefully in a future version add the library support making it easier to approach. (And then hopefully find that the design works with the library design ...)

Re: My tutorial and take on C++20 coroutines

#76

Earlier quoted context omitted.

I don't know how to answer that. For me, it is 100%, but it is a small sample size and one where I, in part, set the standard. If you have a C++11 code base, you don't really lose anything by adopting C++17, and you do gain a few things.

Interesting; I've always mistakenly assumed that C++ codebases working with different standards would necessarily end up being a patchwork.

If you combine larger libraries from pre-eleven with post-eleven libraries you will see the different worlds (Qt as a prime example), small libraries can easily be enhanced with smart pointers etc. so do you don't have much of a clash. After eleven most features are nice things, which make things a bit nicer here or there, but don't change the code as much as reliance on moves and smart pointers do with eleven. Also upgrade from C++11 to C++17 is as painless as a compiler update can be. (Meaning: in some corner case you will probably hit some compiler optimization caused issue, but for most code it's a non-issue)

Re: My tutorial and take on C++20 coroutines

#78
post #48

Earlier quoted context omitted.

This is all down to not having a "managed runtime", so it has to be shoehorned into the environment available where you have a stack, a heap, and that's basically it.

For me coming from Rust, this just seems way overly complicated to me. Rust's async doesn't even need a heap to work: https://lights0123.com/blog/2020/07/25/async-await-for-avr-w...

Requiring heap allocation for coroutines was extremely contentious to say the least. But because C++ does not have a borrow checker, all the other allocation-less designs proved to be very error prone.

C++ coroutines do support allocators [1], so it is not a huge issue, but it does complicate the design further.

[1] the compiler is also allowed to elide the allocation, but a) it is not clear how this is different from the normal allocation elision allowance that compilers already had, and b) it is a fragile optimization.

Re: My tutorial and take on C++20 coroutines

#79

From the existing explanations, I’ve deduced that coroutines are a form of continuation based coopetative multitasking. Is it possible to “restart” the sequence, and how would this be done?

There are two ways you can restart with the standard interface:

- create a new task (start over) and maybe delete the old task

- implement the task as a generator that can repeatedly yield values

I think this is as good as you can hope for without lots of other interfaces (and since you can implement all the promise types yourself, you can do that too).

Re: My tutorial and take on C++20 coroutines

#80
Seems like once again we are stuck with an overly complex and un-ergonomic design that is going to burden every single C++ programmer for a decade, until someone gets fed up and fixes it. Just like chrono, just like random, just like std::string, all of std::algorithm, etc. God damn it.
Post reply on HN