Skip to main content
added 126 characters in body
Source Link
mikera
  • 106.5k
  • 28
  • 265
  • 427

Suppose I have two protocols:

(defprotocol A (f [this])) (defprotocol B (g [x y])) 

And I want to extend protocol B to all instances that support protocol A:

(extend-protocol A String (f [this] (.length this))) (extend-protocol B user.A (g [x y] (* (f x) (f y)))) 

The primary motivation is to avoid having to extend B separately to all the possible classes that A may be extended to, or even to unknown future classes that other people may extend A to (imagine if A was part of a public API, for example).

However this doesn't work - you get something like the following:

(g "abc" "abcd") => #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :g of protocol: #'user/B found for class: java.lang.String> 

Is this possible at all? If not, is there a sensible workaround to achieve the same objective? The primary motivation is to avoid having to extend B separately to all the possible classes that A may be extended to.

Suppose I have two protocols:

(defprotocol A (f [this])) (defprotocol B (g [x y])) 

And I want to extend protocol B to all instances that support protocol A:

(extend-protocol A String (f [this] (.length this))) (extend-protocol B user.A (g [x y] (* (f x) (f y)))) 

However this doesn't work - you get something like the following:

(g "abc" "abcd") => #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :g of protocol: #'user/B found for class: java.lang.String> 

Is this possible at all? If not, is there a sensible workaround to achieve the same objective? The primary motivation is to avoid having to extend B separately to all the possible classes that A may be extended to.

Suppose I have two protocols:

(defprotocol A (f [this])) (defprotocol B (g [x y])) 

And I want to extend protocol B to all instances that support protocol A:

(extend-protocol A String (f [this] (.length this))) (extend-protocol B user.A (g [x y] (* (f x) (f y)))) 

The primary motivation is to avoid having to extend B separately to all the possible classes that A may be extended to, or even to unknown future classes that other people may extend A to (imagine if A was part of a public API, for example).

However this doesn't work - you get something like the following:

(g "abc" "abcd") => #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :g of protocol: #'user/B found for class: java.lang.String> 

Is this possible at all? If not, is there a sensible workaround to achieve the same objective?

Source Link
mikera
  • 106.5k
  • 28
  • 265
  • 427

How can you extend a Clojure protocol to another protocol?

Suppose I have two protocols:

(defprotocol A (f [this])) (defprotocol B (g [x y])) 

And I want to extend protocol B to all instances that support protocol A:

(extend-protocol A String (f [this] (.length this))) (extend-protocol B user.A (g [x y] (* (f x) (f y)))) 

However this doesn't work - you get something like the following:

(g "abc" "abcd") => #<IllegalArgumentException java.lang.IllegalArgumentException: No implementation of method: :g of protocol: #'user/B found for class: java.lang.String> 

Is this possible at all? If not, is there a sensible workaround to achieve the same objective? The primary motivation is to avoid having to extend B separately to all the possible classes that A may be extended to.