Last Updated: February 25, 2016
· sativaware

Using atoms to manage state in your Clojure app.

One of the elegant mechanisms for managing state in Clojure is atoms.

Within our chat app - Jane & Joe are currently online.

#{"Jane" "Joe"}

Moments later, Joy comes online joins them in the chat.

(conj #{"Jane" "Joe"} "Joy")
;; => #{"Joe" "Jane" "Joy"}

Now that Joy has come online, we can see there are 3 people online.

(count #{"Joe" "Jane" "Joy"})
;; => 3

Lets double check and make sure Joy is online

(contains? #{"Joe" "Jane" "Joy"} "Joy")
;; => true

For the sake of this example, we are explicitly defining the set that contains the set of people currently online.

To make the example more practical lets look at how to employ atoms to manage the state of our list of people online.

Jack & Peter are currently online in our chat app:

(def people-online(atom #{"Jack" "Peter"}))
;; => #<Atom@1fec1485: #{Peter Jack}>

Here we are using Clojures atom function to provide a way to manage the state of a set - here we have defined it as people-online

Shortly after, Jen comes online

(swap! people-online conj "Jen")
;; => #{"Peter" "Jen" "Jack"}

Because we are working with an atom we use the swap! function to change the value of the online-people atom.
In this case, we are simple changing it by using conj to add "Jen" to the set of people online.

You can access an atoms state using deref

(count (deref people-online))
;; => 3

or using @

(count @people-online)
;; => 3

Using the @ way, lets double check that Jen is online

(contains? @people-online "Jen")
;; => true

As we can see from this example Clojure's pragmatic & practical approach allows us to manage the state of a part of our application - the use of atoms here can be applied generally.

Useful Links