Fork me on GitHub
#clojure-spec
<
2019-07-25
>
jjttjj04:07:40

is there an example out there of a spec on arguments that look like

([a])
([a b])
([a b c])
([a b c d])
([a b c d e])
where later arguments are optional and can be omitted and replaced with defaults? I feel like there has to be a better way than just a big s/alt with a bunch of s/cats but I can't think of it right now

Alex Miller (Clojure team)05:07:36

(s/cat :a ::a (s/? :b ::b (s/? :c ::c (s/? :d ::d (s/? :e ::e)))))

Alex Miller (Clojure team)05:07:13

but also, sometimes s/alt is clearer, just depends

seancorfield05:07:20

I didn't realize you could cascade s/? like that... I've only seen (s/cat :a ::a :b (s/? ::b)) before I think?

seancorfield05:07:16

Hmm, according to the docs/source, s/? can only take a single pred-form @alexmiller

maxp05:07:57

how to write spec that conforms input value to positive int or to zero when value missing?

maxp05:07:58

like that

(s/def ::offset
  (s/or
    :nil (s/and nil? (s/conformer (constantly 0)))
    :int (s/and int? #(<= 0 %))))

maxp05:07:31

but it returns vector (s/conform ::offset nil) [:nil 0]

Alex Miller (Clojure team)06:07:11

should be s/cats in there

Alex Miller (Clojure team)06:07:56

(s/cat :a ::a :an (s/? (s/cat :b ::b :bn (s/? (s/cat ...

👍 4
Alex Miller (Clojure team)06:07:51

@maxp imo, you should not do that with specs

Alex Miller (Clojure team)06:07:44

s/or always conforms to a tagged result where the tag matches the branch that was taken

Alex Miller (Clojure team)06:07:17

but general data transformation is best applied outside spec, not as part of conforming anyways

maxp06:07:45

thank you

maxp07:07:30

is it possible to "attach" some human readable message to the spec to get it in (explain-data) ?

carkh07:07:28

@maxp check the expound library

carkh07:07:32

not exactly what you're asking but it helps

jjttjj15:07:12

Is there a way to get the resolved value for a given spec? I have a set I generate as a spec and I'm wondering if there's a way to access that set from the spec api:

(s/def ::sec-type (set (map str (Types$SecType/values))))
(s/describe ::sec-type) ;;=> (set (map str (values))) ;can't eval this

seancorfield15:07:14

@jjttjj Try s/form instead.

seancorfield15:07:29

s/describe returns an "abbreviated" version.

jjttjj15:07:55

perfect, thanks again sean