Clojure records are a mechanism for creating data abstractions.

Records are instantiated with a list of the field values:

Explicit nils are required to create a record without some field:

Records are immutable, but new ones can be created by mutating an existing record

Multiple fields can be set by merging a map into a record

Notice that records print in a format that cannot be evaluated. Evaluating the printed form throws an exception.

My understanding is that a future Clojure will address some of the current shortcomings with records, but in the meantime…

The code below provides a generic mechanism for enhancing records in the following ways:

Generate constructor functions that take maps.

Print records in a form that can be evaluated.

The new defrecord2 macro is invoked like defrecord:

This generates a constructor function that takes a map. Using named parameters is clearer than the positional constructors that are provided by plain records.

It is not necessary to pass nils in for the missing fields.

The enhanced records can be mutated by passing in a map of new values:

And of course the records are now printing in a form that can be evaluated. This works both from print and from pprint:

A final benefit of defrecord2 is that the records can be used without importing the underlying record class. This avoids a bit of import complexity.