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.