Hi,

On 04/08/2013 02:18, Kevin Ballard wrote:
I believe that #3 is the right behavior to define. This gives the most
flexibility to individual iterators, and we can provide an iterator
adaptor that gives any iterator the behavior defined by #1 (see Fuse in
PR #8276 <https://github.com/mozilla/rust/pull/8276>).
I think #3 is a terrible idea. It requires that every user of an iterator needs to keep track of if the iterator was exhausted and need to replace it with a dummy iterator that yields None forever or signal to other code that the iterator is exhausted. There is a lot of code that fetches a number of items from an iterator and then passes the iterator on to something else that does more with it.

If I now need to check if the iterator was exhaused and then create a new and empty iterator to pass onwards to the other function it makes it a lot more complicated. Imagine this Python code:

def dropwhile(predicate, iterable):
    iterable = iter(iterable)
    for x in iterable:
        if not predicate(x):
            yield x
            break
    for x in iterable:
        yield x

If it's not guaranteed that an iterator returns None (StopIteration) after it was exhausted it needs to be rewritten to this:

def dropwhile(predicate, iterable):
    iterable = iter(iterable)
    exhausted = True
    for x in iterable:
        if not predicate(x):
            yield x
            exhausted = False
            break
    if not exhausted:
        for x in iterable:
            yield x

People will forget that they have to do this and cause bugs with composable iterator patterns. Just look through the Python itertools package for how many cases of partial iterator processing exist: http://docs.python.org/2/library/itertools.html


Regards,
Armin
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to