Fork me on GitHub
#clojure-spec
<
2019-05-13
>
ben12:05:08

I have a bunch of specs that are quite repetitive to write out manually. Is there an easy way to define spec (e.g. w/in the current ns) with a function?

ben12:05:05

Essentially I have a map that looks something like:

{:event    :some-kw
 :metadata {:a 1 :b 2}}
where the spec of :metadata depends on the value of :event, which I want to check with spec

ben12:05:13

So I think I could do something like:

(s/def :event1/event ...)
(s/def :event2/event ...)
;; and so on

(s/def :event1/metadata ...)
(s/def :event2/metadata ...)
;; and so on

(s/def :event1/message (s/keys :req-un [:event1/event :event1/metadata]))
(s/def :event2/message (s/keys :req-un [:event2/event :event2/metadata]))
;; etc

(s/def ::message (s/or :event1/message :event2/message ...))
But this seems extremely inelegant. Feels like I’m missing something obvious but I’m not sure what

codonnell12:05:07

Sounds like a good use case for a multispec.

alexmiller12:05:42

Yes, also repetitive code can be made less repetitive with a macro

ben12:05:13

> One common occurrence in Clojure is to use maps as tagged entities and a special field that indicates the “type” of the map where type indicates a potentially open set of types, often with shared attributes across the types. yes it does 🙂 thank you, @codonnell

yogthos22:05:19

does anybody know if there's a workaround for this issue https://dev.clojure.org/jira/browse/CLJ-2482

yogthos23:05:28

I guess dropping down to clj 1.9.0 works

alexmiller23:05:22

The linked issue in the comments has some patches people have been using.

alexmiller23:05:47

Patches to Clojure that is

alexmiller23:05:07

I’m not sure which of the many approaches on there is really the best

alexmiller23:05:30

But we will definitely take a look at it in 1.11

yogthos23:05:05

thanks, and 1.9 seems to work so I'll just stick with that for the time being