Fork me on GitHub
#clojure-spec
<
2019-06-08
>
misha11:06:45

is there a better way to make s/conform label values conformed to s/coll-of other than wrap s/coll-of in s/or?

(s/conform (s/coll-of any?) [])
=> []
(s/conform (s/or :vector (s/coll-of any?)) [])
=> [:vector []]

misha11:06:02

need it for a recursive spec, to uniformly label all tree nodes, to dispatch on conform-labels in a case

Alex Miller (Clojure team)12:06:58

Can’t say I have any better idea other than to do this walk after the conform instead

misha13:06:14

(re-)labeling conformed tree is doing (almost) double work. and implies having double knowledge of "how nodes look like" in the code: in spec and inline during the walk. Or, worse, dispatching with call to s/valid? or s/conform again, which will conform entire subtree from current node down. the (s/or) wrappers are hacky, but not that bad for irregular trees, all things considered:

(s/def :user/leaf int?)
(s/def :user/foo (s/coll-of (s/or :user/leaf :user/leaf :user/bar :user/bar :user/foo :user/foo)))
(s/def :user/bar (s/coll-of (s/or :user/leaf :user/leaf)))
(s/def :user/tree
  (s/or
    :user/leaf :user/leaf
    :user/foo :user/foo))

(s/conform :user/tree [[1] 2 [[3]]])
;;=> [:user/foo [[:user/bar [[:user/leaf 1]]]
                 [:user/leaf 2]
                 [:user/foo [[:user/bar [[:user/leaf 3]]]]]]]

Alex Miller (Clojure team)14:06:17

my complaint is basically that you're turning conform into a meat grinder to get a specific data structure you want, and that's not what it's designed for - it's designed to tell you a) is this valid? and b) why?

potetm15:06:36

I thought it was also deigned to be “destructuring on steroids”

potetm15:06:54

(I forget where I heard that.)

Alex Miller (Clojure team)15:06:45

it has some capability in that regard when conforming regex for syntax structures in macros, but even then it's not destructuring, more making structures amenable to destructuring