-
Notifications
You must be signed in to change notification settings - Fork 1.6k
iter.map()
should not guarantee that the closure is executed for all the iterated elements.
#1757
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
Comments
It doesn't guarantee it right now, but the implementation is limited, as if it was necessarily true. |
To be more specific, executed or not for all elements when? Since I associate to special-casing the method |
Alternatively, we could introduce a notion of purity (this has been discussed in the past but I don't remember where). That is, add a marker trait Unfortunately, 99% of methods in debug mode wouldn't be pure because integer overflow panics in debug mode. This would make debug/release behavior differ significantly (although, arguably, it already does...). |
If the map function is pure then the compiler can already optimize it away. |
@Stebalien But if it's pure, then LLVM not being able to optimize it is more or less a bug. |
Sorry, "pure", not pure. My point is that most non-trivial functions in rust aren't pure (there's going to be an assert/unwrap/allocation etc. somewhere). However, many of these side effects aren't really important and it would be nice to be able to say "this function has no important/noticeable side effects, you can avoid calling it if you don't use the result". Basically, make this kind of optimization (this RFC issue) opt-in. |
To defend the cause for some kind of special casing of the counting, the iterator might not be so simple so that a plain .count() without side effects can be reduced to a number (BTreeMap iterators and so on, maybe not even the VecDeque one). |
@bluss That's different, in that the data structure may have some simpler way to get the value. |
sure, the latter. |
What about putting the guarantee not on |
@durka Once specialization lands, external crate could actually provide that using #![feature(specialization)]
pub trait Count {
fn count(self) -> usize;
}
impl<I> Count for I where I: Iterator {
default fn count(self) -> usize {
Iterator::count(self)
}
}
impl<I> Count for I where I: ExactSizeIterator {
fn count(mut self) -> usize {
ExactSizeIterator::len(&mut self)
}
}
pub fn len<I: IntoIterator>(iter: I) -> usize {
Count::count(iter.into_iter())
} |
@durka That's more or less what count already says Iterator::count in rustdoc |
@Stebalien not sure what that adds over |
@durka |
There's an intermediate way there too, |
Famous example: |
This would allow things like optimizing
iter::Map
's implementation ofskip
.The text was updated successfully, but these errors were encountered: