(defn
rswap!
"Swaps the value of a to be (apply f current-value-of-atom args).\n\n rswap! works like swap!, except that recursive calls to rswap! on\n the same atom are allowed – and it always returns nil."
[a f & args]
{:pre [(satisfies? IAtom a) (ifn? f)]}
(if
a.rswapping
(->
(or a.rswapfs (set! a.rswapfs (array)))
(.push (fn* [p1__18477#] (apply f p1__18477# args))))
(do
(set! a.rswapping true)
(try
(swap!
a
(fn
[state]
(loop
[s (apply f state args)]
(if-some [sf (some-> a.rswapfs .shift)] (recur (sf s)) s))))
(finally (set! a.rswapping false)))))
nil)