I've been trying out Clojure spec and I often face situations in which I have to come up with a custom predicate function. Then sometimes these predicate functions require a custom generator. How can I share this predicate+generator bundle between different attributes?
(Also not so important but, can I call this bundle of predicate-fn + generator a spec?)
Example:
Suppose I have the custom predicate:
(defn local-date? [x]
(instance? LocalDate x))
and then I define a brand new generator function for it:
(defn local-date-generator []
(gen/fmap #(LocalDate/ofInstant (Instant/ofEpochMilli %) (ZoneId/of "UTC"))
(gen/large-integer)))
I can go on and define an attribute like:
(s/def :person/birth-date (s/with-gen local-date local-date-generator))
but then I would have to define this s/with-gen
every time I create a LocalDate attribute.
How can I abstract that away?
I've come to the conclusion that the right way to do that would be to define an attribute in a namespace (e.g myprojec.specs
) in which I create an attribute with that spec
(s/def ::local-date (s/with-gen local-date local-date-generator))
and then just re-use it elsewhere
(s/def :person/birth-date :myproject.specs/localdate)
What are the alternatives?