Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Atoms implemented in Clojurescript?

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?

like image 382
hawkeye Avatar asked Feb 17 '14 10:02

hawkeye


People also ask

What are atoms in Clojure?

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!

Which modification operation is used frequently with atom to update its value?

To change the value of an atom, you can use swap!. A lower-level compare-and-set! is also provided.

What is Clojure state?

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.


1 Answers

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)))
like image 153
llj098 Avatar answered Oct 17 '22 08:10

llj098