The anonymous function is created by the
and has a short-hand of
#(...), or an anonymous function literal.
The simple syntax is:
(fn [params*] body)
defn creates a function and binds it to the specified name,
fn just creates a function. The created function can be bound to the name by the
(def my-plus (fn [coll] (.....))).
In this case, the anonymous function gets the name
Advice to coaches
Beginners may be confused by how to pass arguments to an anonymous function. Take time to explain how arguments are consumed by anonymous functions.
Let’s try anonymous functions.
Here is how we define an anonymous function:
(fn [coll] (filter even? coll))
here’s one way to use anonymous function
((fn [coll] (filter even? coll)) [1 2 3 4 5 6])
if we use #() literal, an anonymous function can be written like this:
(#(filter even? %) [1 2 3 4 5 6])
to use anonymous function more than once, bind it to a name:
(def evens (fn [coll] (filter even? coll))) (evens [1 2 3 4 5 6])
You may have thought that the function above is the equivalent to:
(defn evens-by-defn [coll] (filter even? coll)) (evens-by-defn [1 2 3 4 5 6])
However, Clojure programmers use anonymous function very often. Why do we need anonymous function?
The biggest reason is to use functions for higher-order-function
Higher-order Function ).
Another reason can been seen in the next example.
Let’s say we want to get the even numbers after two vectors are combined:
If we use def to save the value…
(defn evens-with-def [vec1 vec2] (def combined (concat vec1 vec2)) (filter even? combined)) (evens-with-def [1 2 3] [4 5 6])
combined is exposed outside of our function, and this is bug-prone.
But, if we use an anonymous function…
(defn evens-with-fn [vec1 vec2] ((fn [x] (filter even? x)) (concat vec1 vec2))) (evens-with-fn [1 2 3] [4 5 6])
There’s no variable for a combined vector.
We could also use
let, which provides lexical binding and limits it to within the scope.
(defn evens-with-let [vec1 vec2] (let [combined-in-let (concat vec1 vec2)] (filter even? combined-in-let))) (evens-with-let [1 2 3] [4 5 6])
combined-in-let is not exposed outside of our function:
Advice to coaches
The third example here doesn’t use anonymous functions. This would be a good example of how Clojure provides many ways to do the same thing.
Clojure, Special Forms
Clojure for the Brave and True, Do Things, 3.4 Anonymous Function