items.filter(item => item.isSelected)
is not “functional trickery”. items.filter(item => item.isSelected)
is not “functional trickery”.A funny trick question as it pretty much does both.
Also I'll take "functional trickery" over needing a page called Slice Tricks so you can find out how to delete an item any day of the week.
let show_items = items.filter(…)
But yeah, things like this you have to know in advance anyway.• `fn filter(self, P²) -> A` consumes self and returns a new thing of type A;
• `fn filter(&mut self, P)` mutates in-place;
• `fn filter(&self, P) -> B<'_>` doesn’t mutate self, but produces a new thing of type B containing references to the contents of self.
As a concrete example, Rust has `Vec::retain(&mut self, P)` to filter a list/array in place, and `Iterator::filter(self, P) -> Filter<Self, P>` to filter an iterator, consuming that iterator object and wrapping it in another.
This is a sterling example of the point of the original article: Rust pushes you to thinking about ownership, and it’s really great and I miss it when working in other languages, where I have to stop and think whether I’m allowed to mutate this object or whether I should make a copy, and the cost of getting it wrong is bad performance in one direction and bugs that can be a nightmare to diagnose in the other direction.
—⁂—
¹ You need linear types to make it just about impossible to get wrong by accident. Rust has a weaker substitute that you can annotate functions with, #[must_use], which says “warn the user if they neglect to use the return value, because they’re almost certainly doing the wrong thing”.
² I’ve omitted the filter predicate P from the signatures to reduce distraction; in each case it’d probably be something like `<P: FnMut(&Self::Item) -> bool>`: a function that is passed a reference to an item and returns true or false.
Because if it is not functional trickery, I don’t really know what is (and no, recursion is not the answer) and it is sure clearer than the 3 nested loop or whatever one might come up with.