Multithreading – how do I implement atoms in clojurescript?
In clojure to address concurrency, we can use an atom to write:
user=> (def my-atom (atom 0)) #'user/my-atom user=> @my-atom 0 user=> (swap! my-atom inc) 1 user=> @my-atom 1 user=> (swap! my-atom (fn [n] (* (+ n n) 2))) 4
We know that this (in the clojure Implementation) is a wrapper around the Java atomic object
Interestingly, atoms are replicated in clojurescript is at the syntactic level - even if JavaScript runs without atomic references
My question is, how do I implement atoms in clojurescript? Are they just an object wrapper?
Solution
It only returns and assigns values
At the source https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L4081
(deftype Atom [state Meta validator watches] ... IDeref (-deref [_] state) ...)
And https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L4110
(defn atom "Creates and returns an Atom ..." ([x] (Atom. x nil nil nil)) ([x & {:keys [Meta validator]}] (Atom. x Meta validator nil)))
Check the implementation of swap! And reset! You will find:
(set! (. - status a) new value)
Then, go to https://github.com/clojure/clojurescript/blob/3bb97961cbc958aeaeac506222dc7b9dcb0e9fc1/src/clj/cljs/compiler.clj#L771 Set! You will find that the compiler only issues an 'assignment statement':
(defmethod emit* :set! [{:keys [target val env]}] (emit-wrap env (emits target " = " val)))