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

0 votes
in Spec by
It would be useful to have specs that described spec forms, such that it was possible to go from a spec form like (s/keys :req [::a ::b] :opt [::c]) to a conformed version that allowed you to grab the parts without parsing the s-expression. This can be done by creating specs, thus allowing:


user=> (require '[clojure.spec :as s] '[clojure.spec.specs])
user=> (s/def ::aspec (s/keys :req [::a ::b] :opt [::c]))
user=> (def aspec-data (s/conform :clojure.spec.specs/spec (s/form ::aspec)))
user=> (pr aspec-data)
[:form {:s clojure.spec/keys,
        :args {:req [[:key :clojure.spec.specs/a] [:key :clojure.spec.specs/b]],
               :opt [:clojure.spec.specs/c]}}]
user=> (map val (-> aspec-data val :args :req))
(:clojure.spec.specs/a :clojure.spec.specs/b)


*Patch:* spec-forms.patch (a work in progress)

9 Answers

0 votes
by

Comment made by: saulshanabrook

Could I help out on this? Happy to work on it. It would be very helpful for me, trying parse the the specs from the :args and :ret in fspec.

0 votes
by

Comment made by: alexmiller

As you can see, there is an existing patch here with substantial work on it already (and some early review from Rich and Stu). The most useful help on this at the moment would be feedback on the gaps/open questions in it.

0 votes
by

Comment made by: alexmiller

Also, I should mention that I do not expect this to be finalized and included until we have finalized the spec forms themselves as they are still subject to change.

0 votes
by

Comment made by: akiel

In the current patch, keywords referencing specs are missing except for keys in s/keys. What would the right way to model the keywords? One way would be to add qualified-keyword? as fourth option to the or-spec of ::spec. Than ::spec could be used as spec for the spec arg in s/valid?, s/conform, s/form and others.

0 votes
by

Comment made by: alexmiller

Yeah, that would probably be good.

0 votes
by
_Comment made by: akiel_

Another observation: Currently {{s/and}} and {{s/or}} are allowed to contain no preds:


(defspec clojure.spec.alpha/and (s/* ::spec))
(defspec clojure.spec.alpha/or (s/* (s/cat :tag keyword? :pred ::spec)))


there should be either a clear semantic definition what an empty form will mean or we should just use {{s/+}} here and require at least one pred. For the and-form, we could define that {{(s/and)}} is the same as {{(s/and any?)}} and the same as just {{any?}}. For the or-form it is difficult, because {{s/conform}} returns tagged results. So conforming any value with {{(s/or)}} will result in {{::s/invalid}} which renders an empty or-form useless.
0 votes
by

Comment made by: alexmiller

There is a clear semantic definition for these - they are the same as clojure.core/and and clojure.core/or. As far as I'm concerned, this is all correct.

0 votes
by

Comment made by: akiel

Thanks. I see. The documentation in {{clojure.core}} defines that {{(clojure.core/and)}} returns {{true}} and {{(clojure.core/or)}} returns {{nil}}.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-2112 (reported by alexmiller)
...