3

I've been experimenting a lot with extending Clojure's protocols to already existing types, but it seems like whenever I have a question like "How would I extend this protocol to all seq-able collections?" or "How would I extend this protocol to all numbers (longs, ratios, integers, floats, etc.)?" I have to do a lot of googling to find the answers, and even then, I'm not always able to find a definitive answer.

Is anyone aware of a handy reference for commonly used clojure.lang.Something, java.lang.SomeJavaClass, etc. classes and protocols? I think it would be beneficial if we had some resource available to help out the Clojurians like myself who have little to no Java experience.

EDIT: To give you an idea of what I'm looking for, in this code:

(defprotocol X
  (do-something [this]))

(extend-protocol X
  ?????? <-- 
  (do-something [this] '(implementation goes here)))

Is there a resource that might have a list of Clojure/Java classes to which it might be useful to extend a protocol?

1

2 Answers 2

5

No direct answer here, but some useful resources:

  • I find Stuart Sierra's class diagram project to be hugely useful for visualizing the class structure of Clojure and Java interfaces it depends on.
  • Chouser has some older static diagrams here
  • If you are creating custom collections via deftype, this scaffolding macro can save you a lot of time
Sign up to request clarification or add additional context in comments.

2 Comments

These all look like very useful resources. Thanks! Props also to the other Alex who mentioned Chouser's diagrams as well as Clojure Atlas. I'll have to spend some time playing with all of these.
Since I wrote this response I co-wrote Clojure Applied on Pragmatic Press, which contains some additional information on the key Java interfaces within Clojure related to collections and sequences.
1

I think I semi-answered my own question, although I'm still curious to know if anyone has a better solution:

For Java classes, you can start by googling e.g. "Java Integer class," and the official docs will show you the chain of inheritance up from java.lang.Integer -> java.lang.Number -> java.lang.Object. It seems that most (if not all...?) java.lang.X classes can be abbreviated within extend-protocol as just X, so Number should work for extending a protocol to all subclasses of numbers.

It seems like the online documentation for Clojure doesn't clearly show chains of inheritance like this, unless I'm missing something. But clojure.core/supers is a handy method to at least find classes to try extending a protocol to in order to get the functionality you're looking for:

user> (class [])
;=> clojure.lang.PersistentVector

user> (supers (class []))
;=> #{clojure.lang.Sequential clojure.lang.ILookup clojure.lang.AFn
      clojure.lang.APersistentVector java.util.concurrent.Callable
      java.util.RandomAccess clojure.lang.Reversible java.util.List 
      clojure.lang.IHashEq java.util.Collection clojure.lang.IMeta 
      java.lang.Object java.io.Serializable clojure.lang.Associative 
      clojure.lang.Seqable clojure.lang.IEditableCollection java.lang.Iterable 
      clojure.lang.Counted java.lang.Runnable clojure.lang.IPersistentCollection 
      clojure.lang.IObj clojure.lang.IPersistentVector clojure.lang.Indexed 
      clojure.lang.IFn clojure.lang.IPersistentStack java.lang.Comparable} 

clojure.lang.Sequential seems like a useful class for extending a protocol for which you'd like a general implemention for all sequential collections.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.