Thanks very much - that makes sense now.
I had read the guide, and not noticed the fact that conformed values can be
used as the *input* to specs. I looked again and the section on composing specs
with and and or makes no mention of it.
This behaviour does get a mention in the section on
I just did a quick scan of this but I think this is the expected behavior. s/or
conforms to a vector entry containing the tag of the path taken and the value.
s/and flows conformed values through each spec in the and, so order is
important. All you're seeing is the conformed or flowing into the
A quick follow-up - if I use s/assert instead of s/valid you can see the
problem with the s/or tag (:b in this case) getting into the assertion val
(s/assert (s/and (s/or :a (s/and #(empty? (::data %))
#(empty? (::path %)))
:b #(= (::val %)