Open rafalg opened 3 weeks ago
You're missing a co_return
at the end. That's technically UB, but it works akin to how python would throw a StopIteration
.
You can either handle that exception or co_return
a null value.
Totally understood. What I meant is that it forces the generator client code to handle special value like null/empty optional as an additional condition to break the iteration. Would you consider adding such a feature to the cobalt ifself? Following python example maybe something like cobalt_iteration_break that could be thrown from generator impl. Cobalt could catch it and nicely terminate the for loop on the client side.
Im working a lot with paginated apis. Im wrapping them in generators so that the client code can work with continous the stream of data without knowing how many calls have been done to the server to acually fetch them. Adding these special values to handle cases like empty api responses etc is just a bit annoying.
What's the annoying part? An extra branch for co_return
in the generator?
The annoying part is extra condition I have to put in the client code. So instead of
while (g) {
auto x = co_await g;
...
}
I have to
while (g) {
auto x_wrapped_in_optional = co_await g;
if (!x) {
break;
}
auto x = *x;
...
}
Easy to forget, plus and additional case to cover in tests. Also everything returned from generator has to be wrapped into std::optional or something similar to allow this check to happen.
Ok, but can't you just throw from the generator then? Because by the time you call co_await
the generator doesn't know if it's completed or not.
Yeah I know I can throw. But it seems like another work around. Haven't done c++ for a while so don't know the limitations or if its possible at all. coming straight from python asyncio it just feels a bit arkward. Implementing stuff like database queries or paginated apis with generators seems kind a natural. Having to add these null checks or try/catch for a pretty simple case like query with no results is just a bit annoying :).
Hi,
Thanks for creating cobalt. Feels like python asyncio but in c++. Been trying to use generators to model results of paginated api like aws s3::list_objects. All in all seems pretty strightforward , I can co_yeild individual response elements and co_return the last one. But came across a corner case where api will respond with 0 elements. My outer loop is:
In python when list_objects goes out of scope simply terminates generator. In cobalt I got the
Any help appreciated!