Fork me on GitHub
#clojure-spec
<
2021-09-25
>
apbleonard06:09:38

When conforming a s/multispec (with clojure.spec.alpha) is it possible to be returned which multimethod dispatch value was used, similar to the "tags" returned when conforming an s/or?

dgb2307:09:12

Not sure if I understand the question:

user=> (require '[clojure.spec.alpha :as spec])
nil
user=> (defmulti tag ::tag)
#'user/tag
user=> (defmethod tag :foo [_] (spec/keys :req [::tag]))
#object[clojure.lang.MultiFn 0x522b2631 "clojure.lang.MultiFn@522b2631"]
user=> (spec/def ::tagged (spec/multi-spec tag ::tag))
:user/tagged
user=> (spec/conform ::tagged {::tag :foo})
#:user{:tag :foo}

dgb2307:09:38

Do you mean that after conforming the above, you somehow forget that :user/tag was used to dispatch and you want to explicitly encode that in the conformed value?

apbleonard11:09:22

Well not quite. In your example I'd like the dispatch value :foo to be explicitly encoded in the conformed result.

apbleonard12:09:13

...as per https://www.cognitect.com/cognicast/103: "In spec, there is valid question mark, just a validator that's Boolean. But, the more interesting function is conform, which takes the data and a spec, and gives you a de-structured, labeled version, if you will, of the data where every branching point that was detected, the result of it was labeled. If you had some arbitrary complex predicate that you needed to satisfy and it was one of three–X or Y or Z–and it matched Y, there'll be a key there that says Y is what they supplied. Your code won't need to figure that out again because the spec did that, de-structured it, and labeled it. There's a path system in spec. It's part of the design. Everywhere there's a branch, there's a label. "

apbleonard14:09:43

I guess I need an s/or. I liked the clear dispatching and the hierarchical keys offeredby multispecs though.