Search code examples
clojurerefs

adjusting the values of an atom which is made up of a list of refs


I have an atom which is to contain a list of refs. How would I update the list of refs inside the atom? I tried the following but it does not work.

(def theatom (atom []))
(def mylist [1 2 3 4])

(reset! theatom (map ref mylist))

(swap! theatom (fn [anAtom]
    (map (fn [theRef] (dosync (alter theRef inc))) theatom)
    ))
(println (map deref @theatom))

The idea is to increase each ref value by one. I should then print [2 3 4 5].


Solution

  • You have it set up weird. I think you meant:

    (swap! theatom (fn [refs]
                     (map (fn [theRef]
                            (dosync (alter theRef inc))
                            theRef) ; Returning the return of dosync "unwraps" the refs
                          refs)))
    

    Although it could be made a little neater using doseq:

    (swap! theatom (fn [refs]
                     (doseq [r refs]
                       (dosync (alter r inc)))
                     refs))
    

    You were trying to map over the atom instead of the list it holds. Atoms aren't iterable, so that would have raised an error.