Fork me on GitHub
#clojure-dev
<
2020-01-14
>
andy.fingerhut05:01:56

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?

andy.fingerhut05:01:44

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)

bronsa09:01:25

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

bronsa09:01:59

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

🤯 1
andy.fingerhut10:01:00

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?

bronsa10:01:45

not using any implementation details/undefined behavior mind you

bronsa10:01:59

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

parrot 1
alexmiller13:01:21

I would say you probably shouldn’t do that

alexmiller13:01:00

There is another technique though that I’ve used

bronsa13:01:31

extending to object with a runtime extend?

bronsa13:01:51

yeah that's a bit better

alexmiller13:01:13

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

alexmiller13:01:37

I have a fuller example of that in Clojure Applied