Where should I use defrecord in clojure?

I consider structs to be effectively deprecated so I don’t use them at all.

When I have a fixed set of well-known keys used in many map instances, I usually create a record. The big benefits are:

  • Performance
  • Generated class has a type that I can switch on in multimethods or other situations
  • With additional macro machinery around defrecord, I can get field validation, default values, and whatever other stuff I want
  • Records can implement arbitrary interfaces or protocols (maps can’t)
  • Records act as maps for most purposes
  • keys and vals return results in stable (per-creation) order

Some downsides of records:

  • Because records are Java class instances (not Clojure maps), there is no structural sharing so the same record structure will likely use more memory than the equivalent map structure that has been changed. There is also more object creation/destruction as you “change” a record although the JVM is designed specifically to eat this kind of short-lived garbage without breaking a sweat.
  • If you are changing records during development you probably need to restart your REPL more frequently to pick up those changes. This is typically only an issue during narrow bits of development.
  • Many existing libraries have not been updated to support records (postwalk, zip, matchure, etc etc). We’ve added this support as needed.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)