Sending a protocol is performed as the first argument of the function. When multiple implementations match the type of the first argument, the most specific implementation is selected. This is why the call (hi #{})allows the implementation of the collection, not the implementation of the collection or fn, even if the collection ( #{}) implements both of these files.
Function find-protocol-implin clojure-deftype.cljseems to process the protocol to implement object resolution:
(defn find-protocol-impl [protocol x]
(if (instance? (:on-interface protocol) x)
x
(let [c (class x)
impl
(or (impl c)
(and c (or (first (remove nil? (map impl (butlast (super-chain c)))))
(when-let [t (reduce1 pref (filter impl (disj (supers c) Object)))]
(impl t))
(impl Object)))))))
source
share