Boost logo

Boost :

Subject: Re: [boost] {Review] Coroutine reviewstarts today, September 3rd
From: Eugene Yakubovich (eyakubovich_at_[hidden])
Date: 2012-09-03 19:30:02


On Mon, Sep 3, 2012 at 6:46 AM, Hartmut Kaiser <hartmut.kaiser_at_[hidden]> wrote:
>
> Hi all,
>
> The review of Oliver Kowalke's Boost.Coroutine library starts today,
> September 3rd 2012, and will end on September 12th.
> I really hope to see your vote and your participation in the discussions on
> the Boost mailing lists!
>

Hi Oliver,

I'm new to this list but because I wanted a coroutine library for a
long time, I want to participate in this review. I'm also very
impressed by Boost.Context and glad that it stands as a standalone and
not in the detail namespace of this coroutine library.

I have a few questions, though. Starting with generator class (easiest):

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);
    };
}

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 << ' ';

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.

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().

Regards,
-Eugene


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