Lesser known Clojure every-pred and some-fn functions


The common thing in functional programming is combining “smaller” functions into the bigger one (higher-order functions). The examples of such functions are every-pred and some-fn. Both those functions were added to Clojure in release 1.3.

every-pred

The available signatures of this function are:

(every-pred p)
(every-pred p1 p2)
(every-pred p1 p2 p3)
(every-pred p1 p2 p3 & ps)

where p, p1, p2 and so on are predicate functions (functions that returns true or false).
The result of every-pred is a function that can take many arguments. This newly created function returns true, if and only if all its composing predicates return true for every argument. It is also worth knowing that created function will stop its execution at first argument that causes that one of given predicates return false.

Let’s look at few examples:

(every-pred string? clojure.string/blank?)
=> #object[clojure.core$every_pred$epn__6900 0x545865df "clojure.core$every_pred$epn__6900@545865df"]

as we can see a new function was created (we pass two functions string? and blank? to it).

((every-pred string? clojure.string/blank?) " " "     " "\t")
=> true

because every argument is a string and it’s blank, returned value is true.

((every-pred string? clojure.string/blank?) " " "     " "sample text")
=> false

one of the passed argument is "sample text" (not a blank string) so the end result is false.

We can use apply function to invoke result of every-pred an a list or a vector:

(apply (every-pred string? clojure.string/blank?) '(" " "     " "            "))
=> true

some-fn

We can say, that some-fn is a sibling function to every-pred function. It has the same signature:

(some-fn p)
(some-fn p1 p2)
(some-fn p1 p2 p3)
(some-fn p1 p2 p3 & ps)

and also returns a function that can take many arguments. The difference is that resulting function (created by invocation of some-fn) returns true when at least one of a given predicates returns true for any arguments. This function stops its execution at the first argument for which one of the specified predicates returns true. Let’s look at few examples:

((some-fn #(< % 5) #(> % 10)) 6 15 7 8)
=> true

argument 15 meets condition #(> % 10) so the whole expression returns true.

((some-fn #(< % 5) #(> % 10)) 6 7 8)
=> false

every argument is bigger then 5 and smaller then 10 so the form returns false.

Knowing those functions isn’t necessary to work efficient with Clojure, but for sure can make your code more idiomatic and nice to read.


You may also like

Lesser known Clojure: variants of threading macro

ClojureScript: JavaScript Interop

Template method pattern