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