On Feb 13, 2014, at 11:56 AM, Daniel Micay <danielmi...@gmail.com> wrote:

> On Thu, Feb 13, 2014 at 10:05 AM, Simon Sapin <simon.sa...@exyr.org> wrote:
>> Hi,
>> 
>> The Rust documentation currently makes iterators behavior undefined after
>> .next() has returned None once.
>> 
>> http://static.rust-lang.org/doc/master/std/iter/trait.Iterator.html
>>> 
>>> The Iterator protocol does not define behavior after None is
>>> returned. A concrete Iterator implementation may choose to behave
>>> however it wishes, either by returning None infinitely, or by doing
>>> something else.
>> 
>> 
>> http://static.rust-lang.org/doc/master/guide-container.html
>>> 
>>> In general, you cannot rely on the behavior of the next() method
>>> after it has returned None. Some iterators may return None forever.
>>> Others may behave differently.
>> 
>> 
>> 
>> This is unfortunate. Code that accepts any iterator as input and does with
>> it anything more complicated than a single 'for' loop will have to be
>> defensive in order to not fall into undefined behavior.
>> 
>> The type system can not enforce anything about this, but I’d like that we
>> consider having conventions about "well-behaved" iterators.
>> 
>> ---
>> 
>> Proposal:
>> 
>> 0. An iterator is said to be "well-behaved" if, after its .next() method has
>> returned None once, any subsequent call also returns None.
>> 
>> 1. Iterators *should* be well-behaved.
>> 
>> 2. Iterators in libstd and other libraries distributed with rustc *must* be
>> well-behaved. (I.e. not being well-behaved is a bug.)
>> 
>> 3. When accepting an iterator as input, it’s ok to assume it’s well-behaved.
>> 
>> 4. For iterator adaptors in particular, 3. means that 1. and 2. only apply
>> for well-behaved input. (So that, eg. std::iter::Map can stay as
>> straightforward as it is, and does not need to be coded defensively.)
>> 
>> ---
>> 
>> Does the general idea sound like something y’all want? I’m not overly
>> attached to the details.
>> 
>> --
>> Simon Sapin
> 
> Enforcing this invariant makes many adaptors more complex. For
> example, the `filter` adaptor would need to maintain a boolean flag
> and branch on it. I'm fine with the current solution of a `fuse`
> adaptor because it moves all of the responsibility to a single
> location, and user-defined adaptors don't need to get this right.

This was the main reasoning behind the current logic. The vast majority of users
of iterators don't care about next() behavior after the iterator has returned
None, so there was no need to make the iterator adaptors track extra state in
the general case. Any client who does need it can just call `.fuse()` to get a
Fuse adaptor that adds the necessary checks.

-Kevin

Attachment: smime.p7s
Description: S/MIME cryptographic signature

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

Reply via email to