Introduction to Clojure

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.



The current production version is 1.4.


Important and useful information about Clojure itself

Cultural readings


Getting Started

First, you'll need to install Java 1.5 or above and download the Clojure jar file. Then, as with most languages, you can use Clojure in two ways:

Actually, there is an alternate approach to all this we'll see after you learn how to do things the hard way.

Writing simple scripts

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

(println "Hello, world")

To run this script (assuming the clojure jar is named clojure.jar and is in the current directory — if not, you'll probably figure out what to do):

$ java -cp clojure.jar clojure.main 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)))
$ java -cp clojure.jar clojure.main triple.clj

Another simple script, this time using commandline 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*))))
$ java -cp clojure.jar clojure.main gcd.clj 42 96

Using interactive mode

$ java -cp clojure.jar clojure.main
$ 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? Okay this may help:

user=> (def k 5)
user=> 'k
user=> k


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)

Cool Stuff

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? You should not be creating a variables! THAT WOULD BE JUST SO WRONG.

But 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? Let's just do the evaluation:

fact 8
= 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 "accumuator" 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. Check this out:

(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.


Transients can speed up certain operations a lot. Read about them.


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.

Read about them.

Interoperating with Java

See the Java interop page at for details.

Working with Clojure

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.inspector,,,,,, clojure.main, 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. In this sense, clojure.core is a library too. Detailed information on these built-in libraries (namespaces) is at the Clojure API Overview page or at ClojureDocs. Also check out the built-in library documentation at

There are also a large number of contributed libraries whose names begin with clojure.contrib.

Find information on the contributed libraries ClojureDocs's contrib page.


The Clojure Beginner's Guide by John Gabriele has a number of very useful links (including videos) where you can get more information — as well as help from the Clojure community.