ABSTRACT

This chapter focuses on Clojure’s various approaches to concurrency visiting refs, agents, and software transactional memory (STM). Clojure is a Lisp, with powerful metaprogramming facilities gained from code-as-data, such as macros. Understanding Clojure begins with understanding its execution model, defined in terms of the reader and the evaluator. Namespaces contain mappings of symbols to vars and classes. Vars refer to mutable storage locations. Vars are Clojure objects. STM solves one of the classic problems in concurrency—transferring money between accounts—quite nicely. Like vars and refs, agents store values which one retrieves via deref. To change the value managed by the agent, a programmer dispatch an action. An action is simply a function call that, provided the optional validation test passes, produces the new value for the agent. The function executes asynchronously on a thread from thread pools managed by Clojure; the programmer never starts any threads or performs any locking.