How to reset! an object's field?


#1

I’m trying to wrap my head around how Clojure works. This is something I’ve ran into that I’d like to get a solid understanding of.

If I have code like this,

(let [obj (atom {:foo "F" :bar "B"})]
  (
   ; How to set obj.foo to "O"?
  ))

What’s the syntax to change obj.foo to “O” instead of “F”? All the examples I’ve found have been for updating primitives and not for updating a nested value.


#2
(let [obj (atom {:foo "F" :bar "B"})]
  (println @obj)
  (swap! obj assoc :foo "O")
  (println @obj))

You shouldn’t try to think of it as an object though. Its an immutable map, which you have stored in a mutable container.

  • assoc creates a new copy of the map, where the key :foo is now associated with the value “O”.
  • swap! changes what the atom points too, by having it point to the new map returned by assoc.

#3

Ok, that makes sense. I’ll try to get myself to stop calling them objects. The main reason I’ve been falling back to that is map is also a function so it’s been a bit confusing to keep track of whether map is talking about a map data structure or the map function. I have a similar issue with the thread macro since it’s not at all related with what thread usually means in programs. Part of the learning process. :slight_smile:


#4

Ya, its definitly a struggle at first to get used to new definitions, new words, new paradigms.

I think my advise is that, if you see it for what it is, a map. Then the question becomes, how do you create a modified copy of a map?

So you can use, map, filter, into, remove, assoc, dissoc, update, update-in, etc.

Then, the question is, how do you change the value of an atom?

So you can use reset! or swap!

I know its a lot to take :yum: Just keep it in mind. It’ll all click eventually.


#5

Yep, definitely. I think what was tripping me up was thinking of the entire map as the atom instead of the atom being, in essence, a pointer to a map and then changing the pointer to point to a new map.