Search code examples
clojurelighttable

LightTable Clojure Watches not Updating on Atom


When I add a watch to a variable in clojure and rebind it, the watch is updated dynamically.

(def x "jlkfds")
x

In the above example x will always reflect its value.

However, when I try and do this using an atom, I have no luck. I have to execute the whole thing again to get the changes to reflect in either the instarepl or the watch.

(defonce y (atom 10))
@y *38*
(swap! y inc) *80*

In the above example I have executed the swap without executing the deref, and they have thus become out of sync.

What confuses me is that I saw a Javascript demo where someone (Chris) was able to watch the coordinates of a mouse pointer dynamically change. I really like the idea of having this functionality. Is there a way to do the same thing in Clojure?

Like this?

http://youtube.com/watch?v=d8-b6QEN-rk

Thank you


Solution

  • Watches are only updated when the thing they are watching is eval'd. Just make sure that you are watching somewhere the watch macro can be eval'd. Try this.

    (defonce y (atom 10))
    
    (do //Eval this sexp
      (swap! y inc)
        @y) //watch this j
    

    I think you are also running into issues with the insta-repl (live mode), periodically it will evaluate the entire page and that is where you are seeing the watches get out of sync. For example, line 1 is evaluated and the atom is created. You add a watch to line 2, evaluating it. You increment the watch with line 3 28 times, then do something that forces line 2 to eval again. This updates the watch to the new value of y. Re-evaluating line 3 doesn't change the watch on line two but it changes the value of y.