A higher-order function is:
In other languages, this feature may have another name. For example, Ruby names it block for a callee function, although the caller doesn’t have specific name.
Before going to those core functions, let’s try the example below. This example is the first type of higher-order function. In this example, we will create a function that does something when given two vectors.
Advice to coaches
concat-evens function is the same example in
If the attendees haven’t looked at the Anonymous Function section and they struggle to understand the example, go back to the Anonymous Function section.
Suppose we want to combine two vectors and take even numbers out:
(defn concat-evens [vec1 vec2] ((fn [x] (filter even? x)) (concat vec1 vec2))) (concat-evens [1 2 3] [4 5 6])
Suppose we want to combine two vectors and take odd numbers out:
(defn concat-odds [vec1 vec2] ((fn [x] (filter odd? x)) (concat vec1 vec2))) (concat-odds [1 2 3] [4 5 6])
Let’s see: the difference of two functions above is just
odd?. What if either
odd? function would be passed as an argument?
(defn concat-some [f vec1 vec2] ((fn [x] (filter f x)) (concat vec1 vec2))) (concat-some even? [1 2 3] [4 5 6])
(concat-some odd? [1 2 3] [4 5 6])
Yay! we created a higher-order function:
concat-some takes a function as an argument.
As we saw above, higher-order functions are a useful way to make functions more generic.
Let’s try one more example. This example is the second type of higher-order function.
Advice to coaches
partial function may be difficult to undertand/use for beginners.
It would be good to use other examples, (partial * 2), to explain.
(defn greeting-in-am [who] (str "Good morning, " who)) (greeting-in-am "everybody")
(defn greeting-in-pm [who] (str "Good afternoon, " who)) (greeting-in-pm "everybody")
(defn greeting-anytime [who] (str "Hello, " who)) (greeting-anytime "everybody")
Let’s see: the difference between the three functions above is
only the first argument of
str. Can we create a generalized function?
(defn greeting [when] (case when :am (partial str "Good morning, ") :pm (partial str "Good afternoon, ") (partial str "Hello, "))) (fn? (greeting :am))
As you can see,
greeting returns a function!
Now, let’s see it in action.
((greeting :am) "everybody, " "nobody, " "whoever")
((greeting :pm) "Andy, " "Bob, " "Charlie, " "David")
With anything else:
((greeting :hm...) "Ann, " "Beth")
With a single
greeting function, we cover the three functions previously defined. Additionally, now, we can pass any number of arguments. Everything other than :am and :pm falls on the last “Hello, “.
PCL -> Clojure, Chapter 11, Higher-order functions