An atom is a concurrency-aware reference for synchronous, uncoordinated changes to a single piece of state. Multiple threads can share it without explicit locking: each update derives a new value from the old value, retrying when another thread changes the state first. A Clojure atom is represented by clojure.lang.Atom, which wraps a Java AtomicReference. section 14.0 section 14.5
Choose the operation according to how the new state is determined:
- Use swap! when the update depends on the current value. It accepts additional arguments and may invoke the update function repeatedly, so side effects inside that function are unsafe. section 14.5
- Use reset! when the new value does not depend on the previous value. It does not retry; competing resets are resolved by the last operation to access the atom. section 14.5
- Use compare-and-set! for an explicit conditional replacement: it succeeds only when the atom still contains the expected value. section 14.5
Updating an atom
Define an atom with (def a (atom 0)), increment it with (swap! a inc), and read the result with @a. The returned value is 1. For nested state, (swap! m update-in [:b :c] inc) updates a map directly and returns the revised map.
Bounded retry with CAS
A custom swap-or-bail! loop can read the current value, compute a candidate, and call compare-and-set!. If another thread intervenes, it retries a fixed number of times before reporting failure. This is useful when the update function is slow or retries must be bounded.
(def a (atom 0)) ; #1 (swap! a inc) ; #2 ;; 1 @a ; #3 ;; 1
Inspect the minimal lifecycle: create an atom, update it, and dereference its current value. section 14.5

