 
      IWatchable
      (-add-watch [self key cb]
-       (letfn [(run-watchers [oldv newv]
-                 (run! (fn [[key wf]] (wf key self oldv newv))
-                       (.-watchers self)))
-               (main-watcher [_ _ oldv newv]
-                 (locking self
-                   (when-not (identical? newv (.-srccache self))
-                     (let [old' (focus lens oldv)
-                           new' (focus lens newv)]
-                       (set! (.-cache self) new')
-                       (set! (.-oldcache self) old')
-                       (set! (.-srccache self) newv)
-                       (when-not (equals? old' new')
-                         (run-watchers old' new'))))))]
-         (locking self
-           (set! (.-watchers self) (assoc watchers key cb))
-           (when (= (count (.-watchers self)) 1)
-             (add-watch src id main-watcher)))
-         self))
+       (set! (.-watchers self) (assoc watchers key cb))
+       (when (= (count (.-watchers self)) 1)
+         (add-watch src id (make-watcher self lens equals?)))
+       self)
 
      (-remove-watch [self key]
        (set! (.-watchers self) (dissoc watchers key))


     clojure.lang.IRef
     (addWatch [self key cb]
       (letfn [(run-watchers [oldv newv]
                 (run! (fn [[key wf]] (wf key self oldv newv))
                       (.-watchers self)))
               (main-watcher [_ _ oldv newv]
                 (locking self
                   (when-not (identical? newv (.-srccache self))
                     (let [old' (focus lens oldv)
                           new' (focus lens newv)]
                       (set! (.-cache self) new')
                       (set! (.-oldcache self) old')
                       (set! (.-srccache self) newv)
                       (when-not (equals? old' new')
                         (run-watchers old' new'))))))]
         (locking self
           (set! (.-watchers self) (assoc watchers key cb))
           (when (= (count (.-watchers self)) 1)
             (add-watch src id main-watcher)))
         self))

     (removeWatch [self key]

  opposite direction, construct a lens that focuses and updates
  a converted value."
  [one->other other->one]
  (lens one->other
        (fn [s f]
          (other->one (f (one->other s))))))

;; lenses

