Created
February 2, 2012 22:17
-
-
Save samaaron/1726148 to your computer and use it in GitHub Desktop.
Clojure: swap-returning-prev! switch!
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 switch! | |
"Sets the value of atom to new-val. Returns the previous value." | |
[atom new-val] | |
(let [old-val @atom | |
success? (compare-and-set! atom old-val new-val)] | |
(if success? | |
old-val | |
(recur atom new-val)))) | |
(defn swap-returning-prev! | |
"Similar to swap! except returns vector containing the previous and new values | |
(def a (atom 0)) | |
(swap-returning-prev! a inc) ;=> [0 1]" | |
[atom f & args] | |
(loop [] | |
(let [old-val @atom | |
new-val (apply f (cons old-val args)) | |
success? (compare-and-set! atom old-val new-val)] | |
(if success? | |
[old-val new-val] | |
(recur))))) |
Yep, you're absolutely correct :-)
However, how would you use recur in #'swap-returning-prev! - you can't call (apply recur atom f args)...
ISTR that recur interacts with destructuring in surprising ways:
((fn [a & b]
(if a
(recur nil b)
b)) 1 2 3) ; -> (2 3)
So apply isn't necessary.
That's scary. I think I might stick with the explicit loop in this case :-)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Do you need an explicit
loop
here? Wouldn't recuring to the top of the function work?