swizzard
swizzard

Reputation: 1095

Extending Clojure core protocols

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

Answers (2)

amalloy
amalloy

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

Nathan Davis
Nathan Davis

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

Related Questions