Clojure Cheat Sheet
Learn Clojure from the basics →
Basics
(f arg1 arg2)- Call a function (prefix notation)
(def rate 0.2)- Name a value in the namespace
(let [x 1 y (+ x 1)] (* x y))- Local bindings
42 3.14 1/3 42N 3.14M- Long, double, ratio, BigInt, BigDecimal
"text" \c :keyword 'symbol nil true- String, char, keyword, symbol, nil, boolean
(str "a" 1) / (format "%.2f" x)- Build and format strings
Collections
[1 2 3] / '(1 2 3)- Vector / list
{:name "Ada" :age 36} / #{:a :b}- Map / set
(conj coll x) / (assoc m :k v) / (dissoc m :k)- Add / set key / remove key (returns new)
(get m :k default) / (:k m)- Look up a key
(update m :count inc)- Apply a function to a value
(get-in m [:a :b]) / (assoc-in m [:a :b] v)- Nested read / write
(merge m1 m2) / (select-keys m [:a :b])- Combine / pick keys
Control Flow
(if test then else) / (when test ...)- Only false and nil are falsy
(cond (neg? n) "neg" (zero? n) "zero" :else "pos")- Multi-branch conditional
(case x 1 "one" (2 3) "few" "many")- Match constants
(or x default) / (and a b)- Defaults and short-circuiting
(loop [i 0] (when (< i 3) (recur (inc i))))- Loop with recur (no stack growth)
(doseq [x xs] (println x)) / (dotimes [i 3] ...)- Side-effecting loops
Functions
(defn greet "doc" [name] (str "Hi " name))- Define a function with a docstring
(fn [x] (* x x)) / #(* % %)- Anonymous function / shorthand
(defn f ([] (f 1)) ([x] x))- Multiple arities
(defn f [x & more] ...)- Variadic arguments
(partial f a) / (comp f g) / (juxt f g)- Build functions from functions
(apply f args)- Call with a collection as arguments
Sequences
(map f xs) / (filter pred xs) / (remove pred xs)- Transform and select (lazy)
(reduce + 0 xs)- Combine into one value
(->> xs (filter odd?) (map inc) (reduce +))- Thread-last pipeline
(-> m (assoc :a 1) (update :n inc))- Thread-first pipeline
(group-by :team people) / (frequencies xs)- Group / count
(sort-by :age > people) / (take 5 (range))- Sort by key / take from infinite seq
(into [] (comp (filter odd?) (map inc)) xs)- Transducer pipeline
Destructuring
(let [[a b & more] xs] ...)- By position, with rest
(let [{:keys [name age] :or {age 0}} m] ...)- Map keys with defaults
(defn f [{:keys [id]}] ...)- Destructure a parameter
(defn f [x & {:keys [port]}] ...)- Keyword arguments
State & Concurrency
(def a (atom 0)) / @a- Create and read an atom
(swap! a inc) / (reset! a 10)- Update with a function / set
(dosync (alter r1 - 5) (alter r2 + 5))- Coordinated change with refs (STM)
(future (work)) / @f / (deref f 100 :timeout)- Run on another thread
(go (>! ch v)) / (<!! ch)- core.async put in a go block / blocking take
Namespaces, Interop & Types
(ns app.core (:require [clojure.string :as str]))- Declare a namespace and require
(.toUpperCase s) / (Math/abs x) / (java.util.Date.)- Instance method, static method, constructor
(defprotocol Shape (area [s]))- Protocol (polymorphism on type)
(defrecord Point [x y]) / (->Point 1 2)- Record (a map with a type)
(defmulti area :shape) / (defmethod area :circle [s] ...)- Multimethod (dispatch on any value)
(try ... (catch Exception e (ex-message e)))- Handle exceptions
(throw (ex-info "msg" {:type :not-found}))- Throw an error with data