I talked about this a bit on IRC\'s #clojure channel today but would like to go more in detail here. Basically, in order to better understand atoms, swap!
Clojure's swap! is just a spinning compare-and-set. You can define an alternate version that returns whatever you like:
(defn alternate-swap [atom f & args]
(loop []
(let [old @atom
new (apply f old args)]
(if (compare-and-set! atom old new)
[old new] ; return value
(recur)))))