Fork me on GitHub
#clojure-spec
<
2019-04-25
>
pyr18:04:45

now that usage of spec is pervasive and given the fact that defrecord produces handy functions

pyr18:04:00

would it make sense to add another one which would create a predicate

pyr18:04:21

to test for protocol satisfaction?

pyr18:04:21

i.e (defrecord MyRecord) ;; => implies ->MyRecord, map->MyRecord, and MyRecord?

borkdude18:04:32

you mean like (instance? Foo (->Foo))?

drone18:04:35

where MyRecord? is a predicate returning true if its argument is an instance of the backing MyRecord class and/or it has the required record fields with values that match some field specs?

pyr18:04:22

the former

pyr18:04:49

meh, now that I say it out loud, it makes more sense for protocols

pyr18:04:51

nevermind

drone18:04:00

I think there’s value in spec’ing fields of records (just as there is in spec’ing plain-old maps). as for protocols there are some technical reasons they aren’t supported. the workaround that was thrown around in the past is having protocol method implementations call a spec’d function

drone18:04:10

re: records. it sounds like most people don’t use them (?) and stick with maps and occasionally add some :tag or :type entry to achieve the ability to determine the “kind” of map

drone18:04:15

not sure if records were too JVM-centric or if they feel too restrictive to the free-spirited majority opposed to types

borkdude18:04:27

weren’t they a little bit better for performance?

borkdude18:04:09

also in Clojure Applied it is recommended for “domain” objects, although I rarely see them used

pyr18:04:15

I like the fact that you can directly attach protocols

drone18:04:24

yeah, you get fast single dispatch (like a Java class, since they’re implemented as Java classes)

Alex Miller (Clojure team)18:04:39

fwiw, I would probably de-emphasize records in a 2nd ed of Clojure Applied

pyr18:04:49

extend-via-metadata will help with that

drone18:04:37

I use them all over in machine learning, data analysis, and program analysis work

pyr18:04:39

@alexmiller so fewer records but protocols still emphasized, correct?

pyr18:04:21

spec and qualified keywords make maps more attractive indeed

pyr18:04:41

breaking out of the protocol + record-implementation will be hard

pyr18:04:51

especially in our component heavy codebase

drone18:04:59

seems like there’s plenty of boiler plate that packaging things as records could manage for you

drone19:04:17

defrecord-spec where each field has an associated spec. spec’d record creation functions, reference the field specs elsewhere when performing a subset select with select

drone19:04:17

the only place I see them being awkward is when you’re building up the fields for a record. which I believe is an example Rich referenced in Maybe Not or another recent-ish talk

drone19:04:29

but, it’s not that bad to just use maps with a sub-select spec until you’ve gathered all the required fields and then throw it into a record

drone19:04:57

feels like serialization is motivating much of this. e.g., you may have some fields that are handy but can be computed from other fields in the map. so when you serialize maps for storage in a database, you drop those derived fields. but then results from the database are “incomplete” and processing is required to generate the derived fields before you could construct the record

drone19:04:15

datomic killed records, is what I’m saying (with tongue in cheek)