More alternative names for yield-from

I still wish I could find a better name for it. Some more ideas: y = suspendable g(x) y = suspending g(x) y = sus g(x) # if you want something short & snappy -- Greg

Greg Ewing wrote:
Along with "call", all of these names don't seem to cater to the majority of people who are going use it as a replacement for the "for x in i: yield x" pattern. I haven't seen anyone (with that use case in mind) who has argued that "yield from" was a bad name. OTOH, I have seen several arguments about the treading use case being questionable, but maybe I mistakenly associate those words with that use. Nevertheless, I think there would be a sizable number of people disappointed to find out "suspendable" is a reserved word. But, I think if you were going down the other path with names, you would end up thinking about things like: y = yield for g(x) -Scott -- Scott Dial scott@scottdial.com scodial@cs.indiana.edu

What about : y = redirect g(x) y = yields g(x) -Gui On Fri, Feb 20, 2009 at 10:24 AM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:

Antoine Pitrou schrieb:
Agreed. It even fit quite well in the schedular example. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

2009/2/20 Greg Ewing <greg.ewing@canterbury.ac.nz>:
I still wish I could find a better name for it.
I think 'yield from' is better than all the other suggestions apart from 'yield *' which would be my choice. A while ago I created a function to almost exactly add the functionality you describe in your PEP including the return behaviour, which I implemented using raise RETURN( ... ). I've slightly modified it so it agrees with your specification and include it in this message after some very simple examples. Of course it would not help you implement the PEP but I thought it may be handy to play with some examples in order to fine tune the PEP. The function is called 'co' and applied to a generator function it turns it into a generator that implements the special behavior of yield FROM ( ... ) raise RETURN ( ... ). Here are some very simple examples and the implementation of co() follows at the end. # # List flattener. # def coflatten(x): if isinstance(x, list): for y in x: yield FROM( coflatten(y) ) else: yield x flatten = co(coflatten)
list(flatten([[[[1,2,3]]],4,5])) [1, 2, 3, 4, 5]
# # Something like Guido's tree example # class Tree(object): def __init__(self, label, children=()): self.label = label self.children = children @co def __iter__(self): skip = yield self.label if skip: yield 'SKIPPED' else: yield 'ENTER' for child in self.children: yield FROM( child ) yield 'LEAVE'
# # Simple example with raise RETURN ( ... ) # @co def gen(): a = yield FROM( co_nested() ) yield a def co_nested(): yield FROM( [1, 2] ) raise RETURN( 3 )
list(gen()) [1, 2, 3]
# # Implementation of co(), FROM, RETURN # class FROM(object): def __init__(self, gen, val=None): self.data = gen, val class RETURN(StopIteration): def __init__(self, val=None): self.val = val def co(cogen, val=None): def gen(*args, **kwargs): gen = cogen(*args, **kwargs) val = None callstack = [] while True: try: ret = gen.next() if val is None else gen.send(val) except StopIteration, e: if callstack: gen, val = callstack.pop(), getattr(e, 'val', None) continue raise if type(ret) is FROM: callstack.append(gen) gen, val = ret.data gen = iter(gen) else: try: val = yield ret except Exception, e: if hasattr(gen, 'throw'): val = yield gen.throw(e) else: raise return gen -- Arnaud

Greg Ewing wrote:
Along with "call", all of these names don't seem to cater to the majority of people who are going use it as a replacement for the "for x in i: yield x" pattern. I haven't seen anyone (with that use case in mind) who has argued that "yield from" was a bad name. OTOH, I have seen several arguments about the treading use case being questionable, but maybe I mistakenly associate those words with that use. Nevertheless, I think there would be a sizable number of people disappointed to find out "suspendable" is a reserved word. But, I think if you were going down the other path with names, you would end up thinking about things like: y = yield for g(x) -Scott -- Scott Dial scott@scottdial.com scodial@cs.indiana.edu

What about : y = redirect g(x) y = yields g(x) -Gui On Fri, Feb 20, 2009 at 10:24 AM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:

Antoine Pitrou schrieb:
Agreed. It even fit quite well in the schedular example. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

2009/2/20 Greg Ewing <greg.ewing@canterbury.ac.nz>:
I still wish I could find a better name for it.
I think 'yield from' is better than all the other suggestions apart from 'yield *' which would be my choice. A while ago I created a function to almost exactly add the functionality you describe in your PEP including the return behaviour, which I implemented using raise RETURN( ... ). I've slightly modified it so it agrees with your specification and include it in this message after some very simple examples. Of course it would not help you implement the PEP but I thought it may be handy to play with some examples in order to fine tune the PEP. The function is called 'co' and applied to a generator function it turns it into a generator that implements the special behavior of yield FROM ( ... ) raise RETURN ( ... ). Here are some very simple examples and the implementation of co() follows at the end. # # List flattener. # def coflatten(x): if isinstance(x, list): for y in x: yield FROM( coflatten(y) ) else: yield x flatten = co(coflatten)
list(flatten([[[[1,2,3]]],4,5])) [1, 2, 3, 4, 5]
# # Something like Guido's tree example # class Tree(object): def __init__(self, label, children=()): self.label = label self.children = children @co def __iter__(self): skip = yield self.label if skip: yield 'SKIPPED' else: yield 'ENTER' for child in self.children: yield FROM( child ) yield 'LEAVE'
# # Simple example with raise RETURN ( ... ) # @co def gen(): a = yield FROM( co_nested() ) yield a def co_nested(): yield FROM( [1, 2] ) raise RETURN( 3 )
list(gen()) [1, 2, 3]
# # Implementation of co(), FROM, RETURN # class FROM(object): def __init__(self, gen, val=None): self.data = gen, val class RETURN(StopIteration): def __init__(self, val=None): self.val = val def co(cogen, val=None): def gen(*args, **kwargs): gen = cogen(*args, **kwargs) val = None callstack = [] while True: try: ret = gen.next() if val is None else gen.send(val) except StopIteration, e: if callstack: gen, val = callstack.pop(), getattr(e, 'val', None) continue raise if type(ret) is FROM: callstack.append(gen) gen, val = ret.data gen = iter(gen) else: try: val = yield ret except Exception, e: if hasattr(gen, 'throw'): val = yield gen.throw(e) else: raise return gen -- Arnaud
participants (7)
-
Antoine Pitrou
-
Arnaud Delobelle
-
Georg Brandl
-
Greg Ewing
-
Guillaume Chereau
-
Scott Dial
-
spir