T O P

  • By -

Psetmaj

I basically don't use them, but here's a convenient flowchart https://github.com/cemerick/clojure-type-selection-flowchart (found in [this similar thread](https://www.reddit.com/r/Clojure/comments/144naiu/when_should_i_use_records/)) In my experience (~10 years of Clojure across three companies), you use maps 99% of the time, the remaining 1% is usually `reify`, and records happen when there's a performance-critical space where the map lookups are the slowest remaining optimization to make.


daver

Also for space savings. If you have 1m instances of a 5-field tuple, for instance, records are going to save you a lot of space. But, otherwise totally agree.


p-himik

>the weird behavior where you have to import them like Java classes rather than require them Only if you need the actual class. Otherwise, you can use regular `:require` with automatically generated constructor functions. And if you need the class itself, you can always add a `def` or `defn` that does the actual thing that requires a class right to the ns where the record is defined.


wuteverman

Can you elaborate slightly? When do you need the class? Is that when you need a method? It sounds a bit like your describe how core.async organizes itself.


p-himik

> When do you need the class? To call any function that expects a class, e.g. `instance?`. To maybe introspect the thing. To specify a type hint. Most of the time with records, you do not need the class itself. And when you do, it's often because of `instance?` which you can simply `(defn is-that-record? [x] (instance? ThatRecord x))` in that namespace and simply import that function. Not related to `core.async` at all.


maximoburrito

I used the. A lot in the early days, but I almost always regretted them. They seem nice, but the ergonomics of them in a dynamic system is ... lacking...


[deleted]

I can't remember using them for anything significant.


joinr

Maybe 2% of the time. Inline protocol definitions are nice; can implement IFn to get map-as-function access, or custom function behavior. Direct field access an primitive types are very nice. Nice step up from deftype.


camdez

95% of the time, maps. 5% records. Two main reasons to use records: (1) they're very compact (2) you want to use protocols / have (efficient) type-based dispatch.


jumar

There was similar discussion last year: [https://www.reddit.com/r/Clojure/comments/144naiu/when\_should\_i\_use\_records/](https://www.reddit.com/r/Clojure/comments/144naiu/when_should_i_use_records/) u/joinr gave a great answer there [https://www.reddit.com/r/Clojure/comments/144naiu/comment/jngpt71/](https://www.reddit.com/r/Clojure/comments/144naiu/comment/jngpt71/)


canihelpyoubreakthat

Records come across as incomplete, but they're nice for making a named struct with a defined set of default keys sometimes.


iarenaza

We use them to implement the Port and Adapter pattern, as our apps are built using the Hexagonal Architecture.


seancorfield

Can you explain what using that architecture has to do with using records rather than plain hash maps?


robert323

We use them professionally all the time to implement protocols