@stuarthalloway is a founder and President of Cognitect (formerly Relevance). He is a Clojure committer, and a developer of the
Datomic database.

Stuart has spoken at a variety of industry events, including StrangeLoop, Clojure/conj, EuroClojure, ClojureWest, SpeakerConf, QCon, GOTO, OSCON, RailsConf, RubyConf, JavaOne, and NFJS.

Stuart has written a number of books and technical articles. Of these,
he is most proud of Programming Clojure.

Simulation Testing

Simulation allows a rigorous, scalable, and reproducible approach to testing:

Statistical modeling

Simulation begins with statistical models of the use of your system. This model includes facts such as “we have identified four customer profiles, each with different browsing and purchasing patterns” or “the analytics query for the management report must run every Wednesday afternoon.” Models are versioned and kept in a database.

Activity streams

The statistical models are used to create activity streams. Each agent in the system represents a human user or external process interacting with the system, and has its own timestamped stream of interactions. With a large number of agents, simulations can produce the highly concurrent activity expected in a large production system.

Distributed execution

Agents are scaled across as many machines as are necessary to both handle the simulation load, and give access to the system under test. The simulator coordinates time, playing through the activity streams for all the agents.

Capture results

Every step of the simulation process, including modeling, activity stream generation, execution, and the code itself, is captured and stored in a database for further analysis. You will typically also capture whatever logs and metrics your system produces.


Since all phases of a simulation are kept in a database, validation can be performed at any time. This differs markedly from many approaches to testing, which require in-the-moment validation against the live system.

Separation of concerns

The separation of concerns above, and the use of a versioned, time-aware database, gives simulation great power. Imagine that you get a bug report from the field, and you realize that the bug corresponds to a corner case that you failed to consider. With a simulation-based approach, you can write a new validation for the corner case, and run that validation against your past simulation results, without ever running your actual system.

This talk will introduce simulation testing, walking through a complete example using an open-source simulation library.

Clojure in the Field

This talk is an experience report on using Clojure in production systems, based on Stuart’s Clojure experiences:

  • using Clojure as his own primary development language since 2008
  • writing the first book on Clojure, now in a second edition
  • committing to Clojure
  • advising the Clojure/core team at Relevance
  • developing Clojure projects for Relevance customers
  • training developers on Clojure
  • helping to develop Datomic, a database written in Clojure
  • collaborating with Rich Hickey, the creator of Clojure, ClojureScript, and Datomic

If you are considering whether, or how, to bring Clojure into your organization, this talk is filled with practical advice, from the high level to the gritty details.

Concurrent Programming with Clojure

Clojure’s immutable, persistent data structures encourage side-effect free programming that can easily scales across multiple processor cores. In this talk, we will explore the various features Clojure provides for dealing with concurrency:

  • Atoms provide for synchronous, uncoordinated updates
  • Agents provide a thread-safe mechanism for asynchronous, uncoordinated updates
  • Futures are a convenient mechanism for execution on a separate thread
  • Delays provide a way to defer work for one-time execution when needed
  • Promises provide one-time delivery as a mechanism for coordination
  • Software Transactional Memory (STM) provides a mechanism for managing references and updates across threads.
  • Dynamic Vars support thread-local state.