Skip to content

Instantly share code, notes, and snippets.

@base698
Last active March 11, 2016 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save base698/a64d2316420b00000542 to your computer and use it in GitHub Desktop.
Save base698/a64d2316420b00000542 to your computer and use it in GitHub Desktop.
update-in, get-in, and assoc-in

update-in, assoc-in, get-in: Not using these functions is doing it wrong

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....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment