A Clojure type is a Java class, although a Clojure type definition is as easy as
(defrecord Point [x y])
(deftype Point [x y])
We’ll discuss the many commonalities that
defrecord share before diving into what makes each unique.
Both of these forms define a new Java class
Point, with two
final fields named
like protocols (and unlike other names in Clojure), type names are usually
CamelCase and not in
lower-dashed-case because they do
compile down to Java classes. Creating a new
Point instance is as simple as calling its
(Point. 3 4)—one argument per field in the same
order as given upon definition, whether it was defined as a
type or a record type. Because
they are regular fields on Java objects:
Accessing and updating their values is much faster than the same operations involving, for example, regular Clojure maps.
You can access fields of
defrecord instances by using Clojure’s
standard field access interop syntax:
(.x (Point. 3 4)) ;= 3
As-is, each field is typed as a default
java.lang.Object; this is often perfectly sufficient for many models, and a necessity if the types of some values in your model may vary. However, if you need to, you can declare fields to be primitive types by using the same sort of metadata that is used to declare the types accepted and returned by functions. You can also optionally hint nonprimitive fields as you would hint method calls, although hints do not change ...