 
   The lens is not well-behaved, depens on the outcome of the predicate."
   [applies?]
-  (lens
-   (fn [s]
-     (when (applies? s)
-       s))
-   (fn [s f]
-     (if (applies? s)
-       (f s)
-       s))))
+  (lens (fn [s]
+          (when (applies? s)
+            s))
+        (fn [s f]
+          (if (applies? s)
+            (f s)
+            s))))
 
 (defn nth
   "Given a number, returns a lens that focuses on the given index of
   a collection."
   [n]
-  (lens
-    (fn [s]
-      (clojure.core/nth s n))
-    (fn [s f]
-      (update s n f))))
+  (lens (fn [s] (c/nth s n))
+        (fn [s f] (update s n f))))
 
 (def fst (nth 0))
 (def snd (nth 1))
 
-(defn sequential-empty
-  {:internal true
-   :no-doc true}
+(defn- sequential-empty
   [coll]
   (cond
     (map? coll) {}


(def tail
  "A lens into the tail of a collection."
  (lens
   rest
   (fn [s f]
     (into (sequential-empty s)
           (cons (first s)
                 (f (rest s)))))))

(defn key
  "Given a key, returns a lens that focuses on the given key of
  an associative data structure."
  [k]
  (lens
   (fn [s]
     (get s k))
   (fn [s f]
     (update s k f))))

(def ^:private core-select-keys
  #?(:clj clojure.core/select-keys
     :cljs cljs.core/select-keys))

(defn select-keys
  "Return a lens focused on the given keys in an associative data
  structure."
  [ks]
  (lens
   (fn [s]
     (core-select-keys s ks))
   (fn [s f]
     (merge (apply dissoc s ks)
            (-> (core-select-keys s ks)
                f
                (core-select-keys ks))))))

(defn in
  "Given a path and optionally a default value, return a lens that
  focuses the given path in an associative data structure."
  ([path]
   (in path nil))
  ([path default]
   (lens
    (fn [s]
      (get-in s path default))
    (fn [s f]
      (update-in s path f)))))

;; interop

(defn- prefix-key
  {:internal true :no-doc true}
  [key id]
  (keyword (str id "-" (name key))))

(def ^:private +empty+
  #?(:clj (Object.) :cljs (js/Object.)))

#?(:clj
   (deftype RWFocus [id lens src equals?


     clojure.lang.IRef
     (addWatch [self key cb]
       (locking self
         (set! (.-watchers self) (assoc watchers key cb))
         (when (= (count (.-watchers self)) 1)
           (add-watch src id (make-watcher self lens equals?)))
         self))

     (removeWatch [self key]
