Fork me on GitHub
#clojure-spec
<
2022-01-10
>
slipset20:01:52

We were discussing at work today, and this cropped up:

ardoq.core> (spec/def :foo/foo string?)
;; => :foo/foo
ardoq.core> (spec/def :foo/bar int?)
;; => :foo/bar
ardoq.core> (spec/def ::test (spec/keys :req [:foo/foo]))
;; => :ardoq.core/test
ardoq.core> (spec/valid? ::test {:foo/foo "foo" :foo/bar 1})
;; => true
ardoq.core> (spec/valid? ::test {:foo/foo "foo" :foo/bar "1"})
;; => false
In the last example, :foo/bar is not mentioned in ::test but seems to still be checked. What am I not seeing?

mpenet20:01:44

s/keys will cause all namespace qualified keys to be checked

slipset20:01:48

Right, it’s there in the docstring: > In addition, the values of all namespace-qualified keys will be validated > (and possibly destructured) by any registered specs. TIL.

slipset20:01:53

Which still is a bit strange since then:

ardoq.core> (s/def :foo/foo string?)
;; => :foo/foo
ardoq.core> (s/def :foo/bar int?)
;; => :foo/bar
ardoq.core> (s/def ::test (s/keys :req []))
;; => :ardoq.core/test
ardoq.core> (s/valid? ::test {:foo/foo "foo" :foo/bar "1"})
;; => false
ardoq.core> 
Which makes you wonder why even bother with :req ?

mpenet20:01:14

You still need to be able to express what key set is required

mpenet20:01:35

I guess for opt it's debatable. It's mostly for gen there

mpenet20:01:48

Also if you have a ns qualified key that points to a value that does not conform to the spec with the same key, no matter where, it's likely a smell. Integrant pushes toward this for instance, I am not a fan of that part of the lib.