Boost logo

Boost :

Subject: Re: [boost] {Review] Coroutine reviewstarts today, September 3rd
From: Oliver Kowalke (oliver.kowalke_at_[hidden])
Date: 2012-09-04 02:38:36


Hi Eugene,

> 1. What is the rationale for having the generator-function's return
> statement be used to return the last generated value or forcing the
> use of yield_break (which uses exceptions that can be slow). My only
> experience with generators/coroutines has been in Python which might
> have biased my view but I think having the generator-function return
> void would be more natural (and would eliminate the need for
> yield_break). For example, if I wanted to generate a sequence of
> evens, I could write:
>
> typedef boost::coro::generator< int > gen_t;
>
> gen_t evens(int cnt) {
> return [=](gen_t::self_t& self) {
> for( int i = 0; i < cnt; i++ )
> self.yield(i*2);
> };
> }

the generator<> template was derived from coroutine<> and therefore it generator follows the practice of coroutien return_type(). Of course I think it would be possible to require a generator-function of void() with
self_t::operator( T t) (T = int, ... == return type from generator) - I should think about it (if and how it is implementable - what think the community members?).

some compilers complain some compilers to no if you end a function without a return statement.
yield_return() does complete the generator and unwind the stack (AFAIK python coroutines are stackles). Unforutnately each compiler has its own unwind facility so it is easier to throw an exception in order to unwind the corutine/generator.

> 2. Considering that generators are used to produce a sequence of
> values, would it make sense to support range based for loop? While
> playing with the library, I defined a (hacky) iterator together with
> begin/end functions that made it possible to:
>
> for( int x: evens(10) )
> std::cout << x << ' ';

Of course iterators should benefit from coroutines/generators in some places. Your code looks like C# - I assume evens(10) is the range enumerator based on a generator?

> I found such usage very natural and wanted to find out if you
> considered adding such support? This should also make it possible to
> turn the generators into Boost.Range ranges.

I agree.

> 3. Regarding both generator and coroutine classes. Their nested self_t
> class should perhaps be called caller_t as it encapsulates the
> caller's context and allows yielding the value _to_ the caller. It
> might then be possible to overload operator()(...):
>
> void gen_evens(gen_t::caller_t& caller) {
> for( int i = 0; i < 10; i++ )
> caller(i*2);
> }
>
> This will achieve a nice symmetry with code that is sending values to
> the coroutines with the use of operator().

maybe - I used Giovanni Derettas interface design. At least you need to call an equivalent to yield_break() - terminating the coroutine - too. THis might break the symmetry.

regards,
Oliver


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk