Chapter 1, Down the Rabbit Hole

in browser Clojure implementation:

(android has a Clojure REPL app)

start repl on command line

% java -cp clojure-1.4.0.jar clojure.main

(to exit repl, enter Ctrl-D)

Expressions, Operators, Syntax, and Precedence

All Clojure code is made up of expressions, each of which evaluates to a single value.

Clojure call expressions follow one simple rule: the first value in a list is the operator, the remainder are parameters to that operator.


Clojure code is composed of literal representations of its own data structures and atomic values; this characteristic is formally called Homoiconicity, or more casually, code-as-data.

Clojure (like all Lisps): rather than defining a syntax that will be transformed into an AST (Abstract Syntax Tree), Clojure programes are written using Clojure data structures that represent that AST directly.

The Reader

  • read
  • read-string
  • pr
  • pr-str

Scalar Literals




true, false





- \space
  • \newline
    • \formfeed
    • \return
    • \backspace
    • \tab
(def person {:name "Sandra"
             :city "Portland"})

:name, :city are keywords. keywords are functions what look themselves up in collections passed to them. keywords are always prefixed with a colon :, and can otherwise consist of any nonwhitespace character.

a slash character / denotes a namespaced keyword, while a keyword prefixed with two colons :: is expanded by the reader to a namespaced keyword in the current namespace.

keywords are one type of "named" values

(name :user/location)
;= "location"
(namespace :user/location)
;= "user"

the other named type of value is the symbol


symbols must begin with non-numeric character, and can contain *, +, !, -, _, and ? and any alphanumberic characters.

symbols that contain a slash / denote a namespaced symbol.


(check doc)

Regular expressions:

strings prefixed with a hash character # as regular expression literals

(class #"(p|h)ail")
;= java.util.regex.Pattern


  • single line: prefixing with a semicolon ;
  • form level: using the #_ macro
    (read-string "(+ 1 2 #_(*2 2 ) 8)")
    ;= (+ 1 2 8)

Whitespace and Commas:

whitespace is sufficient to separate values and forms provided to the reader. commas are considered whitespace by the reader.

(= [1 2 3] [1, 2, 3])
;= true

most common usage for comma is when more than one pair of values appears per line:

(create-user {:name new-username, :email email})

Collection Literals:

'(a b :name 12.5)       ;; list
['a 'b :name 12.5]      ;; vector
{:name "Chas" :age 31}  ;; map
#{1 2 3}                ;; set

since lists are used to denote calls in Clojure, you need to quote ' the list literal


All Clojure code is defined and evaluated within a namespace.

Vars are defined in Clojure using the def special form, which only ever acts within the current namespace.

the current namespace is always bound to *ns*

Code Blocks: do

do evaluates all of the expressions provided to it in order and yields the last expression's value as its value

    (println "hi")
    (apply * [4 5 6]))
; hi
;= 120

Local Bindings: let

let defines locals.

Creating Functions: fn

(fn [x]
    (+ 10 x))
(defn adder [x]
    (+ 1 x))

Function Literals

(fn [x y] (Math/pow x y))
#(Math/pow %1 %2)

no implicit do form

#(do (println (str %1 \^ %2))
        (Math/pow %1 %2))

function literals cannot be nested.

Conditions: if

Clojure conditionals determine logical truth to be anything other than nil or false.

if a conditional expression is logically false, and no else expression is provided, the result of an if expression is nil

Looping: loop and recur

appropriate use of recur: recur is a very low-level looping and recursion operation that is usually not necessary:

  • use doseq and dotimes
  • when "iterating" over a collection or sequence, use map, reduce, for and so on.

Chapter 2, Functional Programming

(ok, i gave up here, this book is not for new learners)

(update: able to finish it on the 3rd trial, it's difficult but worth the time.)

Chapter 3 Collections and Data Structures

Chapter 4 Concurrency and Parallelism

Chapter 5 Macros

Chapter 6 Datatypes and Protocols

Chapter 7 Multimethods

Chapter 8 Organizing and Building Clojure Projects

Chapter 9 Java and JVM Interoperability

Chapter 10 REPL-Oriented Programming

Chapter 11 Numerics and Mathematics

Chapter 12 Design Patterns

Chapter 13 Testing

Chapter 14 Using Relational Databases

Chapter 15 Using Nonrelational Databases

Chapter 16 Clojure and the Web

Chapter 17 Deploying Clojure Web Applications

Chapter 18 Choosing Clojure Type Definition Forms Wisely

Chapter 19 Introducing Clojure into Your Workplace

Chapter 20 What’s Next?

Search Blog: