
Hi all... i'd like to propose a syntax extend of "break" and "continue" to let them work together with "yield". Syntax: continue_stmt: "continue" [ test ] break_stmt: "break" [ test ] it is only valid in "for ... in" block. when we writing "for <fields> in <container>: <suite>", we can say there is a generator ("__g = iter(<container>)") providing values ("<fields> = next(__g)") and the values are processing by <suite>. <suite> implenetments computing. (we focus) inside geneator("__iter__" of <container>) implenetments iteration. (sealed logic) ---- as current ---- "continue" is "next(__g)" (which equals to "__g.send(None)"), "break" leave the block and __g is garbage collected(which implies a __g.close()). "return" "raise" inside <suite> leave the block and __g is garbage collected. let's make thing reverse. consider we are write __g' code. generator function implenetments computing. (we focus) outside code(<suite> of "for ... in") implenetments continuation. (sealed logic) ---- as proposal ---- "continue <test>" is equiv to "__g.send(<test>)". "continue" is alias of "continue None". "break <test>" is equiv to "__g.throw(<test>)". "break" is alias of "break GeneratorExit". "return" "raise" inside <suite> impies a "break" to __g, with communication between "yield" and "continue", "break", this plays just as Ruby's block except return value of __g lost (may we use an "as" after "for ... in" to fetch return value?). -- = =!

Le 24/05/2012 12:47, 海韵 a écrit :
Hi, iter() returns an iterator, not a generator. All generators are iterators, but not all iterators are generators: an iterator may not have a .send() method. How would "continue something_that_is_not_None" behave with an iterator without a .send() method? Regards, -- Simon Sapin

On Thu, May 24, 2012 at 9:26 PM, Steven D'Aprano <steve@pearwood.info> wrote:
It's an approach to driving a coroutine (and one that was discussed back when the coroutine methods were added to generators). Currently, if you're using a generator as a coroutine, you largely *avoid* using it directly as an iterator. Aside from the initial priming of coroutines, most generator based code will either treat them as iterators (via for loops, comprehensions and next() calls), or as coroutines (via send() and throw() calls). The main reason tinkering with for loops has been resisted is that native support for even "continue <value>" (the least controversial part of the suggestion) would likely result in slowing down all for loops to cover the relatively niche coroutine use case. Also, if anything was going to map to throw() it would be "continue raise", not "break": continue -> next(itr) continue <value> -> itr.send(<value>) continue raise <exc> -> itr.throw(<value>) So yeah, this isn't a new proposal, but what's still lacking is a clear justification of what code will actually *gain* from the increase in the language complexity. How often are generator based coroutines actually used outside the context of a larger framework that already takes care of the next/send/throw details? Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Le 24/05/2012 12:47, 海韵 a écrit :
Hi, iter() returns an iterator, not a generator. All generators are iterators, but not all iterators are generators: an iterator may not have a .send() method. How would "continue something_that_is_not_None" behave with an iterator without a .send() method? Regards, -- Simon Sapin

On Thu, May 24, 2012 at 9:26 PM, Steven D'Aprano <steve@pearwood.info> wrote:
It's an approach to driving a coroutine (and one that was discussed back when the coroutine methods were added to generators). Currently, if you're using a generator as a coroutine, you largely *avoid* using it directly as an iterator. Aside from the initial priming of coroutines, most generator based code will either treat them as iterators (via for loops, comprehensions and next() calls), or as coroutines (via send() and throw() calls). The main reason tinkering with for loops has been resisted is that native support for even "continue <value>" (the least controversial part of the suggestion) would likely result in slowing down all for loops to cover the relatively niche coroutine use case. Also, if anything was going to map to throw() it would be "continue raise", not "break": continue -> next(itr) continue <value> -> itr.send(<value>) continue raise <exc> -> itr.throw(<value>) So yeah, this isn't a new proposal, but what's still lacking is a clear justification of what code will actually *gain* from the increase in the language complexity. How often are generator based coroutines actually used outside the context of a larger framework that already takes care of the next/send/throw details? Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
participants (4)
-
Nick Coghlan
-
Simon Sapin
-
Steven D'Aprano
-
海韵