-
Notifications
You must be signed in to change notification settings - Fork 13k
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
[docs] In the documentation of the identify function, clarify that using flatten()
is probably a better idea than using filter_map
#99230
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @m-ou-se (or someone else) soon. Please see the contribution instructions for more information. |
@@ -93,6 +93,8 @@ pub use num::FloatToInt; | |||
/// | |||
/// let iter = [Some(1), None, Some(3)].into_iter(); | |||
/// let filtered = iter.filter_map(identity).collect::<Vec<_>>(); | |||
/// // Equivalent, since Option is also a Iterator itself: | |||
/// // let filtered = iter.flatten().collect::<Vec<_>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Option
is not an Iterator
, but it does implement IntoIterator
, which is sufficient for flatten()
.
Although flatten()
is shorter to write, I personally still prefer filter_map(identity)
because it is a much simpler iterator, and simple is usually better for optimization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't really thought about the optimization aspect, just that I prefer not to import more libraries. That makes the advice previously given in the docs not as bad as I thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, unfortunately .flatten()
is a flat_map
, not a filter_map
, and thus fundamentally more complex. FlatMap
is bigger than FilterMap
because it needs to store the prefix and suffix iterators, as those might have more elements in them, whereas because FilterMap
only deals with Option
s so knows they can't have another item in them after getting the one value out. (You can also see this by how, for example, filter_map
preserves the upper bound on a size_hint
, which flat_map
doesn't, though admittedly the upper bounds on size hints are useless.) And this is why https://rust-lang.github.io/rust-clippy/master/index.html#flat_map_option exists.
I see that flat_map
mentions flatten
in the prose, but doesn't have an example -- maybe it'd make sense to move an example like this (perhaps with arrays instead of options) over to that method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Also, personally I'd never use identity
here, since it needs a use
and even ignoring that it isn't even shorter than writing out the |x| x
closure. But since it's in the docs for identity
and not for filter_map
that seems fine.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. Thank you for your insight, I especially appreciate including references and verifiable facts. I'll try to improve the documentation somewhere else.
I'll close this pull request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I'm glad you raised this, since it made me look for a performance
lint in clippy talking about this, but instead I found exactly the opposite, a lint suggesting the .filter_map(identity)
-> .flatten()
change.
So I've filed rust-lang/rust-clippy#9377 for the clippy folks to discuss the situation.
There is a odd example on the documentation for identity that seems to suggest using
filter_map
to flatten a array ofOption<T>
. However, this can be done far shorter using flatten.The example is good to showcase how identity works but I think a clarification would be good so people don't actually use it that way.
I hope this extra note will help people decide for themselves what the best solution to this problem is.