                      (filter (complement sym-or-str?) (keys kvs))
                      (repeatedly gensym))
         obj (gensym "obj")]
-    `(let [~@(apply concat (set/map-invert expr->local))
+    `(let [~@(apply concat (clojure.set/map-invert expr->local))
            ~obj ~(js-obj* (filter-on-keys core/string? kvs))]
        ~@(map (fn [[k v]] `(aset ~obj ~k ~v)) sym-pairs)
        ~@(map (fn [[k v]] `(aset ~obj ~v ~(core/get kvs k))) expr->local)

  the binding-forms are bound to their respective init-exprs or parts
  therein. Acts as a recur target."
  [bindings & body]
  (assert-args
   (vector? bindings) "a vector for its binding"
   (even? (count bindings)) "an even number of forms in binding vector")
  (let [db (destructure bindings)]
    (if (= db bindings)
      `(loop* ~bindings ~@body)
      (let [vs (take-nth 2 (drop 1 bindings))
            bs (take-nth 2 bindings)
            gs (map (fn [b] (if (core/symbol? b) b (gensym))) bs)
            bfs (reduce (fn [ret [b v g]]
                          (if (core/symbol? b)
                            (conj ret g v)
                            (conj ret g v b g)))
                        [] (map core/vector bs vs gs))]
        `(let ~bfs
           (loop* ~(vec (interleave gs gs))
                  (let ~(vec (interleave bs gs))
                    ~@body)))))))

(def fast-path-protocols
  "protocol fqn -> [partition number, bit]"
  (zipmap `[IFn ICounted IEmptyableCollection ICollection IIndexed ASeq ISeq INext
            ILookup IAssociative IMap IMapEntry ISet IStack IVector IDeref
            IDerefWithTimeout IMeta IWithMeta IReduce IKVReduce IEquiv IHash
            ISeqable ISequential IList IRecord IReversible ISorted IPrintWithWriter IWriter
            IPrintWithWriter IPending IWatchable IEditableCollection ITransientCollection
            ITransientAssociative ITransientMap ITransientVector ITransientSet
            IMultiFn IChunkedSeq IChunkedNext IComparable INamed ICloneable IAtom
            IReset ISwap]
          (iterate (fn [[p b]]
                     (if (core/== 2147483648 b) ;; 2^31
                       [(core/inc p) 1]
                       [p (core/bit-shift-left b 1)]))
                   [0 1])))


(defmacro defrecord [rsym fields & impls]
  (let [rsym (vary-meta rsym assoc :internal-ctor true)
        r    (vary-meta
               (:name (cljs.analyzer/resolve-var (dissoc &env :locals) rsym))
               assoc :internal-ctor true)]
    `(let []
       ~(emit-defrecord &env rsym r fields impls)
       (set! (.-cljs$lang$type ~r) true)
