Coroutines is just a way to write continuations in an imperative style and with more overhead. I never understood the value. Just use lambdas/callbacks.
I'll take the bait. Here's a coroutine waitFrames(5); // wait 5 frames fireProjectile(); waitFrames(15); turnLeft(-30/*deg*/, 120); // turn left over 120 frames waitFrames(10); fireProjectile(); // spin and shoot for (i of range(0, 360, 60)) { turnRight(60, 90); // turn 60 degrees over 90 frames fireProjectile(); } 10 lines and I get behavior over time. What would your non-coroutine solution look like?
``` int f() { a; co_yield r; b; co_return r2; } ```
this transforms into
``` auto f(auto then) { a; return then(r, [&]() { b; return then(r2); }); }; ```
You can easily extend this to arbitrarily complex statements. The main thing is that obviously, you have to worry about the capture lifetime yourself (coroutines allocate a frame separate from the stack), and the syntax causes nesting for every statement (but you can avoid that using operator overloading, like C++26/29 does for executors)