Clojure offers a number of different forms that define types (and generate Java classes). Choosing between deftype, defrecord, reify, proxy, and gen-class can be a tripping point for those new to Clojure.
I’d obviously like to make such decisions easier for everyone. I know that many people learn best through visual aids, so I’ve been working on a flowchart that attempts to encapsulate some of the significant choices that go into deciding between the different type-definition forms. A draft of it is below; let me know if it is helpful to you (or not!), how you think it could be made better, etc. The most recent version of the flowchart, the “source” OmniGraffle file, and many translations of it (feel free to contribute another one!) will always be available here.
“The ‘Interop Zone’” demarcates use cases (e.g. needing to define multiple constructors) and forms (
proxyandgen-class) that are exclusively the domain of Clojure’s JVM interoperability support. Using these forms is fine, but be aware that by doing so, you are stepping outside of Clojure’s “native” abstractions; unless you are defining a type for the express purpose of meeting interoperability requirements, one of Clojure’s simpler type-definition forms may suit your needs better.
Updated 2011-07-05 18:28 UTC based on initial feedback. Thanks!
Updated 2011-07-07 17:38 UTC — added “The ‘Interop Zone’”
Updated 2011-08-09 16:30 UTC — Japanese translation provided by OGINO Masanori
Updated 2011-08-23 17:33 UTC — Portuguese translation provided by Paulo Suzart
Final update: The most recent version of the flowchart, the “source” OmniGraffle file, and many translations of it (feel free to contribute another one!) will always be available here.




Hey, once it’s stable, one could find it interesting to embed this as a wizard in CCW ;-)
This is very nice. One comment:
The two parts of the bottom-right parallelogram don’t seem to connect to me. I can imagine thinking to myself: “Is this class modeling a domain value? No. Do I want to use (:field object) notation and maybe assoc new keys onto the object? Yes.”
My gut reaction is that the default choice in this parallelogram is defrecord unless you want to explicitly prevent map functions like assoc from working on the type. I mean, even if you always use the (.field object) form and don’t assoc, etc., does it *hurt* to use a defrecord?
The point re: “what do we want to be recommending as reasonable defaults” is well taken, thank you.
Yes, absolutely. In particular, if you want to provide your own implementations for these things: suppose you’re defining a new type of IPersistentMap. Then you can’t afford defrecord’s built-ins, which would get in the way of your special versions.
If this is meant to help newcomers then IMHO it is necessary to stress “use regular maps first”. Because a lot of people coming from rigid OO languages (java) would not even think about it.
Yes, thanks; a number of other people mentioned the same thing. The updated flowchart reflects that option as a full peer as defrecord et al.
More like this, please. Could a similar flowchart be produced for when to use protocols?
Pingback: Intermediate Java | Chas Emerick offers a type definition form flowchart for Clojure
I notice one decision path problem.
1. need to extend an existing Java class
2. must be a named type
3. does not need to be referred statically from Java
…leads me to choose deftype, which is not possible given (1)
That first decision isn’t exclusively indicating that you need to extend a class — it includes implementing interfaces. So, there is a bit of ambiguity there. Of course, you’re in
gen-class-land there, but breaking things out more to eliminate the ambiguity would make the flowchart a fair bit bigger, I think.FWIW, I’d personally drop the named type requirement there, use
proxy, and justdefthe result of (class (create-proxy-instance …)) forinstance?checks and such (assuming that that’s why you need the named type).Pingback: Clojure で適切な型定義を選択するためのフローチャート | cemerick
Pingback: Flowchart de apoio a escolha tipos em Clojure « Codemountain, Paulo Suzart's Blog
Absolutelly helpful. Thanks.