アトムは共有された、同期的な独立した状態を管理する手段を提供する。アトムはrefやvarと同様に参照型である。 atom を使用してアトムを作成することが出来、 deref/@ を使用することでその状態にアクセスすることが出来る。refやエージェントと同様にバリデーターをサポートしている。アトムの値を変更するには swap! を使用することが出来る。また、低水準な compare-and-set! も提供されている。アトムに対する変更で競合は発生しない。

全ての参照型と同様に、アトムの想定されている使われ方はClojureのイミュータブルなデータ構造を保持することだ。また、refのalterやagentのsendと同様に、古い値に関数を適用することで値を変更することが出来る。これは swap! によってアトミックに行われる。内的には swap! が現在の値を読み込み、関数を適用し、 compare-and-set を試みる。アトムの値の更新を試みる際に他のスレッドによって値が変更された場合、リトライが必要な可能性があり、そのリトライはループで行われる。最終的な結果として、アトムの値は常に現在値に与えた関数をアトミックに適用した結果の値となる。与える関数は複数回呼び出される可能性があるので副作用が存在しない必要がある。

アトムは協調の必要がない、同期的に変更される状態を効率的に表現する方法だ (エージェントと異なり、独立してはいるが同期的)。使用例としてメモ化が挙げられる:

(defn memoize [f]
  (let [mem (atom {})]
    (fn [& args]
      (if-let [e (find @mem args)]
        (val e)
        (let [ret (apply f args)]
          (swap! mem assoc args ret)
          ret)))))

(defn fib [n]
  (if (<= n 1)
    n
    (+ (fib (dec n)) (fib (- n 2)))))

(time (fib 35))
user=> "Elapsed time: 941.445 msecs"

(def fib (memoize fib))

(time (fib 35))

user=> "Elapsed time: 0.044 msecs"