-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RangeFrom::max should return None #47169
Comments
What does "the maximum element is unbounded" mean exactly? The only interpretation I can find that applies to Going with that interpretation, it's true that
|
I mean that, for any element It does cause a behaviour change, but I can't imagine any users are relying on the termination behaviour of an unbounded iterator like this (especially considering the overflow checks are going to be disabled in release mode). Semantically, I think it's more intuitive to think of The fact that we could only provide this behaviour for some iterators, and others would be consigned to their infinite loops, does decrease the usefulness of such a change, but I think it is still more useful than the current behaviour. |
This definition does not match
But that is not what's documented, and not what the default implementation does, and not something the default implementation can do. I also don't buy that None for empty iterators is not intuitive. The maximum of an empty set/sequence indeed does not exist.
It's not just that this change will fail to achieve its intended effect for some iterators. It will muddy the definition of I'm actually not even sure if returning None is better than looping infinitely -- it won't hang the program, but code that does anything other than |
That's true. More special casing here would be possible, but probably not desirable. The issue is the distinction between what someone expects
I agree that
That's a compelling argument not to change. Without a way to enforce it, this is just going to end up being confusing. Perhaps there's an opportunity for more sensible behaviour with |
With every iterator function I assume that #![feature(step_trait)]
use std::iter::Step;
use std::ops::RangeFrom;
#[derive(Clone, PartialEq, PartialOrd, Debug)]
struct Foo(u8);
impl Step for Foo {
// dummies
fn steps_between(_: &Foo, _: &Foo) -> Option<usize> { unimplemented!() }
fn replace_one(&mut self) -> Foo { unimplemented!() }
fn replace_zero(&mut self) -> Foo { unimplemented!() }
fn sub_one(&self) -> Foo { unimplemented!() }
fn add_usize(&self, _: usize) -> Option<Foo> { unimplemented!() }
// required for this example
fn add_one(&self) -> Foo {
if self.0 >= 10 {
Foo(0)
} else {
Foo(self.0 + 1)
}
}
}
fn main() {
let range = RangeFrom { start: Foo(0) };
for i in range.take(20) {
println!("{:?}", i);
}
} This RangeFrom does indeed have a maximum element, which is 10. Returning If we discuss specializing #47082 does not help this issue, e.g. because |
Iterator::max
states "If the iterator is empty,None
is returned.". In the case of an unbounded range, we know that this maximum does not exist. This meansRangeFrom::max
is consigned to looping forever.If the documentation for
Iterator::max
were rewritten: "If the iterator is empty, or if the maximum element is unbounded,None
is returned.", this could then be implemented as special cases for unbounded iterators (e.g.RangeFrom
), which is far more useful and intuitive.The same complaint goes for
Iterator::last
.The text was updated successfully, but these errors were encountered: