On Sat, Oct 30, 2010 at 4:42 PM, Ron Adam rrr@ronadam.com wrote:
Ok, after thinking about this for a while, I think the "yield from" would be too limited if it could only be used for consumers that must run until the end. That rules out a whole lot of pipes, filters and other things that consume-some, emit-some, consume-some_more, and emit-some_more.
Indeed, the "stop-in-the-middle" aspect is tricky, but is the crux of what we're struggling with here.
I think I figured out something that may be more flexible and insn't too complicated.
Basically a way to use yield from, while declaring how to force the end of iteration? Interesting idea.
However, I think sentinel values are likely a better way to handle this in a pure PEP 380 context.
Here's an example.
Modifying this example to use sentinel values rather than throwing in exceptions actually makes it all fairly straightforward in a PEP 380 context. So maybe the moral of this whole thread is really "sentinel values good, sentinel exceptions bad".
# Helper function to finish off a generator by sending a sentinel value def finish(g, sentinel=None): try: g.send(sentinel) except StopIteration as ex: return ex.value
def gtally(end_tally=None): # Tallies numbers until sentinel is passed in count = tally = 0 value = object() while 1: value = yield if value is end_tally: return count, tally count += 1 tally += value
def gaverage(end_avg=None): count, tally = (yield from gtally(end_avg)) return tally / count
def main(): g = gaverage() next(g) for x in range(100): g.send(x) return finish(g)
Even more complex cases, like my sum-of-averages example (or any equivalent multi-level construct) can be implemented without too much hassle, so long as "finish current action" and "start next action" are implemented as two separate steps so the outer layer has a chance to communicate with the outside world before diving into the inner layer.
I think we've thrashed this out enough that I, for one, want to see how PEP 380 peforms in the wild as it currently stands before we start tinkering any further.
Cheers, Nick.