Clojure

[spec] Add specs for spec forms

Details

  • Type: Feature Feature
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: Release 1.9
  • Fix Version/s: Release 1.10
  • Component/s: None
  • Labels:
  • Approval:
    Incomplete

Description

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)

Activity

Hide
Saul Shanabrook added a comment -

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.

Show
Saul Shanabrook added a comment - 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.
Hide
Alex Miller added a comment -

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.

Show
Alex Miller added a comment - 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.
Hide
Alex Miller added a comment -

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.

Show
Alex Miller added a comment - 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.
Hide
Alexander Kiel added a comment -

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.

Show
Alexander Kiel added a comment - 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.
Hide
Alex Miller added a comment -

Yeah, that would probably be good.

Show
Alex Miller added a comment - Yeah, that would probably be good.
Hide
Alexander Kiel added a comment -

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.

Show
Alexander Kiel added a comment - 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.
Hide
Alex Miller added a comment -

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.

Show
Alex Miller added a comment - 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.
Hide
Alexander Kiel added a comment -

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

Show
Alexander Kiel added a comment - Thanks. I see. The documentation in clojure.core defines that (clojure.core/and) returns true and (clojure.core/or) returns nil.

People

Vote (23)
Watch (19)

Dates

  • Created:
    Updated: