In Clojure to address concurrency issues 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 enough, Atoms are replicated in ClojureScript, at a Syntactic level - even though JavaScript runtimes don't have an Atomic reference.
My question is, How are Atoms implemented in Clojurescript? Are they just an object Wrapper?
Atoms are a data type in Clojure that provide a way to manage shared, synchronous, independent state. An atom is just like any reference type in any other programming language. The primary use of an atom is to hold Clojure's immutable datastructures. The value held by an atom is changed with the swap!
To change the value of an atom, you can use swap!. A lower-level compare-and-set! is also provided.
Exactly one state at any point in time. And that state is a true value, i.e. it never changes. If an identity appears to change, it is because it becomes associated with different state values over time. This is the Clojure model. In Clojure's model, value calculation is purely functional.
It just returns and assigns the value.
In 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 out:
(set! (.-state a) new-value)
then , go to https://github.com/clojure/clojurescript/blob/3bb97961cbc958aeaeac506222dc7b9dcb0e9fc1/src/clj/cljs/compiler.clj#L771 the set!
, you will find the compiler just emits an 'assignment statement':
(defmethod emit* :set!
[{:keys [target val env]}]
(emit-wrap env (emits target " = " val)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With