When teaching programming, something that tends to come up a lot is when and how values can change. While there is a lot of jargon (values, references, mutability) to make communicating with people that already understand these ideas easier, it can be difficult to explain to people that don’t already understand the ideas.

The below was initially written to explain to a co-worker learning Clojure what we mean when we say “values are immutable” and I thought maybe someone else could find it useful.

## Mutability

In Clojure, values are immutable by default. If you have `(let [foo [1 2 3]] ...)` you can’t change that list. You can make `foo` refer to a new value, but you can’t change the value itself. For example, if you have `(let [foo [1 2 3] bar foo] (conj foo 4))` then the values of `foo` & `bar` are still the same, `[1 2 3]` - the `conj` function returns a new vector (that we haven’t given a name to). Even if you do something like

``````(let [foo [1 2 3]
bar foo
foo (conj foo 4)] ...)
``````

`foo` now refers to the vector `[1 2 3 4]`, because we’ve “shadowed” what `foo` refers to, but `bar` is still `[1 2 3]`.

In languages that have mutable values, for example Python, you could do:

``````foo = [1, 2, 3]
bar = foo
foo.append(4)
``````

Then `foo` would be `[1,2,3,4]` and so would `bar`, because the list is mutable, so you can actually change the underlying value the names refer to. In Clojure, even with atoms, only the atom itself is mutable, so, for example:

``````(def foo (atom [1 2 3]))
(def bar @foo)
(swap! foo conj 4)
``````

Now foo is an atom, `@foo` is `[1 2 3 4]` but bar is still `[1 2 3]`

This makes things much less confusing & reduces the potential for bugs, because values aren’t changing out from under you. In the python example, imagine `foo` is getting passed to some other function, then that could make the value of your `bar` variable change!