As Michael said, your original code works fine for me (running 1.2.0 master).
user=> (do (send artisan manufacture) (println @material @products @products-store)) 4 3 2 nil user=> (do (send artisan manufacture) (println @material @products @products-store)) 3 0 6 nil user=> (do (send artisan manufacture) (println @material @products @products-store)) 2 1 6 nil user=> (do (send artisan manufacture) (println @material @products @products-store)) 1 2 6 nil Without seeing the actual exception, it's hard to diagnose what you're running into. What version of clojure are you running? Out of curiosity why did you structure your code that way, as opposed to something like: (defn manufacture [state] (dosync (alter material ask-materials) (alter products send-products)) (str "idle")) I'm not sure what the full story is behind the intent of watchers, but it smells funny to me to have them modify the ref whose modification triggered them. As for dumping the state-change of refs, add-watch seems the right path, though you don't need to repeat yourself: (defmacro dump [& refs] `(do ~@(for [r refs] `(add-watch ~r :dump (fn [k# r# o# n#] (println '~r o# "=>" n#)))))) (dump material products products-store) One issue with the above is that the printlns occur in the agent threads, so the output to the repl can look weird. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en