TheJach.com

Jach's personal blog

(Largely containing a mind-dump to myselves: past, present, and future)
Current favorite quote: "Supposedly smart people are weirdly ignorant of Bayes' Rule." William B Vogt, 2010

Clojure Tip: defstruct, deftype, defrecord

I'm currently learning Clojure, so I intend to document a few findings here that required at least a couple minutes of Googling around for me. The Clojure docs will tell you in the nitty-gritty the differences between defstruct, deftype, and defrecord, but I think an example of each is more beneficial. Also, some older examples of deftype are out of date! Trying to do things the obvious way, at least to me, resulted in a runtime error: "Expecting var, but Point is mapped to class user.Point". Anyway, enough babble, here's a working example of all three.


kevin@jachoonster ~/clojure-1.2.1 $ java -jar clojure.jar
Clojure 1.2.1
user=> (defstruct Point1 :x :y)
#'user/Point1
user=> (def p1 (struct-map Point1 :x 3 :y 4))
#'user/p1
user=> (println p1)
{:x 3, :y 4}
nil
user=> (println (:x p1))
3
nil
user=> (println (struct-map Point1 3 5))
{:x nil, :y nil, 3 5}
nil
user=>
user=> (deftype Point2 [x y]) ; actually creates a java class
user.Point2
user=> (def p2 (Point2. 8 9)) ; notice the '.'!
#'user/p2
user=> (println p2)
#<Point2 user.Point2@54083e1e>
nil
user=> (println (:x p2)) ; won't work
nil
nil
user=> (println (.x p2))
8
nil
user=>
user=> (defrecord Point3 [x y])
user.Point3
user=> (def p3 (Point3. 11 12))
#'user/p3
user=> (println p3)
#:user.Point3{:x 11, :y 12}
nil
user=> (println (:x p3)) ; works
11
nil
user=> (println (.y p3)) ; also works!
12
nil


For a handy flowchart for telling you which you should prefer (especially if you are wondering about proxy, gen-class, and reify), check out this page: http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/. (The author wrote a book on Clojure.)


Posted on 2011-09-10 by Jach

Tags: clojure, programming, tips

Permalink: https://www.thejach.com/view/id/204

Trackback URL: https://www.thejach.com/view/2011/9/clojure_tip_defstruct_deftype_defrecord

Back to the top

davem July 13, 2013 01:43:59 PM nice!
mars0i October 17, 2013 09:50:12 AM Accessing records with :<field> was 3 orders of magnitude faster than accessing them with .<field> , in some quick tests I did.
Back to the first comment

Comment using the form below

(Only if you want to be notified of further responses, never displayed.)

Your Comment:

LaTeX allowed in comments, use $$\$\$...\$\$$$ to wrap inline and $$[math]...[/math]$$ to wrap blocks.