 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reference Types ;;;;;;;;;;;;;;;;
 
-(defprotocol IAtom
+(defprotocol IReset
   (-reset! [o new-value]))
+
+(defprotocol ISwap
+  (-swap! [o f] [o f a] [o f a b] [o f a b xs]))
 
 (deftype Atom [state meta validator watches]
   IEquiv

        new-value))
    (-reset! a new-value)))

(defn swap!
  "Atomically swaps the value of atom to be:
  (apply f current-value-of-atom args). Note that f may be called
  multiple times, and thus should be free of side effects.  Returns
  the value that was swapped in."
  ([a f]
     (reset! a (f (.-state a))))
  ([a f x]
     (reset! a (f (.-state a) x)))
  ([a f x y]
     (reset! a (f (.-state a) x y)))
  ([a f x y z]
     (reset! a (f (.-state a) x y z)))
  ([a f x y z & more]
     (reset! a (apply f (.-state a) x y z more))))

(defn compare-and-set!
  "Atomically sets the value of atom to newval if and only if the

  (if (= (.-state a) oldval)
    (do (reset! a newval) true)
    false))

(defn set-validator!
  "Sets the validator-fn for an atom. validator-fn must be nil or a
