Refs: Team-Oriented Atoms

One drawback in using atoms is that each atom stands alone. For example, if we needed to track the total number of books in the inventory along with each book by title using two atoms, we might try something like this:

 (ns inventory)
 
 (​def​ by-title (atom {}))
 
 (​def​ total-copies (atom 0))
 
 (​defn​ add-book [{title :title :as book}]
  (swap! by-title #(assoc % title book))
 
 ;; Oh no! The two atoms are out of sync right here!
 
  (swap! total-copies + (:copies book)))

We’re going to have an unavoidable window where the new book is in the inventory but not counted.

It is for just such occasions that Clojure supplies us with refs. Setting up a ref is much like setting up an atom:

 (ns inventory)
 
 (​def ...

Get Getting Clojure now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.