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!
You could rely on a promise to store the current value inside the swap!
operation. Then you return the new and old value in a vector, as follows:
(defn- swap-and-return-old-value!
[^clojure.lang.IAtom atom f & args]
(let [old-value-promise (promise)
new-value (swap! atom
(fn [old-value]
(deliver old-value-promise old-value)
(apply f old-value args)))]
[new-value @old-value-promise]))