This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # aleph (1)
- # announcements (14)
- # aws (8)
- # babashka (3)
- # beginners (49)
- # cider (6)
- # clara (7)
- # clj-kondo (58)
- # cljs-dev (17)
- # clojure (65)
- # clojure-dev (45)
- # clojure-europe (5)
- # clojure-italy (4)
- # clojure-nl (25)
- # clojure-norway (3)
- # clojure-uk (68)
- # clojurescript (10)
- # crux (17)
- # cursive (5)
- # datomic (12)
- # emacs (41)
- # fulcro (149)
- # hoplon (56)
- # kaocha (2)
- # luminus (18)
- # malli (7)
- # off-topic (12)
- # other-languages (82)
- # reagent (16)
- # reitit (7)
- # shadow-cljs (44)
- # spacemacs (4)
- # tools-deps (48)
Am I correct in believing that
parents , and
ancestors in clojure.core have no relationship with protocols?
And if the answer is "yes", is there anything built into Clojure that is like
ancestors that takes protocols into account? (Or if that would be ill-defined or not make sense for some reason, would appreciate some hints as to why)
Even if no hierarchy, something like "what protocols does this class/interface implement?" could be useful to query, perhaps?
but it's not possible to do, protocol implementations belong to the protocol not to the classes/interfaces
In Clojure/Java, I have forgotten which ways of defining an implementation of a protocol do this, but some create a "class/interface extends Java-interface-of-protocol" relationship. Those can be seen via Java reflection API, and so also
ancestors . Double checking that to make sure I am not imagining things.
and crucially it's not a thing that happens in all the ways a type can extend a protocol
Understood. I was a bit confused when I first came across that. It does mean some of those relationships show up in
parents results, but not all, I think.
there is preference within protocols impls already: protocol extensions to concretions win over extensions to interfaces
rephrased for broadcast: checking for a protocol implementation walks up the concrete hierarchy before the interfaces
I am still catching up, though 🙂 Ghadi, do you mean that if class A has an implementation for protocol P, and class A implements interface I1, and I1 has an implementation for protocol P, then calling a protocol P function on an instance of class A should always execute the class A implementation?
But still, if one was creating a "does X implement/extend Y" kind of diagram, "A implements P" is true in that situation, regardless of exactly which implementation of P is used.
right -- sorry I thought the original question was about preference when there is ambiguity
So there is no central "registry" of protocols in Clojure, but if you had a list of namespaces, you could walk through all of their Vars and look for them, based on knowing what protocols "look like" in the implementation details?
(note that in the case of multiple inheritance w/o a clear derivation preference, it's undefined which impl will be used)
I don't mind the extra detail, but I was more asking whether there is already something like
parents that, given A, would return P among the results, if A implements P
Well, Java classes can be loaded at runtime, too, so runtime changes don't bother me 🙂
I'm going to split hairs here @bronsa: the undefined impl case you're talking about is when you implement multiple interfaces to which the protocol is extended
Ah, I guess you mean that Java classes have their extends/implements-Java-interfaces relationships all known after the class is initialized, but protocols have another level of dynamicity beyond that?
Thanks for the clarification there. FYI, the reason for my asking is that I was hoping to enhance Stuart Sierra's class-diagram library to show "implements protocol" relationships, in addition to the
ancestors relationships that it shows now, and trying to figure out how.
i'm sure for tooling purposes it should be easy to get something working even tho it may not be correct/complete 100% of the cases
Among other enhancements that led me to look up 1970s CS algorithms papers on computing transitive reductions, which is something I've almost known how to do, but never in anger yet.
No need for anyone to dig through lots of code, but as a semi-quick hack, looking through all Vars in a namespace for those whose value is a Clojure map, that contains at least the keys
(:on :on-interface :sigs :var :method-map :method-builders) , seems likely to catch everything defined via Clojure/Java
defprotocol , and while it could possibly catch other things, that seems somewhat unlikely to happen.
I could do additional sanity checks on the types/values associated with those keys, of course.
I did a quick check, and
:impls are not there when one first defines a protocol, but understood, yes.
And it does not gain a key
:impls if one creates a
deftype that implements the protocol.
yup, the extenders of an interface are an open set. (e.g. functions that return a