On 04 Mar 2014, at 15:59, Simon Sapin <simon.sa...@exyr.org> wrote: > On 04/03/2014 13:23, Tommi wrote: >> On Thu, Feb 13, 2014 at 10:05 AM, Simon Sapin <simon.sa...@exyr.org >> <mailto:simon.sa...@exyr.org>> wrote: >> >>> 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. >>> >> >> I agree with the spirit of your proposal. But I would change that first >> clause above to read: >> >> /An iterator is said to be "well-behaved" when its .next() method always >> returns None if the iterator logically has no elements to iterate over./ > > "No elements to iterate over" is already what None is supposed to mean, so > this doesn’t add anything.
What the wording of my definition does is it relaxes the constraints your definition specified. This relaxation of the rule is needed because there might be a need for the use case of having a once empty iterator become non-empty again. >> And all iterators should, by convention, be well-behaved. Otherwise it's >> impossible to pinpoint what exactly is the bug in the following code: >> >> struct Digits { >> n: int >> } >> >> impl Iterator<int> for Digits { >> fn next(&mut self) -> Option<int> { >> self.n += 1; >> >> if self.n == 10 { >> None >> } >> else { >> Some(self.n) >> } >> } >> } > > I don’t see what’s unclear here. This is the canonical example of an > ill-behaved iterator. This code is buggy, `self.n` should only be incremented > when returning Some(). I agree that this should be an ill-behaved iterator, but my point is that according to the specification [1], this is _not_ an ill-behaved iterator, it's a completely valid one. Given that self.n is less than 10, it correctly returns some elements as Some(...) and then it returns None. After it has returned None, according to specification [1], it is allowed to return whatever it wants. Therefore I'd be inclined to say that the bug in my example is in calling fold on an iterator whose all elements have been exhausted, but that seems just silly and fragile. [1]: The Iterator protocol states that an iterator yields a (potentially-empty, potentially-infinite) sequence of values, and returns None to signal that it's finished. 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. _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev