A Concise Guide to Clojure
Copyright ©2011, David Matuszek

The original version of this page was based on http://lifeofaprogrammergeek.blogspot.com/2009/03/learning-clojure-and-emacs.html.


Clojure is a modern variant of Lisp-1. The following comparisons are to the "original" Lisp.

To run Clojure, enter: java -cp clojure-1.6.0.jar clojure.main (Substitute your version number).

Basic data types

Numbers: Clojure has integers, floating point numbers, and ratios.

Atoms (variables): Names for values. Clojure allows most non-alphanumeric characters in names (but not parentheses, brackets, or braces).

Important atoms: true, false, and nil. In a condition, nil behaves like false; but nil is not equal to an empty list, ().

Strings are enclosed in double quotes, and can contain escaped characters: "hello", "line one\nline two".

Regular expressions are written as a hash character in front of a string: #"[a-z]+". Backslashes do not need to be doubled.

Keywords are not reserved words (like while in Java), but are like "atoms" in Prolog or Erlang. A keyword begins with a colon (:foo) and stands for itself. Keywords are often used as keys in maps.

A list is a sequence of values, separated by whitespace (including commas) and enclosed in parentheses.

A vector is a sequence of values enclosed in brackets, for example [1 2 "buckle my shoe"], or equivalently, (vector 1 2 "buckle my shoe"). Elements of a vector are separated by whitespace, including commas. Vectors are used to enclose the formal parameters of a function.

A map or hash is a sequence of key/value pairs, enclosed in braces, for example, {:ace 1, :deuce 2, "trey" 3}. Elements are separated by whitespace or commas; it is helpful to use commas between key/value pairs.

A set is a pound sign (#) followed sequence of values enclosed in braces, for example #{a b c}.

Clojure has functions, special forms, and macros.

Functions are first-class objects. That is, a function is a value, and can be treated like other kinds of values. Functions can be assigned to variables, passed as parameters to functions, returned as the result of functions, and kept in collections, and there are operations that act on functions. Special forms and macros are not first-class objects.

Comments begin with a semicolon and extend to the end of the line.

Defining and calling functions

The syntax of a named function is: (defn function_name [arguments] expressions). The value of the function is the value of the last expression evaluated.

Parameters may be "deconstructed" (this is akin to pattern matching). For example, if an argument must have the form [a b], the formal parameter may be [x y].

A function may be defined to evaluate different expressions based on the number of arguments. The syntax is (defn function_name ([arguments] expressions) ... ([arguments] expressions)), where each list of arguments is a different length.

A function may be defined to accept an arbitrary number of arguments. The syntax is (defn function_name [arguments & last-argument] expressions). The arguments before the ampersand are as usual; the one last-argument is given to the function as a list of all remaining arguments.

A documentation string may be placed immediately before the vector of arguments. The function (doc function-name) will print out this documentation string, along with other information about the function. doc can be used with built-in functions.

The syntax of a function call is (function_name arguments). The name of the function being called is the first thing inside the parentheses.

The syntax of an anonymous function, or lambda, is (fn [arguments] expressions). This syntax can be used in place of a function name; for example, ((fn [lst] (first lst)) my-list) is equivalent to (first my-list).

Built-in functions

Notation: A + suffix on an argument means "one or more"; a * suffix means "zero or more"; and a ? suffix means "zero or one", that is, optional.

Absolutely fundamental functions

(first sequence)
Returns the first element of a nonempty sequence, or nil if the sequence is empty. For "unordered" collection types, such as sets, some element will be returned, based on how the collection is stored in memory.
(rest sequence)
Returns a list containing all the elements of the given sequence but the first, or () if the given sequence is empty.
(cons value sequence)
Returns a new list created by adding the value as the first element of the given sequence.
(conj sequence value...)
Returns a new sequence created by adding the values to the given sequence. Values will be added to the beginning of a list or to the end of a vector.
(empty? sequence)
Returns true if the sequence is empty, and false otherwise.
(= value1 value2)
Tests whether two values are equal. Works for just about anything except functions.

Additional functions

(concat sequence*)
Concatenates the sequences into a single list. Example: (concat [1 2 3] [5 6] [9]) ;=> (1 2 3 5 6 9)
(apply function arg* sequence)
Equivalent to (function (concat arg* sequence)). Example: (apply + 1000 100 '(1 2 3)) ;=> 1106
(frequencies sequence)
Returns a map from distinct items in sequence to the number of times they appear.

Macros and special forms

Macros and special forms differ from functions in that the arguments are not evaluated before the special form is called. They can then decide whether, when, and how often to evaluate the arguments. There is little difference from the user's point of view; but new macros can be written by the programmer.

(quote argument)
Returns its argument, unevaluated.
(def name expression)
Defines the name to have the value of the expression, in the current namespace. Clojure is single-assignment: Names cannot be reassigned to have a different value (except in the REPL).
(if test thenPart elsePart?)
The test is evaluated; if it is a "true" value, the thenPart is evaluated; if it is a "false" value and there is an elsePart, the elsePart is evaluated. This special form is convenient for simple tests, but for multiway tests, cond is preferable.
(when test expression ... expression)
If the test evaluates to a true value, the expressions are evaluated, and the value of the last expression is returned.
(cond test expression ... test expression)
The tests are evaluated in order, until one is found that results in a "true" value; then the corresponding expression is evaluated and returned as the value of the cond. If no test is true, nil is returned.
(do exprs*)
Evaluates the expressions in order and returns the value of the last. If no expressions are supplied, returns nil.
(let [name value ... name value] expressions*)
Defines local names, evaluates the corresponding values, and binds them to the names. The names are then available in the expressions, which are evaluated in order. The value of the let is the value of the last expression evaluated.
(throw expression)
The expression must evaluate to some kind of Throwable, which is then thrown.
(try expressions* catch-clauses* finally-clause?)
Evaluates the expressions. If no exceptions occur and the finally-clause is omitted, the result of the last expression is returned. If an exception occurs, then the corresponding catch-clause, with the syntax (catch ExceptionName name expressions*), is evaluated and returned. If there is a finally-clause, with the syntax (finally expressions*), then whether or not an exception occurs, it will be evaluated for its side effects.
(recur expressions*)
Performs a recursive call from the tail position (see Tail Recursion), with the exact (not arbitrary) number of arguments.
(loop [bindings*] expressions*)
Like recur, but the recursion point is at the top of the loop.

Functions for specific data types

Characters and strings

Clojure depends on Java for almost all character and string manipulations, for example, (.toUpperCase string) and (Character/toUpperCase char).

(str arguments*)
Converts any number of arguments into strings and concatenates them; ignores any nil argument. Also useful if the arguments are already strings.
(read-string string)
Reads one object from the given string; returns nil if the string is empty.


A vector is a sequence of values enclosed in brackets.

Maps (also known as hashes)

A map or hash is a sequence of key/value pairs, enclosed in braces. The primary operation is searching a map for a given key, and returning its value. This can be done by using either the map or a key as a function, or the function get.

(map key)
(key map)
(get map key)
(get map key default-value)
Each of these looks up the key in the map, and returns the associated value. If the key does not occur in the map, the first and third forms return nil, while the third form gives an error and the fourth form returns the default-value.
(keys map)
Returns a list of the keys.
(vals map)
Returns a list of the values.
(contains? map key)
Tests whether the key is in the map.


A record definition is something like a Java class. It acts as a map but, because the "fields" are predefined, it can be more efficient.


Records are newer and better than structs. Don't use structs.


Numeric comparisons


Higher-order functions

A higher-order function is one that accepts a function as an argument, returns a function as its result, or both.

List comprehensions


Metaprogramming is using a program to write a program (or parts of a program). Metaprogramming is especially in a homoiconic language, that is, a language in which code and data have the same representation. Clojure is homoiconic.

A Clojure macro resembles a function, with these important differences:

The following examples are from Practical Clojure by Luke VanderHart and Stuart Sierra.

(defmacro triple-do [form] ; makes three copies of the form
    (list 'do form form form) )

The call (triple-do (print "Hello ")) prints "Hello Hello Hello " and returns nil.

The forms macroexpand and macroexpand-1 each take a quoted macro call, and return the expanded macro; macroexpand-1 expands a recursive macro only once. For example, (macroexpand '(triple-do (print "Hello "))) returns (do (print "Hello ") (print "Hello ") (print "Hello ")).


The usual list operations are enough to create code, but can be very cumbersome. To make this easier, Clojure supplies a special kind of quote, `, called a syntax-quote. What makes this special is that within the quoted code, things can be unquoted with ~. For example,

(defmacro triple-do [form] ; makes three copies of the form
    `(do ~form ~form ~form) )

If s is a sequence, ~s will be put into the template as the entire sequence. Sometimes it is desirable to instead put the individual elements of the sequence into the template. This can be done with the splicing unquote, ~@ -- for example, ~@s. If this doesn't make sense now, come back to it when you get unwanted parentheses in your expanded macro.

To avoid name conflicts with the code that uses a macro, it is illegal to create and bind local symbols in a macro, unless you end the symbol name with a # character. This tells Clojure to replace the symbol name with some generated name that is guaranteed to be unique. For example, if you define

(defmacro average-macro [a b]
  `(let [avg# (+ ~a ~b)] (/ avg# 2)) )
then (macroexpand '(average-macro 3 5)) will return something like (let* [avg__99__auto__ (clojure.core/+ 3 5)] (clojure.core// avg__99__auto__ 2)).


Interoperability with Java

Clojure can use Java objects, methods, and fields. This includes Java's collections data types, although Clojure's datatypes are preferable because they are immutable and persistent. Possibly the best use of Java in Clojure is to make Swing GUIs.

(import import-lists*)
Imports the named Java classes. Example: (import '(java.awt.Color) '(java.awt.Point)).
Only classes can be imported, not entire packages; there is no equivalent of import java.util.*;
All of java.lang is implicitly imported, along with everything in clojure.core.
(new JavaClassName args*)
(JavaClassName. args*) ;
syntactic sugar for the above--notice the period, it's important!
Creates and returns a new Java object of the specified class. Examples: (def rnd (new java.util.Random)), (def c (java.awt.Color. 255 128 0))
(. JavaObject methodName args*)
(.methodName JavaObject args*)
Calls the Java object's method with the supplied arguments. Examples: (. rnd nextInt 10), (.nextInt rnd 10).
(. JavaObject fieldName)
Returns the value in the named field of the Java object. Example: After (def p (new java.awt.Point 20 40)), (. p x) will return 20.
(JavaClass/staticMethodName args*)
Calls the static method of the class. Example: (System/currentTimeMillis).
Returns the value in the static field of the class. Example: (java.awt.Color/CYAN).
doto(JavaInstanceOrClass methodCalls*)
Uses the Java object or class as the receiver for any number of method calls. Example: (doto (new java.util.HashMap) (.put "a" 1) (.put "b" 2)).
(proxy [Class? Interfaces*] [constructorArgs*] functions*)
Creates a Clojure class to do the work that would be done by a Java class in Java. The optional Class? parameter names the superclass (and if omitted, defaults to Object). If the class's constructor requires parameters, those are provided in the second vector, otherwise the second vector is emtpy, []. The functions are usual Clojure functions (omitting the defn), and have the form (name [params*] body) or (name ([params*] body) ([params+] body) ...). For example,
(. convert-button
    (proxy [ActionListener] []
      (actionPerformed [evt]
        (let [c (Double/parseDouble (. temp-text (getText)))]
          (. fahrenheit-label
            (setText (str (+ 32 (* 1.8 c)) " Fahrenheit"))))))))
There are also functions for dealing with Java arrays, and for treating Java methods as first-class objects. These are not covered here.