Guido van Rossum wrote: >>This change would make a huge difference to the practical usability of these >>generator-based tasks. I think they're much less likely to catch on if you >>have to write "raise StopIteration( Result )" (or "_return( Result )") all the >>time. >> >>[1] a.k.a. coroutines, which i don't think is an accurate name, anymore. > > > Before we do this I'd like to see you show some programming examples > that show how this would be used. I'm having a hard time understanding > where you would need this but I realize I haven't used this paradigm > enough to have a good feel for it, so I'm open for examples. > > At least this makes more sense than mapping "return X" into "yield X; > return" as someone previously proposed. :)
It would be handy when the generators are being used as true pseudothreads with a scheduler like the one I posted earlier in this discussion. It allows these pseudothreads to "call" each other by yielding the call as a lambda or partial function application that produces a zero-argument callable. The called pseudothread can then yield as many times as it wants (either making its own calls, or just being a well-behaved member of a cooperatively MT environment), and then finally returning the value that the original caller requested. Using 'return' for this is actually a nice idea, and if we ever do make it legal to use 'return' in generators, these are the semantics it should have. However, I'm not sure its something we should be adding *right now* as part of PEP 342 - writing "raise StopIteration" and "raise StopIteration(result)", and saying that a generator includes an implied "raise StopIteration" after its last line of code really isn't that difficult to understand, and is completely explicit about what is going on. My basic concern is that I think replacing "raise StopIteration" with "return" and "raise StopIteration(EXPR)" with "return EXPR" would actually make such code easier to write at the expense of making it harder to *read*, because the fact that an exception is being raised is obscured. Consider the following two code snippets: def function(): try: return except StopIteration: print "We never get here." def generator(): yield try: return except StopIteration: print "But we would get here!" So, instead of having "return" automatically map to "raise StopIteration" inside generators, I'd like to suggest we keep it illegal to use "return" inside a generator, and instead add a new attribute "result" to StopIteration instances such that the following three conditions hold: # Result is None if there is no argument to StopIteration try: raise StopIteration except StopIteration, ex: assert ex.result is None # Result is the argument if there is exactly one argument try: raise StopIteration(expr) except StopIteration, ex: assert ex.result == ex.args[0] # Result is the argument tuple if there are multiple arguments try: raise StopIteration(expr1, expr2) except StopIteration, ex: assert ex.result == ex.args This precisely parallels the behaviour of return statements: return # Call returns None return expr # Call returns expr return expr1, expr2 # Call returns (expr1, expr2) Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com