Created
December 9, 2013 11:46
-
-
Save pyrtsa/7871080 to your computer and use it in GitHub Desktop.
Exchange atom value in Clojure. This function seems like a common enough pattern in Clojure it should find its place in the standard library.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn exchange! | |
"Atomically set the value of `atom` to `(apply f @atom args)`, | |
and return the value of `@atom` just before the assignment. | |
(See also: `clojure.core/swap!`)" | |
[atom f & args] | |
{:pre [(instance? clojure.lang.Atom atom)]} | |
(loop [oldval @atom] | |
(if (compare-and-set! atom oldval (apply f oldval args)) | |
oldval | |
(recur @atom)))) | |
;; Example: | |
(def tokens (atom #{10 20 30 40 50})) | |
(defn pop-token! | |
"Atomically `disj` an element in the set-valued atom, | |
returning the removed element." | |
[tokens-atom] | |
(first (exchange! tokens-atom | |
#(disj % (first %))))) | |
(future (pop-token! tokens)) | |
(future (pop-token! tokens)) | |
(future (pop-token! tokens)) | |
(future (pop-token! tokens)) | |
(pop-token! tokens) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment