Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Protocols by

I was playing around with protocols at the REPL and encountered the following:

(defprotocol IGreeter
  (greet [this]))

(deftype MyGreeter []
  IGreeter
  (greet [_] "hi from MyGreeter"))

(extends? IGreeter MyGreeter)
;=> true

 ;; I expected to see MyGreeter listed here, but result is nil
(extenders IGreeter)
;=> nil

Now extend the protocol to a few types.

(extend-protocol IGreeter 
  String 
  (greet [this] "hi-string")
  clojure.lang.Symbol 
  (greet [this] 'hi-sym)  ; ' help syntax highlighter
  clojure.lang.Keyword
  (greet [this] :hi-kw))

(extenders IGreeter)
;=> (java.lang.String clojure.lang.Symbol clojure.lang.Keyword)

String, Symbol and Keyword show up as extenders of IGreeter. MyGreeter does not. This was especially surprising since (extends? IGreeter MyGreeter) returns true. Am I misunderstanding something or could this be a bug? Thank you!

1 Answer

+1 vote
by
selected by
 
Best answer

This matches the docstring for extenders - "Returns a collection of the types explicitly extending protocol', I think here "explicitly extending" refers to types that have been extended via extend-type or extend-protocol or extend. The three mechanisms of extension are sometimes referred to as "external" (or "explicit"), "direct" (deftype / defrecord / reify), and "metadata", see https://clojure.org/reference/protocols.

So, not a bug.

by
Ah, I see the distinction now. Thank you for clarifying. I appreciate having Clojure Q&A to ask questions like this and your role specifically in making a great Clojure community.
...