Welcome! Please see the About page for a little more info on how this works.

0 votes
in Spec by

If I run

 (s/map-of (s/or :keyword keyword? :string string?) any?)
 {:a 1})

I get

{:a 1}

instead of

{[:keyword :a] 1}

Is that expected?

One consequence of that is that if I try to s/unform

 (s/map-of (s/or :keyword keyword? :string string?) any?)
 {:a 1})

I get an exception, because :a is not a valid conformed value for s/or.

I bumped into this issue using spec-tools. Its implementation of explain-data calls s/unform (https://github.com/metosin/spec-tools/blob/master/src/spec_tools/core.cljc#L446). I'm trying to figure out whether this is a spec or spec-tools issue.

1 Answer

+1 vote
selected by
Best answer

Yes, that is the default behavior for a couple reasons - first, map keys are typically simple values - keywords, strings, longs and the conformed values are identical, second it's better perf not to do this if you don't need it.

You can request this with :conform-keys true though if you need it, as it says in map-of docstring. https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/map-of

Should `s/unform` support the non conformed value in that case?
That's a good question, seems like yes so I agree that seems wrong. I don't remember a ticket for this but maybe there is one.
Thanks Alex!