Fork me on GitHub
#clojure-spec
<
2020-03-04
>
jrwdunham03:03:35

Are there best practices for how specs are intended to be identified with one another? I have the situation where I want to define spec ::data via (s/def ::data ::specs/jsonb) (where (s/def ::jsonb map?)). I want to define a map (`spec-casters`) from specs to the functions that can be executed to transform their values (for db insertion). The spec-casters-YES-PLEASE function (which I want to use) seems to do what I want, but I have already run into situations in development where (get spec-casters-YES-PLEASE (s/spec ::other-ns/data)) ;; => nil. I could use spec-casters-NO-THANKS but I would rather avoid that verbosity. This makes me wonder consider that there might be something inadvisable about this approach.

(def spec-casters-YES-PLEASE
  {(s/spec ::specs/jsonb) pg-cast-jsonb})
(def spec-casters-NO-THANKS
  {::specs/jsonb pg-cast-jsonb
   ::other-ns/data pg-cast-jsonb})

Alex Miller (Clojure team)04:03:18

I only understand about 30% of what you're trying to do, but (s/spec ::specs/jsonb) is a spec object without well-defined equality semantics so it seems like a bad choice for a key

jrwdunham04:03:49

Ok, the fact that specs lack well-defined equality semantics suggests that I should just be more explicit and use the NO-THANKS approach where the keys are just the namespaced keywords.

jrwdunham04:03:57

However, that seems to violate the intention of a key spec though, namely that its value should conform to it ...

Alex Miller (Clojure team)04:03:49

but you're not conforming

Alex Miller (Clojure team)04:03:46

you're just matching spec objects

Alex Miller (Clojure team)04:03:04

not using them for anything

jrwdunham04:03:57

right, that's true.