Comment by jiehong
13 hours ago
> … to call them Select and Where.
While map is a great name, I always struggle to remember if ‘filter’ keeps elements that match the condition or removes them.
I mean, it’s like a colander: you filter noodles and water, but which one do you keep? The noodles, right? But, replace noodles with tea and now you want to keep the water part.
Naming is hard I guess.
There's always the Ruby strategy of just making all the names work. `select` and `filter` are buddies and you can use whichever you want or even go back and forth. Not a fan of `reduce`? That's fine, `inject` has got your back. Miss getting to type `collect` from Java or Rust? Don't worry, just use it instead of `map`, it's the same thing.
I believe Ruby uses names inspired by SmallTalk.
Yeah, Smalltalk has select, reject (inverted filter), collect (map) and inject.
Talking about un-guessable, misleading function names,
C++ std::remove.
I would never have guessed what it does exactly. (It moves elements that match the filter to the front, and moves the end-marker forward. Leaves all the elements in the collection. You need to erase them yourself. )
It returns the new end marker
Oh it's a bit like unordered-delete when using an arena. I guess I would have expected an ordered-delete instead
I've never run into a generic "filter" function which keeps only the non-matching elements.
Smalltalk has #reject: which does that. You could, of course, just wrap a not around the test in the closure, but sometimes reject with a well-named predicate is easier to read.
bsnpApproved := tvShows reject: [ :eachShow | eachShow hasNaughtyContent ].
Common Lisp's filter is remove-if which works this way.
(It also has remove-if-not but that's deprecated and if you use it your code smells.)
`remove-if-not` was deprecated before the Common Lisp standard was approved and yet it remained (and will never be removed because the standard will never be updated). That's not deprecated for any practical purpose. And it's more convenient than using `(remove-if (complement #'some-predicate) sequence)`
Scheme has `filter` and `filter-not` in the SRFI-1 list library. Both of which can easily be written using a fold to bring this vaguely on topic.
The filter keeps the tea... it's just that you then lift the filter out of the cup, carrying the tea with it. Flip your brain around to see it from that direction and it might help you with the mnemonics.
if you had parameter names maybe it might help?
`filter(where:)` like in swift...?
Doesn't seem to help the ambiguity to me.
Maybe those two could be filter_for (the “where” case) and filter_out.
Kotlin has filter and filterNot (it also has separate "reduce" and "fold" functions, dependingon whether you want to specify an initial accumulator value or not)
If you're making tea with a colander something is very wrong ;)
I was thinking an apt analogy might be making stock -- you filter out all the solid food you don't want to keep in the liquid.
And it's a doubly-good analogy, because I have occasionally gotten that confused in real-life as well. Twice in the past ten years I've had a stock boil away for three hours, and then set a colander in the sink and poured it through, only to watch my beautiful stock swirl down the drain because motor-memory made me forget that I wasn't draining pasta but should have put the colander in a bowl...
depends on the size of the sieve, but sometimes one does cook a whole stewpot of tea at once (f.e. in canteen)
> While map is a great name, I always struggle to remember if ‘filter’ keeps elements that match the condition or removes them.
In Common Lisp both functions exist, under the names `remove-if` and `remove-if-not`.
select/reject (Ruby)