s/valid returns false, but s/explain prints "Success!"

225 views
Skip to first unread message

Markus Agwin

unread,
Sep 26, 2019, 8:41:20 AM9/26/19
to Clojure
Consider the following cloure.spec-alpha2 example:
  
(def v [0])
(s/def ::thevec vector?)
(s/def ::data (s/coll-of number? :kind ::thevec))

(s/valid? ::data v) ;;=> returns false, my expectation is that it should return true
(s/explain ::data v) ;;=> prints "Success!", which inconsistent to s/valid?

(s/def ::data2 (s/coll-of number? :kind vector?))
(s/valid? ::data2 v) ;;=> returns true, as expected

I expect (s/valid? ::data v) to return true, but it returns false. Moreover, s/explain prints "Success!" which is inconsistent to s/valid? for this example.
If I replace :kind ::thevec by :kind vector?, everything is fine. Why is that (the spec documentation says: ":kind - a predicate or spec").

Alex Miller

unread,
Sep 26, 2019, 8:54:03 AM9/26/19
to Clojure


On Thursday, September 26, 2019 at 7:41:20 AM UTC-5, Markus Agwin wrote:
Consider the following cloure.spec-alpha2 example:
  
(def v [0])
(s/def ::thevec vector?)
(s/def ::data (s/coll-of number? :kind ::thevec))

:kind is expected to be a predicate, not a spec. The doc string (in s/every) says ":kind - a pred that the collection type must satisfy, e.g. vector?"

so this should be:

(s/def ::data (s/coll-of number? :kind vector?))

With the prior, you're getting the keyword ::thevec as the predicate - that will look ::thevec up in whatever you pass it when used as a predicate.
 
(s/valid? ::data v) ;;=> returns false, my expectation is that it should return true

This matches above interpretation - (::thevec [0]) yields nil
 
(s/explain ::data v) ;;=> prints "Success!", which inconsistent to s/valid?

Agreed that's confusing. I think it's because the keyword as predicate returns nil instead of false but there is probably something to clean up here.
 

(s/def ::data2 (s/coll-of number? :kind vector?))
(s/valid? ::data2 v) ;;=> returns true, as expected

I expect (s/valid? ::data v) to return true, but it returns false. Moreover, s/explain prints "Success!" which is inconsistent to s/valid? for this example.
If I replace :kind ::thevec by :kind vector?, everything is fine. Why is that (the spec documentation says: ":kind - a predicate or spec").

The docs were wrong at one point in time, but this was fixed a while ago, only preds are supported here.  Where are you seeing the old docs?

https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/every doesn't have that and you won't see it in docstrings of current spec or spec 2 versions

Markus Agwin

unread,
Sep 26, 2019, 12:15:21 PM9/26/19
to Clojure
https://www.clojure.org/guides/spec are the docs I mentioned (search for first occurrence of :kind)
Thank you very much! I have foolishly only checked for s/explains's "Success!" string, having omitted the s/valid? check to save runtime.

Alex Miller

unread,
Sep 26, 2019, 12:26:10 PM9/26/19
to clo...@googlegroups.com

> On Sep 26, 2019, at 7:15 PM, Markus Agwin <markus...@gmail.com> wrote:
>
> https://www.clojure.org/guides/spec are the docs I mentioned (search for first occurrence of :kind)

Thanks, that’s just old, will fix.


>
Reply all
Reply to author
Forward
0 new messages