Though it kind of bothered me at first, now I really like the way python handles the semipredicate problem, which is to throw an exception at the end of the iteration rather than try to return a specific value (which may end up as part of an iterable). Besides, I think that python's yield would have been one of the easiest ways to solve this problem. For those who don't know about yield it stops the execution of a function (it can be in the middle of an infinite loop) which will be resumed when the next value is fetched. Perl 6's lazy lists can be used in a similar way according to its faq
As for understanding my code, the concept is actually fairly simple (well, to me it is, but I'm used to working with closures). I started with a flat list iterator: a closure that holds the array and the current index. In the nested list version, each flat list iterator has a children which is an iterator for the current element if the element itself is an array. You could see it as equivalent to this:
def next:
if array[index].isAnArray() and array[index].hasNext()
ret = array[index].next();
else
ret = array[index]
endif
index++
end
. This means that the calling stack for a deeply nested list will be something like:
parent.next()
child.next()
grandChild.next()
...
And so each time a value is fetched, which is why an iterative solution like MidLifeXis's can be far more effective.
|