Skip to content

Clojure Functions Guide — Defn, Anonymous Functions, Closures, and Higher-Order Patterns

DodaTech Updated 2026-06-28 2 min read

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