[Python-ideas] Cofunctions - Getting away from the iterator protocol
Ron Adam
ron3200 at gmail.com
Tue Nov 8 17:56:13 CET 2011
On Tue, 2011-11-08 at 20:43 +1000, Nick Coghlan wrote:
> On Tue, Nov 8, 2011 at 6:24 PM, Ron Adam <ron3200 at gmail.com> wrote:
> > On Tue, 2011-11-08 at 15:46 +1000, Nick Coghlan wrote:
> >> No, that doesn't make any sense.
> >
> > Probably because I didn't explain it well enough.
>
> No, it doesn't make any sense because you're taking a symmetric
> coroutine concept and attempting to apply it to an asymmetric
> coroutine API design.
I'm not really thinking that way. I'm just looking at what I want to do,
and what I'd like to have to do it nicely in python.
> *If* this was a symmetric coroutine design (like greenlets), then
> *yes* it would make sense to offer resume() and throw() as your
> control flow APIs
Yes.
> (there wouldn't be a suspend() at all in a symmetric
> design, except perhaps as a convenience wrapper around invoking
> resume() on the coroutine that called resume() or throw() on you).
You lost me here with suspend() not being needed except as a wrapper
around resume(). I think the reason you don't want to do that is
because you may want to .resume() multiple sub-coroutines, but you only
suspend() the one your in.
The way I see it, coroutines are a bit like little box's where there is
a boundary we can't cross in the way we normally would with exceptions.
Which is where the throw() method comes in. A throw keyword would go
the other direction. (out instead of in.) It wouldn't raise the
exception and let it bubble out as in the case of an unexpected error.
It would handle expected exception conditions, so continuing from there,
does make sense.
My feeling is the reason we don't already have that, has less to do with
asymmetric/symmetric design principles, and more to do with not having a
strong enough need (possibly until now) to justify a new keyword.
An API design that doesn't require new keywords wouldn't have that
limitation. So we could offer both and let the programmer design his
coroutines as symmetrical or asymmetrical.
> With an asymmetric design, you only have 3 sensible options: terminate
> naturally, terminate with an exception or suspend execution. Look at
> the API design again - like the corresponding generator methods,
> cothread.resume() and cothread.throw() both use "returned normally" to
> indicate that the coroutine is suspended and still has more to do. If
> they raise an exception, it means the coroutine is done, either
> because it failed or because it finished normally (with the latter
> case being distinguished by a specific exception type, just as it is
> for generators). You're suggesting it would be reasonable to raise an
> exception *and* still expect the coroutine to eventually be resumed
> again. How is the caller of resume() or throw() meant to distinguish
> that new case from the two terminating cases?
Asymmetric, and symmetric wording is a description of how it's used. We
don't necessarily need to limit python programmers to one or the other
exclusively.
Let me come up with some working examples. I'm not too far from that
now. Then we can discuss and experiment with it in a much more
practical way.
Cheers,
Ron
More information about the Python-ideas
mailing list