How to define and use functions in Clojure: arities, anonymous functions, variadic args, destructuring, and apply.
Functions are Clojure’s unit of composition. If you’re used to Java, think: a function is like a static method that you can pass around as a value.
defn1(defn greet
2 "Returns a greeting string."
3 ([name] (str "Hello, " name "!"))
4 ([] (greet "world")))
5
6(greet "Ada") ; => "Hello, Ada!"
7(greet) ; => "Hello, world!"
Notes that matter in real code:
fn and #()Prefer fn when the function is more than a one-liner:
1(map (fn [n] (* n n)) [1 2 3])
2;; => (1 4 9)
Use #() for short transforms:
1(map #(* % %) [1 2 3])
2(map #(+ %1 %2) [1 2] [10 20])
3;; => (11 22)
applyUse & to accept “the rest” of the arguments:
1(defn sum [& xs]
2 (reduce + 0 xs))
Use apply when you have arguments in a collection:
1(apply + [1 2 3]) ; => 6
Map destructuring pulls keys out directly, and :or lets you supply defaults:
1(defn area [{:keys [w h] :or {w 0 h 0}}]
2 (* w h))
3
4(area {:w 3 :h 4}) ; => 12
5(area {:w 3}) ; => 0
Vector destructuring is useful when a parameter is “position-based”:
1(defn first-two [[a b]] [a b])
1(defn make-adder [n]
2 (fn [x] (+ x n)))
3
4(def add10 (make-adder 10))
5(add10 5) ; => 15