Scala collections: Does filter mean retain/keep, remove

As an update before getting into the original article (below), I’ve come to think of the Scala filter method being spelled as the British filtre, and then I think of this acronym, which helps me remember how filter/filtre works: “Find In List Then Retain Each.” So basically filter means retain.

I know that’s a little hokey, but it works for me. And now, here’s the original article:

As part of my personal ongoing battle with the meaning of the filter method in functional programming languages like Scala, I decided to create add a keep method to the Scala List class using the Scala 3 extension method approach, like this:

extension [A](xs: List[A])
    def keep(f: (A) => Boolean): List[A] = xs.filter(f)

That code defines a new method named keep that is now available on List class instances, so now I can use keep — rather than wondering what filter means:

val xs = List(1, 2, 3)     // List(1, 2, 3)
val ys = xs.keep(_ > 2)    // List(3)

A Twitter user asked if I could define keep higher up in the Scala sequence class hierarchy so it would be available on other sequences, and the answer is yes, you can define it on something like this Seq:

extension [A](xs: scala.collection.immutable.Seq[A])
    def keep(f: (A) => Boolean): Seq[A] = xs.filter(f)

After that you can continue to use it with List:

val xs = List(1, 2, 3)     // List(1, 2, 3)
val ys = xs.keep(_ > 2)    // List(3)

and you can also use keep with other sequences, like Vector:

val xs = Vector(1, 2, 3)   // Vector(1, 2, 3)
val ys = xs.keep(_ > 2)    // Vector(3)

It looks like the filter method is defined in the IterableOps type, so it might be best to define keep as an extension method on that type, but I haven’t looked into this in detail yet.