Clojure
Share your thoughts in the 2024 State of Clojure Survey!

Cheatsheet

Clojure 1.11 Cheat Sheet (v54)

Download PDF version / Source repo

Many thanks to Steve Tayon for creating it and Andy Fingerhut for ongoing maintenance.

Documentation

clojure.repl/ doc find-doc apropos dir source pst javadoc (foo.bar/ is namespace for later syms)

Primitives

Numbers

Literals Long: 7, hex 0xff, oct 017, base 2 2r1011, base 36 36rCRAZY BigInt: 7N Ratio: -22/7 Double: 2.78 -1.2e-5 BigDecimal: 4.2M
Arithmetic + - * / quot rem mod inc dec max min +' -' *' inc' dec' (1.11) abs
Compare == < > <= >= compare
Bitwise bit-and bit-or bit-xor bit-not bit-flip bit-set bit-shift-right bit-shift-left bit-and-not bit-clear bit-test unsigned-bit-shift-right (see BigInteger for integers larger than Long)
Cast byte short int long float double bigdec bigint num rationalize biginteger
Test zero? pos? neg? even? odd? number? rational? integer? ratio? decimal? float? (1.9) double? int? nat-int? neg-int? pos-int? (1.11) NaN? infinite?
Random rand rand-int
BigDecimal with-precision
Unchecked *unchecked-math* unchecked-add unchecked-dec unchecked-inc unchecked-multiply unchecked-negate unchecked-subtract

Strings

Create str format "a string" "escapes \b\f\n\t\r\" octal \377 hex \ucafe" See also section IO/to string
Use count get subs compare (clojure.string/) join escape split split-lines replace replace-first reverse index-of last-index-of (1.11) (clojure.core/) parse-boolean parse-double parse-long parse-uuid
Regex #"pattern" re-find re-seq re-matches re-pattern re-matcher re-groups (clojure.string/) replace replace-first re-quote-replacement Note: \ in #"" is not escape char. (re-pattern "\\s*\\d+") can be written #"\s*\d+"
Letters (clojure.string/) capitalize lower-case upper-case
Trim (clojure.string/) trim trim-newline triml trimr
Test string? (clojure.string/) blank? starts-with? ends-with? includes?

Other

Characters char char? char-name-string char-escape-string literals: \a \newline (more at link)
Keywords keyword keyword? find-keyword literals: :kw :my.name.space/kw ::in-cur-namespace ::namespace-alias/kw
Symbols symbol symbol? gensym literals: my-sym my.ns/foo
Misc literals: true false nil

Collections

Collections

Generic ops count empty not-empty into conj (clojure.walk/) walk prewalk prewalk-demo prewalk-replace postwalk postwalk-demo postwalk-replace (1.9) bounded-count
Content tests distinct? empty? every? not-every? some not-any?
Capabilities sequential? associative? sorted? counted? reversible?
Type tests coll? list? vector? set? map? seq? record? map-entry?

Lists (conj, pop, & peek at beginning)

Create () list list*
Examine first nth peek .indexOf .lastIndexOf
'Change' cons conj rest pop

Vectors (conj, pop, & peek at end)

Create [] vector vec vector-of mapv filterv
Examine (my-vec idx)( nth my-vec idx) get peek .indexOf .lastIndexOf
'Change' assoc assoc-in pop subvec replace conj rseq update update-in
Ops reduce-kv

Sets

Create unsorted #{} set hash-set
Create sorted sorted-set sorted-set-by (clojure.data.avl/) sorted-set sorted-set-by (flatland.ordered.set/) ordered-set (clojure.data.int-map/) int-set dense-int-set
Examine (my-set item)( get my-set item) contains?
'Change' conj disj
Set ops (clojure.set/) union difference intersection select See also section Relations
Test (clojure.set/) subset? superset?
Sorted sets rseq subseq rsubseq

Maps

Create unsorted {} hash-map array-map zipmap bean frequencies group-by (clojure.set/) index
Create sorted sorted-map sorted-map-by (clojure.data.avl/) sorted-map sorted-map-by (flatland.ordered.map/) ordered-map (clojure.data.priority-map/) priority-map (flatland.useful.map/) ordering-map (clojure.data.int-map/) int-map
Examine (my-map k)( get my-map k) also (:key my-map)( get my-map :key) get-in contains? find keys vals
'Change' assoc assoc-in dissoc merge merge-with select-keys update update-in (clojure.set/) rename-keys map-invert (1.11) (clojure.core/) update-keys update-vals GitHub: Medley
Ops reduce-kv
Entry key val
Sorted maps rseq subseq rsubseq

Queues (conj at end, peek & pop from beginning)

Create clojure.lang.PersistentQueue/EMPTY (no literal syntax or constructor fn)
Examine peek
'Change' conj pop

Relations (set of maps, each with same keys, aka rels)

Rel algebra (clojure.set/) join select project union difference intersection index rename

Transients (clojure.org/reference/transients)

Create transient persistent!
Change conj! pop! assoc! dissoc! disj! Note: always use return value for later changes, never original!

Misc

Compare = identical? not= not compare clojure.data/diff
Test true? false? instance? nil? some?

IO

to/from ... spit slurp (to writer/from reader, Socket, string with file name, URI, etc.)
to *out* pr prn print printf println newline (clojure.pprint/) print-table
to writer (clojure.pprint/) pprint cl-format also: (binding [*out* writer] ...)
to string format with-out-str pr-str prn-str print-str println-str
from *in* read-line (clojure.edn/) read (clojure.tools.reader.edn/) read
from reader line-seq (clojure.edn/) read (clojure.tools.reader.edn/) read also: (binding [*in* reader] ...) java.io.Reader
from string with-in-str (clojure.edn/) read-string (clojure.tools.reader.edn/) read-string
Open with-open (clojure.java.io/) text: reader writer binary: input-stream output-stream
Binary (.write ostream byte-arr) (.read istream byte-arr) java.io.OutputStream java.io.InputStream GitHub: gloss byte-spec
Misc flush (.close s) file-seq *in* *out* *err* (clojure.java.io/) file copy delete-file resource as-file as-url as-relative-path GitHub: fs
Data readers *data-readers* default-data-readers *default-data-reader-fn*
tap (1.10) tap> add-tap remove-tap

Abstractions (Clojure type selection flowchart)

Protocols (clojure.org/reference/protocols)

Define ( defprotocol Slicey (slice [at]))
Extend ( extend-type String Slicey (slice [at] ...))
Extend null ( extend-type nil Slicey (slice [_] nil))
Reify ( reify Slicey (slice [at] ...))
Test satisfies? extends?
Other extend extend-protocol extenders

Records (clojure.org/reference/datatypes)

Define ( defrecord Pair [h t])
Access (:h (Pair. 1 2))1
Create Pair. ->Pair map->Pair
Test record?

Types (clojure.org/reference/datatypes)

Define ( deftype Pair [h t])
Access (.h (Pair. 1 2))1
Create Pair. ->Pair
With methods ( deftype Pair [h t]
  Object
  (toString [this] (str "<" h "," t ">")))

Multimethods (clojure.org/reference/multimethods)

Define ( defmulti my-mm dispatch-fn)
Method define ( defmethod my-mm :dispatch-value [args] ...)
Dispatch get-method methods
Remove remove-method remove-all-methods
Prefer prefer-method prefers
Relation derive underive isa? parents ancestors descendants make-hierarchy

Datafy (article)

Datafy (clojure.datafy/) datafy nav

Special Characters (clojure.org/reference/reader, guide)

, Comma reads as white space. Often used between map key/value pairs for readability.
' quote: 'form( quote form)
/ Namespace separator (see Primitives/Other section)
\ Character literal (see Primitives/Other section)
: Keyword (see Primitives/Other section)
; Single line comment
^ Metadata (see Metadata section)
*foo* 'earmuffs' - convention to indicate dynamic vars, compiler warns if not dynamic
@ Deref: @form( deref form)
` Syntax-quote
foo# 'auto-gensym', consistently replaced with same auto-generated symbol everywhere inside same `( ... )
~ Unquote
~@ Unquote-splicing
-> 'thread first' macro ->
->> 'thread last' macro ->>
>!! <!! >! <! core.async channel macros >!! <!! >! <!
( List literal (see Collections/Lists section)
[ Vector literal (see Collections/Vectors section)
{ Map literal (see Collections/Maps section)
#' Var-quote: #'x( var x)
#" #"p" reads as regex pattern p (see Strings/Regex section)
#{ Set literal (see Collections/Sets section)
#( Anonymous function literal: #(...)(fn [args] (...))
% Anonymous function argument: %N is value of anonymous function arg N. % short for %1. %& for rest args.
#? Reader conditional: #?(:clj x :cljs y) reads as x on JVM, y in ClojureScript, nothing elsewhere. Other keys: :cljr :default
#?@ Splicing reader conditional: [1 #?@(:clj [x y] :cljs [w z]) 3] reads as [1 x y 3] on JVM, [1 w z 3] in ClojureScript, [1 3] elsewhere.
#foo tagged literal e.g. #inst #uuid
#: map namespace syntax e.g. #:foo{:a 1} is equal to {:foo/a 1}
## (1.9) symbolic values: ##Inf ##-Inf ##NaN
$ JavaContainerClass$InnerClass
foo? conventional ending for a predicate, e.g.: zero? vector? instance? (unenforced)
foo! conventional ending for an unsafe operation, e.g.: set! swap! alter-meta! (unenforced)
_ conventional name for an unused value (unenforced)
#_ Ignore next form

Metadata (clojure.org/reference/reader, special_forms)

General ^{:key1 val1 :key2 val2 ...}
Abbrevs ^Type^{:tag Type}
^:key^{:key true}
Common ^:dynamic ^:private ^:doc ^:const
Examples (defn ^:private ^String my-fn ...)
(def ^:dynamic *dyn-var* val)
On Vars meta with-meta vary-meta alter-meta! reset-meta! doc find-doc test

Loading

Load libs (tutorial) require use import refer
List loaded loaded-libs
Load misc load load-file load-reader load-string