Clojure Core Functions Guide — Essential Functions and Idiomatic Code
In this tutorial, you will learn about Clojure Core Functions Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
Clojure core functions enable functional composition and data transformation -- apply spreads collections as arguments, partial presets arguments, comp chains functions left-to-right, juxt applies multiple functions, and threading macros (->, ->>) create readable transformation pipelines.
Apply
;; Apply: spread collection as arguments
(apply + [1 2 3 4 5]) ;; 15 (like (+ 1 2 3 4 5))
(apply str ["a" "b" "c"]) ;; "abc"
(apply conj '() [1 2 3]) ;; (3 2 1)
;; With prepended args
(apply str "Prefix: " ["a" "b"]) ;; "Prefix: ab"
Partial and Comp
;; Partial: preset some arguments
(def add-five (partial + 5))
(add-five 10) ;; 15
(def greet (partial str "Hello, "))
(greet "Alice") ;; "Hello, Alice"
;; Comp: chain functions (right-to-left)
(def process (comp clojure.string/upper-case clojure.string/trim))
(process " hello ") ;; "HELLO"
;; Reverse order left-to-right
((comp inc *) 3 4) ;; 13 (first *, then inc)
Juxt and Complement
;; Juxt: apply multiple functions, collect results
(def stats (juxt min max mean))
(stats [1 2 3 4 5]) ;; [1 5 3]
;; Extract multiple fields
(def name-age (juxt :name :age))
(name-age {:name "Alice" :age 30}) ;; ["Alice" 30]
;; Complement: negate a predicate
(def not-empty? (complement empty?))
(not-empty? [1 2]) ;; true
(not-empty? []) ;; false
Threading Macros
;; Thread-first (->): insert as first arg
(-> (range 10)
(filter even?)
(map #(* % %))
(reduce +))
;; 120 (0^2 + 2^2 + 4^2 + 6^2 + 8^2)
;; Thread-last (->>): insert as last arg
(->> (range 10)
(filter even?)
(map #(* % %))
(reduce +))
;; Same result
;; Some-> : short-circuit on nil
(some-> nil inc str) ;; nil
(some-> 5 inc str) ;; "6"
Useful Combinators
;; constantly: always return same value
(map (constantly 0) [1 2 3]) ;; (0 0 0)
;; identity: return argument unchanged
(filter identity [1 nil 2 nil 3]) ;; (1 2 3)
;; fnil: supply default for nil args
(def safe-trim (fnil clojure.string/trim ""))
(safe-trim nil) ;; ""
Common Mistakes
1. Forgetting apply for variable-arg functions
(str ["a" "b"]) calls str with one argument (a vector). Use (apply str ["a" "b"]) to spread.
2. Confusing -> and ->>
(-> x (f y)) expands to (f x y). (->> x (f y)) expands to (f y x). Choose based on where the threaded value goes.
3. Overusing comp
(comp f g) applies g then f (right to left). This is the mathematical convention but can be confusing. Use -> threading for clarity.
Practice Questions
1. What does apply do?
(apply f coll) calls f with the elements of coll as individual arguments.
2. What does partial do?
(partial f arg1) returns a function that calls f with arg1 plus remaining args.
3. What is the difference between -> and ->>?
-> threads as the first argument. ->> threads as the last argument.
FAQ
{{< faq question="What is the threading macro?" >}}
-> and ->> insert a value into the next form, making deeply nested calls read linearly.
{{< /faq >}}
{{< faq question="What does juxt do?" >}} Takes multiple functions and returns a function that applies each to the argument and returns a vector of results. {{< /faq >}}
{{< faq question="What is fnil?" >}}
Creates a function that replaces nil arguments with defaults: (def safe-get (fnil get {})).
{{< /faq >}}
What's Next
Now learn about error handling in Clojure.
| Topic | Description | Link |
|---|---|---|
| Error Handling | Exception Handling | {{< ref "12-error-handling" >}} |
| Testing | Testing in Clojure | {{< ref "13-testing" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro