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 [_]))
P
user=> (defprotocol Q (g [_]))
Q
user=> (extend-type user.Q P (f [this] (g this)))
nil
user=> (deftype T [] Q (g [_] :g))
user.T
user=> (f (T.))
:g
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?
yes
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
I would say you probably shouldn’t do that
There is another technique though that I’ve used
extending to object with a runtime extend?
Yeah
yeah that's a bit better
Which was suggested by Rich at the first conj during Chousers protocol talk
I have a fuller example of that in Clojure Applied