Clojure's defrecord - how to use it?

Here's how you define your record:

(defrecord MyType [a b])

Note that in Clojure you don't typically define "methods" within your record type itself (the exception is if you want to directly implement a Java interface or a protocol).

A basic constructor (prefixed with ->) gets generated automatically for free:

(def foo (->MyType [1 2 3] [4 5 6]))

foo
=> #user.MyType{:a [1 2 3], :b [4 5 6]}

You can then write more sophisticated constructor functions that use this, e.g.

(defn mytype-with-length [n]
  (let [a (vec (range n))
        b (vec (range n))] 
    (->MyType a b)))

(mytype-with-length 3)
=> #user.MyType{:a [0 1 2], :b [0 1 2]}

And "mutate-and-return" also comes for free - you can just use assoc:

(assoc foo :b [7 8 9])
=> user.MyType{:a [1 2 3], :b [7 8 9]}

Clojure defrecord example:

;;define Address record

(defrecord Address [city state])

;;define Person record

(defrecord Person [firstname lastname ^Address address])

;;buid the constructor

(defn make-person ([fname lname city state]
               (->Person fname lname (->Address city state))))

;;create a person

(def person1 (make-person "John" "Doe" "LA" "CA"))

;;retrieve values

(:firstname person1)
(:city (:address person1))

Tags:

Clojure