                cached-hierarchy# (atom {})
                hierarchy# (get ~options :hierarchy (cljs.core/get-global-hierarchy))]
            (cljs.core/MultiFn. (cljs.core/symbol ~mm-ns ~(name mm-name)) ~dispatch-fn ~default hierarchy#
-                               method-table# prefer-table# method-cache# cached-hierarchy#))))))
+             method-table# prefer-table# method-cache# cached-hierarchy#))))))
 
 (core/defmacro defmethod
   "Creates and installs a new method of multimethod associated with dispatch-value. "

        (bar-me [this y] x))))
  => 17"
  [psym & doc+methods]
  (let [p (:name (cljs.analyzer/resolve-var (dissoc &env :locals) psym))
        [doc methods] (if (core/string? (first doc+methods))
                        [(first doc+methods) (next doc+methods)]
                        [nil doc+methods])
        psym (vary-meta psym assoc
               :doc doc
               :protocol-symbol true)
        ns-name (-> &env :ns :name)
        fqn (fn [n] (symbol (core/str ns-name "." n)))
        prefix (protocol-prefix p)
        _ (core/doseq [[mname & arities] methods]
            (when (some #{0} (map count (filter vector? arities)))
              (throw
                #?(:clj (Exception.
                          (core/str "Invalid protocol, " psym
                            " defines method " mname " with arity 0"))
                   :cljs (js/Error.
                           (core/str "Invalid protocol, " psym
                             " defines method " mname " with arity 0"))))))
        expand-sig (fn [fname slot sig]
                     `(~sig
                       (if (and ~(first sig) (. ~(first sig) ~(symbol (core/str "-" slot)))) ;; Property access needed here.
                         (. ~(first sig) ~slot ~@sig)
                         (let [x# (if (nil? ~(first sig)) nil ~(first sig))]
                           ((or
                             (aget ~(fqn fname) (goog/typeOf x#))
                             (aget ~(fqn fname) "_")
                             (throw (missing-protocol
                                     ~(core/str psym "." fname) ~(first sig))))
                            ~@sig)))))
        psym   (vary-meta psym assoc-in [:protocol-info :methods]
                 (into {}
                   (map
                     (fn [[fname & sigs]]
                       (let [doc (as-> (last sigs) doc
                                   (when (core/string? doc) doc))
                             sigs (take-while vector? sigs)]
                         [(vary-meta fname assoc :doc doc)
                          (vec sigs)]))
                     methods)))
        method (fn [[fname & sigs]]
                 (let [doc (as-> (last sigs) doc
                             (when (core/string? doc) doc))
                       sigs (take-while vector? sigs)
                       slot (symbol (core/str prefix (name fname)))
                       fname (vary-meta fname assoc
                               :protocol p
                               :doc doc)]
                   `(defn ~fname
                      ~@(map (fn [sig]
                               (expand-sig fname
                                 (symbol (core/str slot "$arity$" (count sig)))
                                 sig))
                          sigs))))]
    `(do
       (set! ~'*unchecked-if* true)
       (def ~psym (js-obj))

  and map->TypeName, taking a map of keywords to field values."
  [rsym fields & impls]
  (validate-fields "defrecord" rsym fields)
  (core/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! (.-getBasis ~r) (fn [] '[~@fields]))
