Skip to content

A look at Clojure Concurrency primitives: delay, future and promise

August 14, 2012

As I was reading through the excellent book, Clojure Programming book by Chas Emerick, Brian Carper and Christophe Grand, I got to the part on Concurrency and felt that I should write about these primitives as a taste of what concurrency is like in Clojure. I highly recommend reading the book as it explains these concepts far better than I could in this short post!

So, quick rundown of these handy constructs:


delay wraps up an arbitrary body of code for evaluation at a later stage (when it is required) so that the code in question isn’t run unless asked. This will also cache the result value of the code to prevent another execution. This means that the code is guaranteed to only run once, even if dereferenced concurrently. A small REPL example (the “user>” bit being the REPL prompt) :

user> (def d (delay (println "Hello world!") 42))
user> d
#<Delay@320dafa2: :pending>
user> (realized? d)
user> @d
Hello world!
user> @d
user> (realized? d)
user> d
#<Delay@320dafa2: 42>

Here first assign the delay to a var, arbitrarily called ‘d’, if we look at it, we can see it starts in a pending state. We can then check if it has been run with the realized? function – dereferencing it (with the @) causes the code to run and Hello world! printed. Notice that the second @d does not print Hello world! again.


This is a simple way of spinning off a new thread to do some computation or I/O that you will need access to in the (surprise!) future. The call is entirely compatible with delay, so you can swap them out if you want to start the work immediately. If you dereference a future, it will block until the value is available – REPL example :

user> (def do-something (future (Thread/sleep 10000) 28))
user> do-something
#<core$future_call$reify__6110@14c55ea: :pending>
user> (realized? do-something)

… 10 seconds pass ….

user> (realized? do-something)
user> @do-something
user> do-something
#<core$future_call$reify__6110@14c55ea: 28>

You can see that realized? is once again useful for when you don’t want to incur the blocking penalty and that you didn’t need to dereference do-something for the value to become realized.


Promises are used in a similar way to delay or future in that you dereference them for a value, can check if they have a value with realized? and they block when you dereference them if they don’t have a value until they do. Where they differ is that you don’t immediately give them a value, but provide them with one by calling deliver:

user> (def p (promise))
user> (realized? p)
user> (deliver p "as-promised")
#<core$promise$reify__6153@66650e56: "as-promised">
user> (realized? p)
user> @p

Of course, calling @p will block the REPL until you open a new one and deliver it (provided you’re using swank or something that can have multiple open REPL threads). There are some really neat ways to combine the promise with future to get nice and declarative concurrency semantics. But I’ll leave that as an exercise for you.

I really enjoy how the dereferencing work exactly the same for future, delay and promise as they do for the Clojure atom and ref types.


From → Coding

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: