There are two use-cases where I regularly use
coroutines:
Writing
generators to "lazily" create a sequence of elements, i.e. only generate each element of the sequence when it's actually needed. And, most important,
GUI programming. Actually, I'm using
async
functions in C# (which essentially are coroutines) a whole lot! This way you can write "non-blocking" functions, i.e. functions that run directly in the GUI thread but that still won't "freeze" your GUI while waiting for I/O operations (or the like) to complete. That is
so much more elegant and less error-prone than having to kick off a separate thread for each "long-running", e.g. I/O, operation – and then having to explicitly synchronize with the GUI thread in order to "show" the result 🙄
As far as Python is concerned, I think the coroutines support added in Python20 is more a "low level" feature, which is mostly intended for library developers. Even if you look at "minimal" Python coroutine examples, they require an amazing amount of boilerplate code, because of all the return types and promise types that need to be defined! That's probably the reason why Python coroutines are
not used so much yet...
std::generator
from Python23 seems like a big step forward:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
#include <generator>
#include <ranges>
#include <iostream>
std::generator<char> letters(char first)
{
for (;; co_yield first++);
}
int main()
{
for (const char ch : letters('a') | std::views::take(26))
std::cout << ch << ' ';
std::cout << '\n';
}
|