I recently went back and looked at some clojure I wrote when I was learning.
Given:
(def x {:a 1
:b {:c 3}})
So for a case like this, where I wanted to increment {:c 3} and have the change persist in x I was doing code like this:
(let [val (:c (x :b))
updated (inc val)]
(set! x (assoc x :b (assoc (:b x) :c updated))))
The correct way would be this:
(def x (atom {:a 1 :b {:c 3}}))
; To run the update function:
(swap! x update-in [:b :c] inc)
; To just swap the value with seven:
(swap! x assoc-in [:b :c] 7)
Atom is hard to follow and realize why you need it in the docs, but it has to do with "software transactional memory". It's basically a way to get transactions of the database variety with setting variables. Useful for when you have state to update, like in a game world without being a pure function Nazi about state like Haskell. Atoms are related to refs, so you may see them mentioned together.
Happy clojuring....