clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
bbrinck 2020-03-01T19:42:23.079400Z

In spec2, how would I use a set spec to match against a symbol that happens to be the name of a macro?

> (s/def ::is-foo #{foo})
:expound.alpha2.core-test/is-foo
> (s/form ::is-foo)
#{foo}
> (s/explain ::is-foo 'foo)
Success!
nil
> (s/def ::is-or #{or})
:expound.alpha2.core-test/is-or
> (s/form ::is-or)
#{clojure.core/or}
> (s/explain ::is-or 'or)
or - failed: #{clojure.core/or} spec: :expound.alpha2.core-test/is-or
nil
Or should I avoid using set specs in this case?

alexmiller 2020-03-01T20:08:46.080400Z

there is actually a known issue around sets of symbols (kind of a collision with symbol as function reference, which need qualification)

alexmiller 2020-03-01T20:13:12.081600Z

a workaround for the moment is (s/register ::is-or (s/resolve-spec #{'or}))

1šŸ‘1
bbrinck 2020-03-01T21:06:05.083800Z

Perhaps just a different view on the same underlying issue, but it looks like spec2 is using clojure.core/and instead of the and symbol for combining specs in :req?

> (s/def :keys-spec/name string?)
> (s/def :keys-spec/age int?)
> (s/def :key-spec/state string?)
> (s/def :key-spec/city string?)
> (s/def :key-spec/zip pos-int?)
> (s/def :keys-spec/user2 (s/keys :req [(and :keys-spec/name
                                           :keys-spec/age)]
                                :req-un [(or
                                          :key-spec/zip
                                          (and
                                           :key-spec/state
                                           :key-spec/city))]))
> (s/form :keys-spec/user2)
(clojure.alpha.spec/keys :req [(clojure.core/and :keys-spec/name :keys-spec/age)] :req-un [(clojure.core/or :key-spec/zip (clojure.core/and :key-spec/state :key-spec/city))])

bbrinck 2020-03-01T21:09:25.084300Z

I would have expected :req [(and :keys-spec/name :keys-spec/age)]

favila 2020-03-01T22:35:41.086800Z

Iā€™m pretty sure spec1 does the same? I think the form (in spec1) gets rewritten to a predicate fn in a trivial way. Iirc you can even use your own predicates instead of only and/or