Fork me on GitHub

So in some ways, a Clojure protocol is like a Java interface. One difference that I think is true is: a Java interface can extend another Java interface, but there is no notion of a Clojure protocol extending another Clojure protocol. Is that correct?


Of course another difference being that a developer can make a type extend a protocol, even if they did not write the code that defines the type, without modifying that code. But you cannot make a Java class implement a Java interface directly except by modifying the source code defining that Java class. (there are techniques like delegation in Java that let you create 'shim code' that achieves a somewhat similar effect, I think, but is a bit more tedious to write the code for than something like Clojure's extend-type)


but there is no notion of a Clojure protocol extending another Clojure protocol. Is that correct eeeh technically one can, ish


user=> (defprotocol P (f [_]))
user=> (defprotocol Q (g [_]))
user=> (extend-type user.Q P (f [this] (g this)))
user=> (deftype T [] Q (g [_] :g))
user=> (f (T.))

🤯 4

That is taking advantage of the fact that Clojure/Java creates a Java interface user.Q, and so this is a trick specific to Clojure/Java, it appears?


not using any implementation details/undefined behavior mind you


extending a protocol to an interface is supported, and so is the underlying interface of a protocol

parrot 4
Alex Miller (Clojure team)13:01:21

I would say you probably shouldn’t do that

Alex Miller (Clojure team)13:01:00

There is another technique though that I’ve used


extending to object with a runtime extend?


yeah that's a bit better

Alex Miller (Clojure team)13:01:13

Which was suggested by Rich at the first conj during Chousers protocol talk

Alex Miller (Clojure team)13:01:37

I have a fuller example of that in Clojure Applied