Clojure Functions Guide — Defn, Anonymous Functions, Closures, and Higher-Order Patterns
In this tutorial, you will learn about Clojure Functions Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
Clojure functions are first-class values with defn (named), fn (anonymous), and #() reader macro -- supporting multi-arity dispatch, variadic arguments (& rest), destructuring in parameter lists, and closures over lexical scope.
Defining Functions
;; Named function
(defn greet [name]
(str "Hello, " name "!"))
;; Anonymous function
(fn [x] (* x x))
#(* % %) ;; reader macro version
;; Calling
(map (fn [x] (* x x)) [1 2 3]) ;; (1 4 9)
(map #(* % %) [1 2 3]) ;; same
Multi-arity
(defn greet
([] (greet "World"))
([name] (str "Hello, " name "!"))
([name title] (str "Hello, " title " " name "!")))
(greet) ;; "Hello, World!"
(greet "Alice") ;; "Hello, Alice!"
(greet "Smith" "Dr.") ;; "Hello, Dr. Smith!"
Variadic Functions
;; Variable arguments with &
(defn sum-all [& numbers]
(apply + numbers))
(sum-all 1 2 3 4 5) ;; 15
;; Fixed + variadic
(defn log [level & messages]
(println (str "[" level "] " (clojure.string/join " " messages))))
(log "INFO" "User" "logged" "in")
Destructuring
;; Sequential destructuring
(defn print-first [[x & rest]]
(println "First:" x))
;; Map destructuring
(defn describe [{:keys [name age]}]
(println name "is" age "years old"))
(describe {:name "Alice" :age 30})
;; Nested destructuring
(defn process [[a b] {:keys [x y]}]
(+ a b x y))
Closures
;; Closure: function captures lexical scope
(defn make-counter []
(let [count (atom 0)]
(fn []
(swap! count inc))))
(def counter (make-counter))
(counter) ;; 1
(counter) ;; 2
(counter) ;; 3
Common Mistakes
1. Missing parentheses
In Clojure, (f x) calls f with x. f x without parens is a syntax error. The parentheses are function call syntax.
2. Confusing fn with defn
fn creates an anonymous function. defn defines a named var. Don't use defn for inline lambdas.
3. Forgetting % in anonymous functions
#(* % %) has one arg (%). #(* %1 %2) has two. #(%) calls the first arg as a function.
Practice Questions
1. How do you define a named function?
(defn func-name [args] body). Returns the function in a var.
2. How do you write a two-argument anonymous function?
(fn [x y] (x y)) or #(%1 %2).
3. How do you handle variable numbers of arguments?
Use & in parameter list: (defn f [a b & rest] ...). Collects remaining args as a seq.
FAQ
{{< faq question="What is arity?" >}} The number of arguments a function accepts. Multi-arity functions have multiple definitions with different arg counts. {{< /faq >}}
{{< faq question="Can I recurse anonymously?" >}}
Yes, with recur (tail Recursion). Clojure doesn't have TCO for mutual recursion, but recur handles self-tail-calls.
{{< /faq >}}
{{< faq question="What is apply?" >}}
(apply f args) calls f with args spread as individual arguments. (apply + [1 2 3]) is (+ 1 2 3).
{{< /faq >}}
What's Next
Now learn about the sequence abstraction.
| Topic | Description | Link |
|---|---|---|
| Sequences | Sequence library | {{< ref "06-sequences" >}} |
| Macros | Macro programming | {{< ref "07-macros" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro