[Proposal] Add Enum.select as alias for Enum.filter

65 views
Skip to first unread message

Michael Neumann

unread,
Feb 3, 2024, 1:56:07 AMFeb 3
to elixir-lang-core
Hi,

I am proposing to add Enum.select as an alias for Enum.filter.

Why? In my native language (German), when we talk about "filtering", its exact meaning can be context dependent:

- Water filter - Filters substances out of unclean water. (rejects all but water)
- Particle filter - Rejects particles from a gas. Sometimes also called an "air filter"
- Coffee drip filter - Rejects the coffee powder

So it's not always clear what the filter rejects or selects. A particle filter, rejects particles, while a water filter selects water (it actually does not filter water, but dirty water). We also use the verb "to filter out" (herausfiltern), which has the opposite meaning of "to filter".
  • This ambiguity in my native language, which likely also applies to English, makes my brain sometimes spend unnecessary cycles. Dunno if it's just me.
  • Coming from Ruby, select seems to be a natural choice
  • While we have  Enum.reject, it's natural counterpart Enum.select is missing.
IMHO:

[:water, :bacteria] |> Enum.select(& &1 == :water)

has higher chances to be understood well by beginners over:

[:water, :bacteria] |> Enum.filter(& &1 == :water)

Regards,

  Michael

Andrew Timberlake

unread,
Feb 3, 2024, 3:06:13 AMFeb 3
to elixir-lang-core
I doubt an alias will be accepted.

What’s interesting is that Javascript doesn’t have select or reject, but only filter.
Filter actually works exactly like you say it does in language (both German and English)

<what I want> = Enum.filter(& &1 == <select>)
<what I want> = Enum.filter(& &1 != <reject>)

Just an observation

—Andrew

  Michael -- 
 You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
 To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/28f58f84-7666-4609-89a1-81d8835a0551n%40googlegroups.com.

Nick West

unread,
Feb 3, 2024, 3:24:28 AMFeb 3
to elixir-l...@googlegroups.com
On the semantic side, I respectfully disagree with Andrew that filter is clearly filter out or filter in, in common usage in both English and in German filter can easily imply either action in either direction, e.g. selection or removal (source: am native english speaker with english degree, german as second language). 

I’ve found filter to be a flimsy word in both JS and Elixir, am mildly relieved to find I’m not the only one


José Valim

unread,
Feb 3, 2024, 3:25:58 AMFeb 3
to elixir-l...@googlegroups.com
Correct, Elixir rarely adds aliases, because it adds to the learning curve (and Enum is already a large module) and it also eventually becomes a struggle for consistency (this code base must “only use select” or “only use filter”).

Plus I personally dislike select because it partially conflicts with SQL, where it may read as filtering columns from a table but it is also as a mechanism to perform transformations akin to map. I believe some programming languages do provide a select with the same meaning as map, so it would add to the confusion.

Andrew Timberlake

unread,
Feb 3, 2024, 3:48:33 AMFeb 3
to elixir-lang-core
I didn’t mean it was clearly out or clearly in, but covers both and you can use the same function whichever way you want it to work.

—Andrew

Billy Lanchantin

unread,
Feb 3, 2024, 1:39:45 PMFeb 3
to elixir-lang-core
Also worth noting, `filter` has a long history of use and is common in functional languages:


I agree that the common meaning of filter in English (and German, apparently) clashes somewhat with its use in functional languages. It was a stumbling point for me too. But it's the classic trade-off of "what people have grown accustomed to" vs. "what a newcomer might find intuitive".

Ideally, Elixir is easy to pick up for both first-time functional language users and those who already have some experience.

Michael Neumann

unread,
Feb 3, 2024, 8:58:44 PMFeb 3
to elixir-l...@googlegroups.com
Whether my proposal will be accepted or rejected... or shall I say, whether my proposal will be filtered or filtered out... :)

Airfilter:
air w/o particles = Enum.filter(& &1 == "air")

Particle filter:
particles = Enum.filter(& &1 == "particles")

Technically, in both cases, particles stay in the filter sieve, and in both cases this is the residue (unwanted stuff). But , we actually don't want the particles :).

I'll give you another exam:

University exams are often used to filter out unqualified students. In natural language we would say that we reject (or filter out) 
every student with a score below X. We would not say that we filter students with a score above X, or would we? At least in Germany, we always filter out
students :). Or we would say that we select (or accept) the best students, those with a score above X.

IMHO, filter is a bad naming for what it does when coupled with booleans. If the filter condition would return either :keep or :pass, it would be obvious. 



Austin Ziegler

unread,
Feb 3, 2024, 9:40:15 PMFeb 3
to elixir-l...@googlegroups.com
On Sat, Feb 3, 2024 at 8:58 PM Michael Neumann <michae...@gmail.com> wrote:
IMHO, filter is a bad naming for what it does when coupled with booleans. If the filter condition would return either :keep or :pass, it would be obvious. 

Regardless of your opinion on the name for this concept (I have no strong feeling either way), the ship has sailed for most languages. RosettaCode's page for this is called…Filter: https://rosettacode.org/wiki/Filter

There are various names for this:
  • remove-if-not (Common Lisp)
  • filter (Clojure)
  • seq-filter (Elisp)
  • lists:filter (Erlang)
  • List.filter (F#)
  • Array.prototype.filter (JS)
  • select (jq)
  • filter (Kotlin)
  • grep (Perl)
  • findall (Prolog)
  • filter (Python, but list comprehensions are more idiomatic)
  • select (Ruby)
  • filter or retain (Rust)
The most *common* name that I saw in the entries was filter or some variation.

-a
--

Michael Neumann

unread,
Feb 3, 2024, 9:43:23 PMFeb 3
to elixir-l...@googlegroups.com
True, SQL uses it in a slightly different way and that might be confusing for someone.  In this case Enum.accept would be the better choice, or Enum.keep_if.

How do you teach that Enum.filter is the opposite of Enum.reject instead of Enum.accept?

I doubt that adding e.g. Enum.accept would have any impact on the learning curve, rather the opposite, unless we continue to add more and more aliases for basically the same thing. In Ruby, there is:
filter, find_all, select, keep_if that more or less do the same, plus reject :).

True, there would be yet another way to do filtering.

Consistency: Yes, people might start using Enum.accept where they would  have used Enum.filter before
I'd argue that it could look more consistent in certain cases, where both filter and reject are used to condense an enumeration:

[1,2,3]
|> Enum.filter(& &1 > 2)
|> Enum.reject(& ...)

vs.

[1,2,3]
|> Enum.accept(& &1 > 2)
|> Enum.reject(& ...)

 TBH, I don't like Enum.accept that much in the example above :/.




Michael Neumann

unread,
Feb 3, 2024, 10:08:25 PMFeb 3
to elixir-l...@googlegroups.com
So languages clearly favor filter.

  • Ruby has filter, too, and I think the name "filter" comes in handy when you want to do a filter+map in one operation: filter_map.
  • Rust's retain does not operate on an Iterator, but is a special in-place "filter" for Vec-tors, similar to Ruby's keep_if.
  • Haskell and Ocaml both use filter, too.
  • C#: List.FindAll or LINQ ("SQL"): where clause.
  • Go: Seems to have no built-in functionality for "filter". Libraries tend to prefer "Filter" as name. Rob Pike actually has a library called filter (https://pkg.go.dev/robpike.io/filter) that uses Choose. IMHO, good name :)

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

Jon Rowe

unread,
Feb 4, 2024, 6:29:39 AMFeb 4
to Elixir Lang Core
FWIW the Wikipedia definition for "Filter" (higher order function) backs up the usage here too:

In functional programming, filter is a higher-order function that processes a data structure (usually a list) in some order to produce a new data structure containing exactly those elements of the original data structure for which a given predicatereturns the boolean value true.

As a former (sometimes current) Rubyist I too reach for select at times, but honestly I think the usage of filter is well undersood in general.
Reply all
Reply to author
Forward
0 new messages