According to Clojure's documentation, reset!
can be used as:
Sets the value of atom to newval without regard for the current value. Returns newval.
Thus, I can do:
user> (def my-test (atom 666))
#'user/my-test
user> my-test
#<Atom@66d7a880: 666>
user> @my-test
666
user> (reset! my-test 77)
77
user> my-test
#<Atom@66d7a880: 77>
user> @my-test
77
But, is there any difference between using another def
instead of reset!
?
user> (def my-test (atom 666))
#'user/my-test
user> my-test
#<Atom@66d7a880: 666>
user> @my-test
666
user> (reset! my-test 77)
77
user> my-test
#<Atom@66d7a880: 77>
user> @my-test
77
;;;; converting it back to the original value via def
user> (def my-test (atom 666))
#'user/my-test
user> @my-test
666
user> my-test
#<Atom@7ce4f432: 666>
user>
Just by reading the experiments on the REPL I cannot identify any difference. But I am new to Clojure, so I am probably naive here.
If there is any difference, why should I use reset!
instead of a new def
?
You can see the answer in the REPL output in your question. When you write (reset! a 1)
, you give a new value to the existing atom. When you write (def a (atom 1))
, you get a brand new atom. Why does this matter? Because someone may have another reference to the old atom: in the former case they see the new value, and in the latter case they don't. Compare, for example:
(def a (atom 0))
(defn counter [c] (fn [] (swap! c inc)))
(def count-up (counter a))
(count-up) ; 1
(count-up) ; 2
(reset! a 0)
(count-up) ; 1 again
with
(def a (atom 0))
(defn counter [c] (fn [] (swap! c inc)))
(def count-up (counter a))
(count-up) ; 1
(count-up) ; 2
(def a (atom 0))
(count-up) ; 3, because the old atom still holds 2