On Fri, Aug 13, 2010 at 7:39 AM, Nick Coghlan firstname.lastname@example.org wrote:
On Thu, Aug 12, 2010 at 10:51 PM, Greg Ewing email@example.com wrote:
Nick Coghlan wrote:
Without send() and throw(), an object is just an iterator, never a cofunction (as there is no way for it to make cooperative calls - you need the extra two methods in order to receive the results of any such calls).
There are plenty of uses for cofunctions that never send or receive any values using yield, but just use it as a suspension point. In that case, send() is never used, only next(). And I suspect that use of throw() will be even rarer.
Could you name some of those uses please? If you aren't getting answers back, they sound like ordinary iterators to me. The whole *point* of cofunctions to my mind is that they let you do things like async I/O (where you expect a result back, in the form of a return value or an exception) in a way that feels more like normal imperative programming.
So, you may consider there to be plenty of uses for iterate-only cofunctions, but I come up blank.
At the very least, a non-generator cofunction will need to offer close() and __del__() (or its weakref equivalent) to release resources in the event of an exception in any called cofunctions (independent of any expected exceptions, almost anything can throw KeyboardInterrupt).
I just don't see how further blurring the lines between cofunctions and ordinary generators is helping here. Providing dummy implementations of send() and throw() that ignore their arguments and devolve to next() is trivial, while still making the conceptual separation clearer. PEP 342 is *called* "Coroutines via enhanced generators", and it still seems to me that the usage of send() and throw() is one of the key features distinguishing a cooperative scheduler from ordinary iteration.