Clojure is simple, easy, fun, and very cool. Some have said that Clojure—or a language very much like it—is the future of programming languages.




Important and useful information about Clojure itself:

Cultural readings:


What is so great about Clojure being in the Lisp family?

Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot. —Eric S. Raymond

Getting Started

Install Clojure by downloading the latest version from the Clojure download page or use your favorite package manager (e.g., brew install clojure should just work on a Mac). Now you can:

Writing simple scripts

Make a file called hello.clj that looks like this:

(println "Hello, world")

And run it:

$ clojure -M hello.clj
Hello, world

Another simple script:

; This script prints all integer Pythagorean triples for values <= 100.

(doseq [c (range 1 101) b (range 1 c) a (range 1 b)]
  (if (= (+ (* b b) (* a a)) (* c c))
    (printf "(%d,%d,%d)\n" a b c)))
$ clojure -M triple.clj

Another simple script, this time using command line arguments:

; This script prints the gcd of its two command line arguments

(defn gcd [x y]
  (if (= y 0) x (gcd y (mod x y))))

    (read-string (first *command-line-args*))
    (read-string (second *command-line-args*))))
$ clojure -M gcd.clj 52 91

Using interactive mode

There is a cheap REPL:

$ clojure
$ user=> (+ 8 7)
$ user=> (/ 8 7)
$ user=> (type (/ 8 7))

Now try to hit the up arrow key to bring back the last command. Ooops. Or type a line and try using the right and left arrow keys. Pretty annoying, huh?


You'll want to use Leiningen to do anything with Clojure. Follow the instructions on its main project page on github for installation. Now you can fire off a repl using the lein script.

$ lein repl
user=> (/ 22 7.0)
user=> (* (/ 3 4) (/ 2 5))
user=> (defn fact [a] (if (<= a 1) 1 (* (fact (- a 1)) a)))
user=> (fact 40)
ArithmeticException integer overflow  clojure.lang.Numbers.throwIntOverflow
user=> (defn fact [a] (if (<= a 1N) 1N (* (fact (- a 1N)) a)))
user=> (fact 40)
user=> (type \k)
user=> (type :k)
user=> (type 'k)

Learning By Example

Here are few example evaluations in the REPL to get you warmed up. After you check these examples out, please go spend some time with the Cheatsheet and the Core QuickRef.


user=> (type 'k)
user=> (type k)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: k in
this context, compiling:(NO_SOURCE_PATH:1)

That's because things are evaluated: the value of `k is the symbol k, but when we just write k we mean the value associated with k. Confused yet? We would like to use recursion, but we all know the gt; (def k 5) #'user/k user=> 'k k user=> k 5


You'll recognize some of the numeric types from Java, but Clojure does add some new ones.

user=> (type 9)
user=> (type 9223372036854775807)
user=> (type 9223372036854775808)
user=> (type 579347593875938474772983477234283929398762781091283)
user=> (type 7N)
user=> 2.35E234
user=> (type 2.35E234)
user=> 2.35E999
user=> 2.35E999M
user=> (type 2.35E999M)


user=> (str "94" 2 6 " dogs")
"9426 dogs"
user=> (format "It was %d %s" 40 "degrees")
"It was 40 degrees"
user=> (count "привет")
user=> (subs "Hello" 2 4)
user=> (subs "I'm hungry" 4 7)
user=> (split "" #"\.")
CompilerException java.lang.RuntimeException: Unable to resolve symbol: split in this
context, compiling:(NO_SOURCE_PATH:1)
user=> (clojure.string/split "" #"\.")
["192" "168" "1" "1"]
user=> (use 'clojure.string)
user=> (split "" #"\.")
["192" "168" "1" "1"]


Clojure has four basic collection types:

Clojure collections are immutable and persistent. Adding or removing produces a new object, rather than mutating the collection. They use structural sharing, are efficient, and inherently thread-safe.

The following functions work on all collection types:


A Lists is a sequence in which count is Θ(1) and conj adds to the front.

Lists are immutable, of course:

user=> (def x (list 1 2 3 4 5))
user=> x
(1 2 3 4 5)
user=> (conj x 100)
(100 1 2 3 4 5)
user=> x
(1 2 3 4 5)

Please make a point to fully understand first, rest, and cons. They are part of Clojure's Lisp heritage (actually List uses the terms car, cdr, and cons, but that's just life).

user=> (def dogs (list 'sparky 'spot 'spike 'rex))
user=> (first dogs)
user=> (rest dogs)
(spot spike rex)
user=> (cons 'max dogs)
(max sparky spot spike rex)
user=> dogs
(sparky spot spike rex)


A Vector is a collection of values indexed by contiguous integers. The conj operation adds to the end.

user=> (def dogs ['sparky 'spot 'spike 'max])
user=> (type dogs)
user=> (count dogs)
user=> (conj dogs 'rex)
[sparky spot spike max rex]
user=> (peek dogs)
user=> (get dogs 2)


A Set is a collection of unique elements.

user=> (def dogs #{'sparky 'spot 'spike 'max})
user=> dogs
#{sparky max spot spike}
user=> (= dogs #{'spike 'max 'spot 'sparky})
user=> (conj dogs 'rex)
#{rex sparky max spot spike}
user=> (count dogs)
user=> (disj dogs 'sparky)
#{max spot spike}
user=> (contains? dogs 'spot)
user=> (contains? dogs 'sport)

There are hashed and sorted varieties of sets:

user=> (vec (hash-set 5 8 10 2 1 6 -5))
[1 2 -5 5 6 8 10]
user=> (vec (sorted-set 5 8 10 2 1 6 -5))
[-5 1 2 5 6 8 10]


A Map is a collection mapping keys to values.

user=> (def capitals {:ca "sacramento" :hi "honolulu" :ak "juneau"})
user=> (type capitals)
user=> capitals
{:ca "sacramento", :hi "honolulu", :ak "juneau"}
user=> (capitals :ca)
user=> (count capitals)
user=> (keys capitals)
(:ca :hi :ak)
user=> (type (keys capitals))

The assoc function returns a new map just like the original one except with one of the fields updated.

user=> (def dueDate {:month 12 :day 16 :year 2015})
user=> dueDate
{:month 12, :day 16, :year 2015}
user=> (assoc dueDate :day 26)
{:month 12, :day 26, :year 2015}
user=> dueDate
{:month 12, :day 16, :year 2015}
user=> (def lateDate (assoc dueDate :day 26))
Exercise: Learn how to create maps with hash-map, array-map, and sorted-map, and research the difference between these three kinds of maps.

Defining Functions

Function objects are introduced with fn:

user=> ((fn [x] (+ x x x)) 20)

Like any other value, you can bind a function to a name. This lets you call it through the name:

user=> (def triple (fn [x] (+ x x x)))
user=> (triple 2)

As a convenience you can use defn:

user=> (defn triple [x] (+ x x x))
user=> (triple 5)

There's even a shorter form, #(...) where parameters are called %1, %2, %3 and so one. (You can even use % for %1.)

user=> (def triple #(+ % % %))
user=> (triple 4)

The short form is very convenient for higher-order functions:

user=> (map #(* 3 %) '(1 2 3 4 5 6))
(3 6 9 12 15 18)
user=> (reduce #(+ (* 2 %1) %2) '(1 2 3 4 5 6))

Local Variables

user=> (defn energy [m] (let [c 299792458] (* m c c)))
user=> (energy 75)
user=> (defn bmi [pounds inches]
    [KILOGRAMS_PER_POUND 0.45359237
     METERS_PER_INCH 0.0254
     kilos (* pounds KILOGRAMS_PER_POUND)
     meters (* inches METERS_PER_INCH)
    (/ kilos (* meters meters))))
user=> (bmi 155 69)

Local Functions

user=> (letfn [
  #_=>   (sum [x y] (+ x y))
  #_=>   (half [x] (/ x 2))
  #_=> ]
  #_=> (half (sum 100 200)))


Structs are still around, but you should be using records instead.

user=> (defstruct point :x :y)
user=> (struct point 5 8)
{:x 5, :y 8}
user=> (defn makePoint
  ([] (struct point 0 0))
  ([x y] (struct point x y)))
user=> (def p (makePoint 6 8))
user=> (p :x)
user=> (:x p)

Technical Features

Persistent Data Structures

Clojure strives to make functional programming easier. One of the big things in functional programming is immutability. So Clojure’s data structures (at least almost all of them) are persistent. You don’t mutate them in place. Instead, you create a new data structure that is a modified version of the old one. This is done in a way that is efficient and doesn’t require copying the entire data structure.

Because the data structures are immutable, adding the string "cat" to a list of 50 dogs just tacks a node on the front:

(let [a (repeat 5 "dog") b (conj a "cat")] (list a b))


Protocols and Datatypes

A great introduction: Solving the Expression Problem

From the Clojure docs:

Iteration and Recursion

As a functional programming language, Clojure wants you to avoid mutable state as much as possible. How do you do this for simple loops, such as computing a factorial? We would like to use recursion, but we all know the classic recursive algorithm is not good:

; This isn't good!
(defn fact [n] (if (<= n 1) 1 (* (fact (- n 1)) n)))

It is bad because each recursive calls fills up the call stack with unevaluated forms:

fact 4
= 4 * fact 3
= 4 * (3 * fact 2)
= 4 * (3 * (2 * fact 1))
= 4 * (3 * (2 * (1 * fact 0)))
= 4 * (3 * (2 * (1 * 1)))
= 4 * (3 * (2 * 1))
= 4 * 3 * 2
= 4 * 6
= 24

It would be better to create a tail-recursive formulation. Let's make a little function called f that takes in two arguments, and use it as a helper. Like this:

; This is tail recursive so you would think it's good....
(defn fact [n]
      (f [i a] (if (<= i 1) a (f (dec i) (* i a))))
  (f n 1)))

How does this work? We would like to use recursion, but we all know the = f 8 1 = f 7 8 = f 6 56 = f 5 336 = f 4 1680 = f 3 6720 = f 2 20160 = f 1 40320 = f 40320

That is a neat little function! Notice that we are not mutating the variable i; we're making recursive calls. The binding of the argument to the parameter gives it the feel of updating i and a, but we're not really. FYI, the second variable a stands for "accumulator" because it is building up (accumulating) the result.

This function is tail recursive because it returns the result of a recursive call. So a good compiler and a good runtime system can evaluate this function as if it were a loop! Alas, the JVM cannot do this. So Clojure has loop and recur, to play the role of the inner function. You need to do it this way:

(defn fact [n]
  (loop [i n a 1]
    (if (<= i 1) a (recur (dec i) (* i a)))))

Here the inner recursive helper is replaced with a loop expression that initializes i to n and a to 1, then appears to "call itself," but it's really just repeating the "loop body" with updated values.

Keep in mind, however, that Clojure has lazy sequences and a wealth of powerful sequence operators. So you might actually do factorial this way:

defn factorial [n]
  (reduce * (range 1 (inc n)))

or even:

(defn factorial [n]
  (apply * (range 1 (inc n))))


From the documentation:

A seq is a logical list. ... Seqs differ from iterators in that they are persistent and immutable, not stateful cursors into a collection. As such, they are useful for much more than foreach - functions can consume and produce seqs, they are thread safe, they can share structure etc. ...

Most of the sequence library functions are lazy, i.e. functions that return seqs do so incrementally, as they are consumed.

Many of the functions in the seq library take one or more collections, call seq on them, and then operate on the resulting seq. In other words, many of these functions take collections but operate on their seqs.

Please see the the Clojure documentation page on sequences.


Looping through persistent data structures might generate a bit too much copying. In the middle of your operation, you might want do some mutation, but just in your little temporary world. Transients can speed up certain operations a lot. Read about them.

Here’s another example. Without transients:

(defn change [amount]
  (loop [values [25 10 5 1] remaining amount result []]
    (if (empty? values)
      (recur (rest values) (rem remaining (first values))
        (conj result (quot remaining (first values)))))))

Now with transients:

(defn change [amount]
  (loop [values [25 10 5 1] remaining amount result (transient [])]
    (if (empty? values)
      (persistent! result)
      (recur (rest values) (rem remaining (first values))
        (conj! result (quot remaining (first values)))))))
Exercise: Do a timing study for this little example.


Ah, macros.... Macros are what makes a Lisp Lisp. They are so cool we need to have a whole page describing them.

Basically a macro looks like a function but the arguments are not evaluated when the macro is called; they are passed to the macro as unevaluated forms. Then the macro may or may not evaluate them.

Here’s the reference.

But you will want to go deeper, so see the Macros chapter in Clojure for the Brave and True book. There’s also a special Learn X in Y Minutes page specifically for Clojure macros.

Interoperating with Java

See the Java interop page at for details.

Working with Clojure

The ecosystem is a big part of any major language. Here’s some of Clojure’s.

Unit Tests

(ns physics)

(defn energy [m]
  (let [c 299792458] (* m c c)))
(use 'physics)
(use 'clojure.test)

(deftest energy-test
  (is (= (energy 0) 0))
  (is (= (energy 1) 89875517873681764))
  (is (= (energy (/ 1 4)) 22468879468420441)))


Make sure to put the current directory (or whatever directory the source code is in) on your classpath.

$ java -cp clojure.jar:. clojure.main physicstest.clj

Or better, test with Leiningen.

Building Projects

Use Leiningen to set up, build, and deploy Clojure projects in much the same way you use Maven to manage your Java projects.


When defining functions, you can place a doc-string between the function name and the parameter vector, then refer to it later with doc, or use a documentation generator.

user=> (defn square "squares a number" [n] (* n n))
user=> (square 8)
user=> (doc square)
  squares a number


The libraries that are included with Clojure include:

clojure.core, clojure.core.async, clojure.core.protocols, clojure.core.reducers,,, clojure.inspector, clojure.instant,,,,,, clojure.main, clojure.math, clojure.pprint, clojure.reflect, clojure.repl, clojure.set, clojure.stacktrace, clojure.string, clojure.template, clojure.test, clojure.test.junit, clojure.test.tap, clojure.walk, clojure.xml,

These libraries are actually namespaces. Detailed information on these built-in libraries (namespaces) is at ClojureDocs. Also check out the “Other Included Libraries” documentation at

There are many contributed libraries whose names begin with clojure.contrib. Find information on the contributed libraries ClojureDocs's contrib page.

And More

Here’s the Awesome List.