Reputation: 1095
Warning: I'm almost certain I'm using at least some of the relevant terms wrong
I want to modify flatland.ordered.set.OrderedSet so that nth
works. I think this involves something like:
(extend-type flatland.ordered.set.OrderedSet
?????
(nth [this n] (nth (vec this) n))
I've been trying to discern what protocol defines nth
for a few hours now, with no luck. Is there a list of "native" protocols? Am I just totally mixed up?
Upvotes: 4
Views: 359
Reputation: 91837
As Nathan Davis says, you can't do this "from the outside", because this stuff is based on interfaces rather than protocols. It would be quite reasonable for OrderedSet to implement Indexed; I must have just overlooked that interface entirely.
On the other hand, your implementation of nth is very inefficient: you don't want to create an entire length-N vector just to look up a single element in it. Instead, you want to call into get
, which does the same thing as nth
.
Edit: having looked back over the code again, I see that nth
is not nearly as easy to implement correctly, because the existence of disj makes it difficult to quickly tell how many elements have been dropped from the set where. I don't think an efficient implementation for nth
can really exist for this data structure unless you remove the ability to use disj
. So I probably won't accept a pull request implementing nth
unless you figure out something really clever, but feel free to fork ordered
and add it to your own fork if you don't need disj
support.
Upvotes: 3
Reputation: 5766
It is not currently possible to do what you want to do using extend-type
. Clojure's persistent collection interfaces are implemented using Java interfaces, not Clojure protocols. Therefore, it is not possible to extend them using extend-type
.
However, since the code is open source, you could always change the library itself. All you should need to do is implement nth
in OrderedSet
's deftype
. nth
is defined by the clojure.lang.Indexed
interface.
Upvotes: 3