Immutability
BasicIn Clojure, the built-in collections are persistent: every "update" returns a brand new value and leaves the original untouched. You don't mutate data; you derive new versions of it. That sounds expensive, but Clojure shares structure between versions, so the cost is small and the guarantees are huge.
Minimal example
conj returns a new vector with one more element. The original is unchanged
when you look at it again:
The same holds for maps. assoc produces a new map; the original still has the
old value:
Practical example
Because values do not change behind your back, you can hold onto a snapshot and trust it. Here a "transaction history" keeps every prior state:
This is why local reasoning works in Clojure: if you bound xs ten lines ago,
nothing your callees do can make xs mean something else now.
Exercise
Define rename-key, which takes a map m, an old key k, and a new key k',
and returns a new map with the value moved from k to k'. The original m
must not change.