On Tue, Nov 8, 2011 at 6:24 PM, Ron Adam email@example.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.
*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 (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).
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?