SICP in Clojure - Chapter 4

SICP in Clojure - Chapter 4

In one of the previous blog posts I have announced that I would like to start a new series of posts. It is a persistent journal from my journey through aforementioned book. I hope that you will enjoy it and find it useful - the main goal is to make this series a place where we can return in future, recall ideas and thoughts that accompanied reading process.


By finishing the previous chapter we learned more about functional programming, designing and dealing with stateful computation and a little bit about laziness. It was pretty much a general purpose programming book till now. Last two chapters of the book are really … Lispy. :wink:

Chapter which will be discussed today is focused on Lisp core values built around universal evaluator, homoiconicity and linguistic abstractions.

What is homoiconicity?

Very concise, I would say a mathematical, definition will explain it as a isomorphic relation between language AST (Abstract Syntax Tree) and its syntax. In more human friendly words - it is a property of a programming language in which the program structure is similar to its syntax. If such language is homoiconic, it allows all code in the language to be accessed and transformed as data, using the same representation - because AST is exactly the same as the language itself.

All languages from Lisp family have this property, also languages like Io, Julia or Prolog also have this ability (to a certain degree of course). Keep in mind that it does not mean that having a macros system in the language makes it homoiconic.

Metalinguistic abstraction

Title of this section sounds like a difficult concept, where the core idea is really simple. Aforementioned abstraction is an ability to create new languages. We have done that previously (e.g. by creating various Domain Specific Languages when solving exercises). By the creation, authors also mean ability to evaluate (or interpret) constructs written in that newly created dialect, by calculating values from the prepared expressions. Program which does such thing is called an evaluator (or interpreter).

If we go one level deeper in the abstraction tree, a metacircular evaluator (or also often called a metacircular interpreter) is an evaluator written in the same language that it will interpret. It means that you can write an interpreter of any Lisp dialect in that chosen language.

Core of metacircular evaluator

Clojure REPL (actually any kind of REPL) is an evaluator. But also, our run-time environments are also built on top of such constructs.

In Lisp, the core of the evaluator is often called an eval-apply cycle. If we will dive into implementations presented in the book, we will immediately see a symmetry between them. Authors defined both of them as follows.


To evaluate a combination (a compound expression other than a special form), evaluate the subexpressions and then apply the value of the operator subexpression to the values of the operand subexpressions.
1 ;; You can either evaluate quoted expressions
2 ;; or strings, but keep in mind that string
3 ;; does not have an AST-like structure by itself.
4 ;; It needs to be parsed first (with a
5 ;; `read-string`).
7 (eval '(let [a 10] (+ 3 4 a)))
8 (eval (read-string "(+ 1 1)"))

Evaluation means that we take fragment of the code (in form of a quoted expression or parsed from a string) and evaluate that, using all rules of the language. In other words, it calculates the result of a certain expression. Keep in mind that a delivered expression is just a data structure - list of keywords, other tokens, and other data structures. And it looks exactly the same as the language itself. That is a practical implication of the homoiconicity.


To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. To construct this environment, extend the environment part of the procedure object by a frame in which the formal parameters of the procedure are bound to the arguments to which the procedure is applied.
 1 ;; Result of executing both expressions is
 2 ;; exactly the same, but only the first one
 3 ;; is an application.
 4 ;;
 5 ;; Function application means that you have to
 6 ;; deliver all arguments upfront in a form of
 7 ;; collection.
 9 (apply str ["str1" "str2" "str3"])
10 (str "str1" "str2" "str3")

At the first sight you will find that apply is only a strange syntax for a function invocation. But then, the obvious reflection strikes in - it is exactly the opposite. Function call is a syntax sugar on top of apply function. Moreover, having this function in your toolbox opens a different ways of thinking about invoking unknown functions, and build other concepts like partial application and currying based on that.

Combining both powers together

Process of interpreting a program is an interaction between them. How it looks like? Here is an excerpt from an implementation (again full version is inside my repository - afronski/sicp-in-examples):

 1 (defn my-eval [exp env]
 2   (cond (self-evaluating? exp) exp
 3         (variable? exp)        (lookup-variable-value exp env)
 4         (quoted? exp)          (text-of-quotation exp)
 5         (assignment? exp)      (my-eval-assignment exp env)
 6         (definition? exp)      (my-eval-definition exp env)
 7         (if? exp)              (my-eval-if exp env)
 8         (lambda? exp)          (make-procedure (lambda-parameters exp)
 9                                                (lambda-body exp)
10                                                env)
11         (do? exp)              (my-eval-sequence (do-actions exp) env)
12         (cond? exp)            (my-eval (cond->if exp) env)
13         (application? exp)     (my-apply (my-eval (operator exp) env)
14                                          (list-of-values (operands exp) env))
16         :else                  (assert false "Unknown expression in `my-eval`.")))
18 (defn my-apply [proc args]
19   (cond (primitive-procedure? proc)
20           (my-apply-primitive-procedure proc args)
21         (compound-procedure? proc)
22           (my-eval-sequence (procedure-body proc)
23                             (extend-environment (procedure-parameters proc))
24                             args
25                             (procedure-environment proc))
27         :else
28           (assert false "Unknown procedure type in `my-apply`.")))

Even without exact definitions of the used functions, code is pretty self-explanatory. As we can see evaluation requires in certain cases an application, and application requires evaluation of function body and arguments. They are often expressed as a yin-yang symbol, because they are complementing each other.

Different evaluation models

Instead of reimplementing different evaluation models, I have prepared different examples of such, built on top of Clojure standard library (or sometimes with additional custom facilities). We will start with the concept which we already know from the previous chapter.


We have met this concept earlier already. In the previous chapter we worked with streams and infinite collections which simulate e.g. computation process. But built-in mechanisms in Clojure have much more to offer in that matter. We have already created some infinite collections, but let us remind how it works:

 1 (import java.util.UUID)
 3 (defn uuid-seq []
 4   (lazy-seq
 5     (cons (str (UUID/randomUUID))
 6           (uuid-seq))))
 8 (println (take 3 (uuid-seq)))
10 ; (b09b2a29-2cad-4cda-8e4c-8a9a5c136f05
11 ;  8ece35e6-202f-4977-9987-7292239833e4
12 ;  0a336e55-5e42-4312-87ea-24e86ba4311e)

First we are defining a lazy-seq then we use standard mechanism of constructing the collection from the first, evaluated element and the rest, which evaluation will be deferred. What I mean by deferring? If you will try to put the following lines inside a file (but not inside the REPL - it will force the evaluation) you will receive nothing:

 1 ; This returns a lazy collection, which
 2 ; is not evaluated yet.
 3 (map inc [1 2 3 4])
 5 ; You can force evaluation either by
 6 ; enforcing simple run (and wait for
 7 ; side-effects) or return the result
 8 ; of the operation.
10 (dorun (map inc [1 2 3 4])) ; nil
11 (doall (map inc [1 2 3 4])) ; (2 3 4 5)

But it is not an only way of creating lazy sequences. You can use also repeat, repeatedly, cycle or iterate in a following way:

 1 ; `repeat` and `repeatedly` creates an infinite sequence
 2 ; either of elements or results of a function call. You can
 3 ; create infinite sequence or a limited one by passing an
 4 ; argument or not.
 6 (println (str (clojure.string/join (take 5 (repeat "Na "))) "Batman!"))
 7   ; "Na Na Na Na Na Batman!"
 9 (println (repeatedly 5 #(rand-int 100)))
10   ; 34 23 12 1 23
12 ; `cycle` returns a lazy collection with repetitions
13 ; of a delivered collection.
15 (println (take 5 (cycle [1 2 3])))
16   ; (1 2 3 1 2)
18 ; `iterate` is a more generic constructor. It returns
19 ; a lazy sequence, which has the following values:
20 ;
21 ;   x, f(x), f(f(x)), ...
22 ;
23 ; This also means, that used `f` functions should be
24 ; *pure* (no side-effects).
26 (println (take 5 (iterate (partial * 3) 1)))
27   ; (1 3 9 27 81)

But laziness can be also used in a different way.

Ambiguous operator

Around 1961, John McCarthy (the inventor of LISP) described an interesting mathematical operator called amb (from ambiguous). Essentially, amb have to be called with arguments, but thanks to that - it can look into the future to keep that from happening. It does that by rewinding into the past whenever it sees trouble, and try a different choice.

It is called a backtracking algorithm. This technique is often used for solving problems with huge search space. The most canonical example is called 8 queens puzzle. Whole approach is partially based on top of laziness and searching problem space in a lazy way, basing on the constraints and then doing a backtracking.

In example presented below, we are trying to find all Pythagorean triple solutions in a specific range, passed as an argument:

 1 ; Both `amb-let` and `amb-let-helper` implementations
 2 ; are shamelessly taken from:
 3 ;
 5 (defn amb-let-helper [bindings body]
 6   (if (< 0 (count bindings))
 7     (let [[form expression] (take 2 bindings)
 8           more-bindings (drop 2 bindings)
10           filtered-recurse (if (= :where (first more-bindings))
11                              `(when ~(second more-bindings)
12                                 ~(amb-let-helper (drop 2 more-bindings) body))
13                              (amb-let-helper more-bindings body))
15           res (if (and (seq? expression)
16                        (= 'amb (first expression)))
17                 `(apply concat (for [~form ~(second expression)]
18                                  ~filtered-recurse))
19                 `(let [~form ~expression]
20                    ~filtered-recurse))]
21       res)
22     [body]))
24 ; Macro definition.
26 (defmacro amb-let [bindings body]
27   (amb-let-helper bindings body))
29 ; Defining problem and its constraints.
30 ; We would like to calculate all triples in range 100 that
31 ; fullfilling following conditions:
32 ;
33 ;   2 < a < MAX
34 ;   a <= b < MAX
35 ;   b <= c < MAX
36 ;
37 ;   a^2 + b^2 = c^2
39 (defn triple [max]
40   (amb-let [a (amb (range 1 max)) :where (> a 2)
41             b (amb (range a max))
42             c (amb (range b max))
44             :where (= (+ (* a a) (* b b))
45                       (* c c))]
46            [a b c]))
48 (println (triple 20))
49 ;  ([3 4 5] [5 12 13] [6 8 10] [8 15 17] [9 12 15])

Talking about backtracking, we can again building on top of that concept power our next evaluator extension. We can use it for logic programming and it is described in the book as a last enhancement.

Logic programming

Book takes that concept as a last one, by implementing own version of logic engine in the Scheme. In Clojure and ClojureScript there is no point of doing that, because we have it in the set of additional libraries. It is called core.logic and it is delivered as a separate library.

In prepared example we will take the most common problem when it comes to the logic programming kindergarten - simple genealogy questions. It may sound simple, but the provided relations, facts and queries will show the basic unification mechanism:

 1 (ns logic-example.core
 2   (:use [clojure.core.logic.pldb]))
 4 ; In the logic programming we are creating *relations* and *facts*.
 5 ; Relation describes how to interpret *facts*, with certain associations.
 7 (db-rel father Father Child)
 8 (db-rel mother Mother Child)
10 ; *Facts* are the truths, nothing more than a specific data structure
11 ; which describes our state of knowledge.
13 (def genealogy
14   (db
15    [father 'Adam 'Wiliam]
16    [father 'Adam 'Thomas]
17    [father 'Andrew 'Jessica]
18    [father 'Andrew 'Mark]
19    ; We are deliberately omitting Dorothy's father here.
21    [mother 'Eve 'Wiliam]
22    [mother 'Eve 'Thomas]
23    [mother 'Eve 'Jessica]
24    [mother 'Angie 'Mark]
25    [mother 'Angie 'Dorothy]))
27 ; Having *facts* and *relations* we can query them and thanks to them
28 ; `unification` mechanism, based on defined relations and facts available
29 ; in the database our logic engine will answer to that query with one,
30 ; more or no results.
32 (defn jessica-mother[]
33   (with-db genealogy
34     (run* [q]
35       (mother q 'Jessica))))
37 ; user=> (logic-example.core/jessica-mother)
38 ; (Eve)
40 (defn adam-children []
41   (with-db genealogy
42       (run* [q]
43         (father 'Adam q))))
45 ; user=> (logic-example.core/dorothy-father)
46 ; (Thomas Wiliam)
48 (defn dorothy-father []
49   (with-db genealogy
50     (run* [q]
51       (father q 'Dorothy))))
53 ; user=> (logic-example.core/dorothy-father)
54 ; ()

Depending on the knowledge and the environment, answers to the prepared questions are different. Query can return either one, more or no results. Everything is related with previously defined facts and relations. It looks pretty amazing, and that is only an introduction to that topic. For more, I will recommend you to read either about Prolog (you can start from here) or play with this tutorial.


We have managed to finish 4th chapter of the book. In the last part we will attack problems with which we are already familiar, but on the lowest possible level. We will focus on hardware specifics of Lisp evaluator implementations, including design constraints and limitations related with those topics.

I hope that we will meet there again! :smile:



Clojure Gazette 144: Can manipulating deep data structures be faster than update-in?

Clojure Gazette -- Issue 144 - October 5, 2015

Can manipulating deep data structures be faster than update-in?
Read this email on the web
Clojure Gazette
Issue 144 - October 5, 2015

Hi Clojure lovers!

As you know, I also make courses to teach Clojure. I like making them, but they take months to make. I've been searching for a format that will let me make smaller courses that come out with less delay.

I'm just about ready to make that available. It's a monthly subscription for access to new content and the backlog. I'll also be able to engage personally with people who want to learn Clojure more than ever. I'm really excited and I hope you are too. See this week's sponsored link for more information.

Please enjoy the issue!

Rock on!
Eric Normand <>

PS Subscribe to the list!
PPS Want to advertise to smart and talented Clojure devs?

Sponsor: Online Mentoring

You're looking into a career change. But you worry that you will face difficulty trying to get your first job in Clojure, since the niche is small and you've got limited Functional Programming background. How can you get clear on exactly what the hurdles and requirements are on the way there? Online Mentoring is designed to smooth out the learning curve, get you programming as soon as possible, and fit into your busy schedule. The lessons cover a broad range of topics, from beginner skills to libraries to deploying production code. You get the skills to succeed with Clojure and Functional Programming. If you're interested, subscribe and find out when it starts.

Specter: Clojure's Missing Piece Youtube

Nathan Marz presented his library Specter at Strange Loop. It's an abstraction for querying and modifying deeply nested data structures while maintaining the existing structure.

The Programming Language Called Classical Chinese Youtube

I've wanted to learn Mandarin for a long time. I've tried, giving it a shot during a short stay in China. One of the hardest parts is parsing the sentences. Not because I didn't know the words, but because there was so little structure to them. This talk was great because it explained the structure that is there (very little!) in terms a computer programmer could understand.

ClojureScript - React Native

A great--and growing--collection of resources for learning and using React Native with ClojureScript.

Transcript of Are We There Yet

It must be obvious by now that I like listening to talks. Having said that, these transcripts of great talks are simply amazing. It's crazy how much more you can get out of it if you read it, even after having seen the talks a number of times. Matthias Nehlsen and the other contributors are doing awesome work.

The Changelog: Living Clojure, ClojureScript, and more with Carin Meier

Carin Meier gave a great interview on The Changelog podcast. She touches on Clojure, chemical programming, speech acts, and her book Living Clojure.

The future of software, the end of apps, and why UX designers should care about type theory

Paul Chiusano's argument is that applications are silos of functionality that should be decomposed into composable parts. End users should be able to compose those parts as they wish in a powerful and fluent programming system. I'm glad I'm not alone in this line of thinking, even as knowing how far we are from them depresses me.

iota: Cheer up your testing with this small library

What an interesting library for defining tests in Clojure(Script).

Immutable Data Structures and JavaScript

If you're using JavaScript and want some immutable data structure goodness, this article has some pointers.

Clojure in Production: Logging

A super-practical guide to what logging is, why to do it, and how to do it in Clojure.


Fold the Zip Up

"They fell together all, as by consent."
-- Shakespeare, The Tempest
Act II, Scene I, Line 207


Zip can be thought of as the more generic form of Map.  Think of Zip as applying a function against each member of the collections given to it, thus mapping more than one collection to another collection.  It is a lot easier to see than to explain in words.

I believe Zip2 would get the following definition:

zip2 :: (α → β → γ) → ([α] → [β] → [γ])
zip2 f = fold (λx y xs ys → f x y : xs ys) [ ]

This would be if we limit Zip to being used on 2 collections (this is mine definition, Dr. Graham Hutton has nothing to do with this definition, blame me if it is wrong).

Folding a Zip we'll need a collection to seed with then we just apply the given function against each member from each collection concatenating it with the seed, just as we did with Map.

Next we'll look at a simple example adding the members of two collections together.

First Memoize has nothing and X has 1 while Y has 10 giving the result of 11.

Next Memoize has 11 and X has 2 while Y has 20 giving the result of 11, 22.

Lets see some code examples.


With Clojure we do not have to worry about the number of collection we'll give our Zip function since we can use destructing to say and everything else.  We can then apply map to create a vector containing all the elements next to each other, we'll see this is common in the other languages since the implementation of reduce is only design to work with a single collection.  From here it is just like Map except that we need to use apply since are members are a collection themselves.


With C# we have to specify the number of collection we are going to Zip, in this case we'll do two.  We need to Zip the members from the two collections together into a Tuple (which is a bit of cheating but I can find no other way to do it with LINQ).  From there it is just like Map.  With this implementation we do have a limitation in that the two collections must be the same size, since to get around that would be a bit of work and we rather have a readable implementation than perfect code.

ECMAScript 2015

In ECMAScript 2015 (also known as JavaScript ES6), we see an implementation similar to the C# code except we use lodash's zip to place the members in a single collection (lodash's zipWith is like LINQ's Zip).  From there it is just like Map.  With this implementation like the C# implementation we have a limitation in that the two collections must be the same size, and again the work around would be a lot of work so we'll error on keeping the code readable.


There you have it showing once again that all you need is Zip.


Guest Post - Beginning Clojure: Cursive

This post is from my friend and colleague Tim Pote. He’s a really smart guy and wrote up a tutorial on getting started with Clojure and IntelliJ/Cursive. Graciously, he’s allowed me to cross post it here. I’m currently pushing him to write more about Clojure on his blog.

The focus is Clojure, but IntelliJ/Cursive works just as well with ClojureScript (I use it and love it). In the future, I’ll add some notes on integrating tools like Figwheel.

Getting started with Clojure

One thing I often hear from people getting started with clojure is:

I’m learning clojure, and, since it seems to be the defacto standard for Lisp, I’m also learning Emacs.

Now, I’ll just come out and say it: I’m a Vim guy.

When I started learning clojure in 2012, the options were pretty much: use emacs, or use vim-fireplace. vim-fireplace is great, but it doesn’t provide you near the power and flexibility of a true REPL. Additionally, I don’t find paredit emulators in vim to be a fluid editing experience.

So, like many, I tried to learn clojure and Emacs at the same time.

I found that experience to be extremely frustrating. Not only was I having to learn and apply new language concepts, but I constantly felt hampered by my inability to edit text efficiently. Not to mention getting set up with any of the aforementioned tools is non-trivial for a newcomer. To this day, I remember the difficulty trying to “just fire up and connect to nREPL”.

Nowadays most of that pain has been alleviated by Cursive. That’s especially true if you’re accustomed to using an IDE. You get “simple” things like autocompletion, documentation, suggestions, and refactoring, all without having to “fire up a nREPL”. You get a full-fledged, interactive REPL. And you get to choose what editing mode you prefer. Emacs, Vim, point-and-click, whatever. Cursive’s got you covered.

So, now when people tell me “I’m learning clojure,” I usually respond:

Use Cursive, unless you already know Emacs

The problem with saying that is there’s still a pretty lengthy install process for an absolute beginner.

Therefore, I decided to put together a little tutorial for clojure newcomers that I can point to when the question comes up.

Install Java

  1. Go to the Java Download Page
  2. Accept the license agreement
  3. Select the appropriate install
  4. Note the install location. Example install locations are:
    • Mac: /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home
    • Windows: C:\Program Files\Java\jdk1.8.0_60
    • Linux: I have no idea. Figure it out. You asked for this :)

Install Leiningen

Leiningen is currently the defacto standard for clojure build tools. It’s used for lots of things, but in this example we’re only going to use it to generate our project.

If you’re on Windows, you should be able to use the windows installer.

If you’re on Mac/Linux, open a terminal and run:

echo 'export $PATH=$HOME/bin:$PATH' >> ~/.bashrc
mkdir ~/bin
cd ~/bin
chmod 755 lein

At this point, you can start a repl with lein repl. Yay!

Create a new clojure project

You should now be able to create your first clojure project. Simply open a terminal window, navigate to your projects directory, and run:

lein new app hello-clojure

This creates a new directory called hello-clojure which contains the scaffolding for an “app” project. If you want to create a different kind of application, simply replace app with the lein template of your choice. For example, if you want to create a webapp, you might choose chestnut.

Install Cursive

Download and install IntelliJ. The Free Community Edition will suffice.

Follow the Getting Started tutorial to install the Cursive plugin.

After you’ve installed the plugin, you’re going to want to set up keybindings for Cursive. Keep in mind that IntelliJ does not allow you to overwrite the template keybindings, so you must first make a copy of your preferred keymap.

Now that you have Cursive all set up, you can import the project you just created and set up a REPL in your project.

NOTE: During the project import process, you will be prompted to choose an SDK.

  1. Click the + button to create a new SDK
  2. Select JDK from the Add New SDK drop down
  3. Navigate to the Java install location you noted during step 1.

You can later access and modify the SDKs you have installed by going to File → Project Structure → SDKs. You can change the SDK for a particular project by going to File → Project Structure → Project and selecting a new Project SDK.

(Optional) Install IdeaVim

Lastly, we’ll mix in all the goodness of vim with the IdeaVim plugin. Go to Settings → Plugins → Install JetBrains plugin → IdeaVim. Click Install Plugin and restart.

There are a few gotchas with this plugin, but the one that gets me the most is the ability to use Esc from the REPL. One of the IntelliJ defaults is Esc returns you to the editor. This means that if you’re in the REPL, you have to hit Ctrl-c if you want to enter navigation mode. You can remap Esc but then you lose the ability to jump back to the editor altogether.


And that’s it! You now have the JVM and Leiningen installed, know how to set up a new project, and have a powerful editor.

Feel free to hit me up on twitter if there are any corrections or clarifications that need to be made to this tutorial.

Find this post useful? Please share the love on Hacker News.


Littlepot: Autofilled Cache

Cook, little pot, cook!

-- The Magic Porridge Pot, Brothers Grimm

I've just released littlepot, tiny library devoted to transform batched request into single element request.

The Problem

Imagine you develop a service which return one random image and some witty text below. As an image provider, you have chosen some, because they have a free limited API. Their endpoint is exactly what you need.

You wrote a function to get batched data.

(def get-batch []
  (-> api-endpoint

But your service need to return one image (get-image)

Wasting Requests

You lazy enough, so you just return random image from fresh batch.

(defn get-image []
  (rand-nth (get-batch)))

Simple enough, unless you'll encounter RateLimitException because guys from too greedy and allow only 100 requests per hour, but you just utilize 2% of all images.


Obvious solution: save images somewhere and return from there.

Congratulations, you discovered state, your life will never be the same.

Assume you introduced atom over list to save the data from the batch. Now every time you retrieve image, you need to remove it from cached batch.

(defn get-image []
  (let [element (first @batch)]
    (swap! batch rest)


Good enough, but the cache is not infinite, you need to refill it when data is over.

(defn get-image []
  (when (empty? @batch)
        (fill batch))
  (let [element (first @batch)]
    (swap! batch rest)

All clients are blocked until you cache is filled and see little latency.

What if we could send request in background, allowing clients still retrieve the data?


Meet littlepot, solutions to some of these problems.

Storage. It is backed by clojure.lang.PersistentQueue, clojure queue implementation, so you don't need to care about efficient storage.

Autofill. It sends request for next batch in a background, when your cached data is close to exhaustion, so the process of filling cache goes automatically and silently.

Non-blocking. You do not need to wait when data appears in cache; if something there, return it, if not, return :no-data.

Composable. Having function to retrieve single element (get-one) you can easily get fifty elements by calling (take 50 (repeatedly get-one)).

Concurrency. It encapsulates whole state in ref and uses STM, so multiple consumers allowed. Also, guaranteed that at most one batch will be in progress.

Getting Started Guide or some Advanced Usages could be found on github.


Time and Concurrency

Last Wednesday, I gave a short talk at Baltimore Innovation Week DevDay, entitled “Time and Concurrency”. The slides are hosted here, but I’ll try embedding them:

Okay, that seems to work.

I won’t recap the entire talk here, as I’m sure I’ll be presenting (a revised version of) it again in the future, but I’ll summarize.


Programmers, especially in the established object-oriented (and imperative) paradigms, have a problem with time. This isn’t a new argument; Rich Hickey spends most of his talk Are We There Yet? problematizing time in object-oriented programming; even Uncle Bob (Robert C Martin) addresses this in Functional Programming; What? Why? When?.

I wanted to present the problems with time and concurrency, which are really problems with state, value, and identity, and how functional programming, specifically using Clojure and Datomic, allowed us to either negate or embrace these problems.

Put simply, mutable state is evil. Sometimes a necessary evil, but evil nonetheless. Even something as simple as assignment:

foo = 3
puts foo
=> 3
foo += 1
puts foo
=> 4

foo is not the foo I started with! We create an identity, foo, assign it a value, and then willy-nilly assign it a new value. Consider:

(def foo 3)
(println foo)
=> 3
(println (inc foo))
=> 4
(println foo)
=> 3

The function inc (increment) doesn’t alter foo, it simply takes a value, and returns a new value. This is because inc is a pure function; it has no side-effects and cannot alter state.

The problem is that, as Rich Hickey puts it, “object-oriented languages have no reified notion of time”. Objects change over time, but we allow them a constant identity and have no guarantees (beyond mutexes and locks, which are the gateway to madness) to ensure that foo has the value I expect when I dereference it.

Pure functions have no concept of time, because having no state, time is not an issue; they take values and return values, always the same, every time.


Way back when we only had to consider single-threaded, single-process programs, time did seem very linear. But in a world of multiple threads in multiple processes spread across multiple cores, and often multiple machines, running in parallel, shared mutable state is a huge problem. Pure functions return the same result, given the same inputs, anywhere they are run, and don’t alter anything. Clojure’s emphasis on immutable state, persistent data structures, and pure functions1. In Clojure, mutable state is managed, thread-safe, and mutations are always explicit, usually within a transaction.


Datomic takes the ideas of time and immutability and applies them to the database. Datomic is an EAVT tuple-store, supporting both ACID transactions and unlimited horizontal read scalability. I highly recommend watching Rich Hickey’s talk Deconstructing the Database for a deep look at the theory and practice behind Datomic. But in borad strokes, instead of storing tables of mutable rows and columns (SQL style), or mutable documents2, Datomic stores facts. These facts are immutable; if something changes, a new fact is inserted, or a previous fact is retracted. That insertion or retraction is stored as a new fact.

This allows Datomic to apply the concept of time to the database; the previous state of the db as-of any point in time can be queried, and since the database functionally uses the same persistent data structures as Clojure, external data can be queried alongside Datomic data as if it were in the database. This concept of time allows us not only to examine any past state, but to virtually query the future by adding hypothetical data to our queries.

I won’t go into the mechanism of how this all of this is achieved, rather I’ll direct you to the videos on


DevDay Talks was a really great experience. You can see the full speaker lineup on the BIW site (linked above). I especially enjoyed Eric Oestrich’s talk on Kubernetes, and Richard McCluskey’s dive into DevOps at Millenial Media. So many great talks, and the after party was a lot of fun too. Thanks to Baltimore Innovation Week and Baltimore for throwing such a great event!

  1. “Impure” functions, i.e. those having side-effects, are allowed in Clojure (unlike, say, Haskell), but are the exception rather than the rule

  2. Like, e.g., MongoDB or CouchDB


[ANN] Reforms 0.4.0

I just released version 0.4.0 of Reforms - a library for quickly building dynamic web forms with validation, use controls such as tables with row selection.

Home: Github:

Generated markup is compatible with Bootstrap and Font Awesome CSS to give you a quick start but you're in no way obliged to use these libraries.

You can use this library to write concise code that is compatible with both Om and Reagent letting you easily switch between these libraries.

What's new

  • New table control with support for row selection using checkboxes.
  • Labels for controls are now optional.
  • Placeholder text for input/password/textarea etc. is no longer a required argument.
  • Experimental support for binding to Om local state.
  • Numerous bugfixes incl. ones relating to React's warnings about required "key" props.

Any sort of feedback is most welcome. Thank you.


Copyright © 2009, Planet Clojure. No rights reserved.
Planet Clojure is maintained by Baishamapayan Ghose.
Clojure and the Clojure logo are Copyright © 2008-2009, Rich Hickey.
Theme by Brajeshwar.