Mutable References

Learn about the variables and references in Clojure that change their content over time.

Introduction

Clojure can be considered one of the safest languages when dealing with concurrency. As in any other language, sometimes we need to perform state-modification operations concurrently. Until now, we’ve talked a lot about immutability and how things are expected to happen in Clojure. However, at some point, we need to have a functionality to deal with states.

The term value is commonly used among the Clojure community, but its specific meaning might differ from what we’re used to. Values are considered atomic in the way that they form a unit or component in a larger system. For instance, numbers are values: it wouldn’t make sense for the number 13 to mutate into another number. When we apply a mathematical function for adding or subtracting from 13, we don’t change the number 13; we just create a new value with a different number.

Clojure’s data structures are all values because they’re immutable. When we use assoc on a map, we don’t modify the original map; instead, we derive and create a new map. So a value doesn’t change, but we can apply a process to a value to produce a new value. From this perspective, there’s no such thing as a mutable state. Instead, state means the value of an identity at a point in time.

The change will only occur when:

  • A process generates a new value.

  • We choose to associate the identity with the new value.

To handle this sort of change, Clojure uses reference types, which let us manage identities by naming an identity and retrieving its state.

Atoms

Atoms are probably the most famous and popular concurrency primitive in Clojure. They capture the essence of sharing a single piece of information and keeping its state. They provide a way to manage a shared, synchronous, and independent state. So, for example, if we define an atom with a data structure and dereference it, we will never block the thread like futures, delays, and promises do. Instead, we’ll have it evaluated immediately.

To define an atom, we can have two arities, (atom x) and (atom x & options), in which x is the value that this atom holds and options are optional defined fields to validate things in the atom.

Let’s see an example:

Get hands-on with 1200+ tech skills courses.