Find which protocols are implemented by a Clojure datatype.

As part of a somewhat larger experiment (implementing dynamic mixins in Clojure) I needed to know what protocols are implemented for a given object (defined for example by defrecord or deftype). For example I have defined the next protocol:

When I try to find the implemented protocol by using the ancestors function, I get the opposite result:

(ancestors Foo)

has dci.core.LogProtocol in it’s list of ancestors, while

(ancestors Bar)

doesn’t.

So there is a difference (at least in Clojure 1.2) in behavior whether you implement the protocol directly with defrecord (as done with Foo) or extend it later (Bar). I wanted a solution that works with both declarations. I first implemented a function protocol? that checks for a given symbol if it is a protocol:

(defn protocol? [maybe-p]
(boolean (:on-interface maybe-p)))

This implementation depends on the :on-interface key, which is undocumented. Next I created a function all-protocols that returns a list of all protocols in the current namespace (*ns*).