Add swap-vals! and reset-vals! (swap! and reset! that return [old new])


  • Type: Feature Feature
  • Status: Closed Closed
  • Priority: Critical Critical
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: Release 1.9
  • Component/s: None
  • Labels:
  • Approval:


Sometimes, when swapping or resetting an atom, it's desirable to know the value before the update. The existing swap! and reset! functions return the new value instead. Currently, the only option is to roll your own using a loop and compare-and-set!

Example use cases:

  • When an atom contains a PersistentQueue and you want to atomically remove the head of the queue and process it: if you run (swap! q pop), you have lost the reference to the old head of the list so you can't process it.
  • Want to check if an operation has occurred before by using atom as a flag (this can be achieved with compare-and-set! but reads a little easier this way).
    (def has-run-once (atom false))
    (when-not (get-and-set! has-run-once true)
    (do something))
  • Want to use an atom similarly to a java.util.concurrent.LinkedTransferQueue, for the case of pairing up adds by writers and drainTo y readers:
    Thread 1: (swap! atm conj item1)
    Thread 2: (swap! atm conj item2)
    Thread 3: (let [new-vals (get-and-set! atm [])] 
    (do-something new-vals))

Approach: Add clojure.core/swap-vals! and clojure.core/reset-vals! that return [old new]

Patch: clj-1454-4.patch

  1. clj-1454-3.patch
    06/Sep/17 8:01 AM
    7 kB
    Alex Miller
  2. clj-1454-4.patch
    06/Sep/17 12:30 PM
    8 kB
    Alex Miller
  3. deref-swap-deref-reset-extending-IAtom.diff
    29/Feb/16 11:03 AM
    5 kB
    Linus Ericsson
  4. deref-swap-deref-reset-with-IAtomDeref-and-tests.diff
    02/Mar/16 2:14 PM
    6 kB
    Linus Ericsson



Vote (16)
Watch (10)


  • Created: