-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Suggest replacing simple loops with specialized folds #2401
Comments
This is a great idea. Whenever I bring up |
And as a bonus, |
I prefer |
A lot of simple loops can be written using fold-like methods in iterators. Clippy should have a set of lints (maybe even a lint group1) that promotes the more functional style.
Have a look at this code:
Seasoned functional programmers recognize that is is just a fold/reduce. In Rust, you'd write it like this:
Seasoned Rust programmers would use a specialized fold here (basically a shortcut that makes use of FromIterator):
.collect::<Vec<_>>()
for loops that just build vectorsLet's make this a bit more complicated:
This is still a pretty simple loop, and we can rewrite it like this:
(Sadly, it's not a trivial as it first appeared to be because filter passes a reference to the closure, and we need to rewrite that in the comparison we copied from the
if
. Instead of|&x| *x > 2
we could also generate|x| **x > 2
or|&&x| x > 2
.).filter.collect
for these kinds of loopsThere are of course a bunch more specialized folders we can recognize. For example:
Isn't it wonderfully procedural? It takes 4 lines and inline mutation to find out if an item in that iterator is greater than two. How about suggesting
any
instead? (Also see this exisiting lint.)any
instead of simple loops (that on condition match set a boolean to true and break)all
instead of simple loops (that on condition match set a boolean to false and break)find
instead of simple loops (that on condition match set an optional value to Some and break)position
/rposition
instead of simple loops (that count iterations and on condition match store the current iteration number in a variable and break)max{,_by,_by_key}
instead of simple loops (that compare values and store larger one in variable)min{,_by,_by_key}
instead of simple loops (that compare values and store smaller one in variable)sum
/product
instead of simple loopscontains(y)
instead ofiter().any(|x| x == y)
(Suggest replacing 'iter().any(|x| x == y)' with 'contains' where appropriate #2534)Haven't found an open issue about that, searched for "loop", "reduce", "fold".
Footnotes
Please name the group after an Office Assistant! ↩
The text was updated successfully, but these errors were encountered: