On Tue, Nov 25, 2014, at 15:31, Chris Barker wrote:
Once you start nesting these things, the distinction between "implementor" and "caller" gets mingled. And I think this is all about how nested generators behave, yes?
For something more concrete, we can consider a naive implementation of iteration over adjacent pairs:
def pairs(x): i = iter(x) while True: yield next(i), next(i)
list(pairs(range(1)))
[]
list(pairs(range(2)))
[(0, 1)]
list(pairs(range(3)))
[(0, 1)]
list(pairs(range(4)))
[(0, 1), (2, 3)]
list(pairs(range(5)))
[(0, 1), (2, 3)]
list(pairs(range(6)))
[(0, 1), (2, 3), (4, 5)]
To work under the new paradigm, you need to catch StopIteration explicitly:
def pairs(x): i = iter(x) while True: try: a = next(i) b = next(i) except StopIteration: return yield a, b