Fork me on GitHub

I really like how succinct spec-tools data-specs are. It takes 17 lines worth of specs for a map that has a key that has a collection of maps down to 3 lines. Will Spec2 be able to do this as well? The syntax described here looks quite similar. The description makes it sound like that syntax will only be available for unqualified keys though.


Why not support qualified keys with that syntax?


(s/def ::error-code string?)

(s/def ::error-message string?)

(s/def ::id uuid?)

(s/def ::failed-request
  (s/keys :req [::error-code ::error-message ::id]))

(s/def ::failed-requests
  (s/coll-of ::failed-request))

(s/def ::result
  (s/keys :req [::failed-requests]))
(s/def ::result
  {::failed-requests [{::error-code    string?
                       ::error-message string?
                       ::id            uuid?}]})
The latter seems so much easier to read.


Sorry, I don't follow. The latter could easily expand to do exactly as that doc describes.


Well, I suppose the nested map wouldn't have a name.

Alex Miller (Clojure team)16:01:38

the objective here is not just to validate but to build a library of reusable (ie named + registered) specifications


So Spec1 forces you to do that with unqualified keys. Why has that changed with Spec2?

Alex Miller (Clojure team)16:01:13

not sure I understand the question


If I'm understanding the syntax here, you are no longer creating a reusable specification for the nested map.


Well, that I guess that applies for key & value in that ::order spec. Nothing is reusable.

Alex Miller (Clojure team)16:01:17

well, you are in the schema, but not in the sub levels. as unqualified names, they often are ambiguous

Alex Miller (Clojure team)16:01:27

you still can do like you did in spec 1 (relate unqualified keys to qualified specs) but it's not constrained to the unqualified name match and it's optional


To be clear, the issue with something like this

(s/def ::result
  {::failed-requests [{::error-code    string?
                       ::error-message string?
                       ::id            uuid?}]})
Is that the nested map is not named?

Alex Miller (Clojure team)16:01:40

you're inventing syntax here, it can't be just considered in isolation


Fair enough. I mean like this

(s/def ::order 
  (s/schema {:purchaser string? 
             :due-date inst?
             :line-items (s/coll-of (s/schema {:item-id pos-int? 
                                               :quantity nat-int?})
                           :kind vector?
                           :min-count 1
                           :gen-max 3)}))
but with every key qualified instead of unqualified.

Alex Miller (Clojure team)16:01:22

this now occupies the "map" slot in the language of specs, which may have other uses

Alex Miller (Clojure team)16:01:29

certainly, this goes against the grain of naming and registering the specifications. names have multiple utility in spec - they are used for spec reuse, but also in things like explain reporting, and I don't remember what else

Alex Miller (Clojure team)16:01:33

none of this rules out the possibility of adding more support for concise definition of multiple specs in tandem

Alex Miller (Clojure team)16:01:54

or even extension to support this in the future, but it's not our top concern

Alex Miller (Clojure team)16:01:46

and if we were going to do so, it would be driven by a top level problem, not just "it's a thing we can do".


Understood. I don't think it necessarily goes "against the grain of naming and registering".

(s/def ::order
  (s/schema {::purchaser  string?
             ::due-date   inst?}))
That would register the ::purchaser spec as string? , ::due-date as inst? and ::order as "s/keys".

Alex Miller (Clojure team)16:01:23

what do you mean by 0.1.x and 0.2.x?

Alex Miller (Clojure team)16:01:44

are you talking specifically about spec.alpha?

Alex Miller (Clojure team)16:01:29

0.1.x is Clojure 1.9 era and 0.2.x is Clojure 1.10 era

Alex Miller (Clojure team)16:01:08

I don't think there were any breaking changes between those

Filipe Silva16:01:33

yes that is what I meant

Filipe Silva16:01:30

trying to update from cljs 1.10.520 to `1.10.597` causes my app to have a runtime error for optimized builds on what seems to be something spec related, so I thought there might be a breaking change

Alex Miller (Clojure team)16:01:59

what are 1.10.520 and 1.10.597 applicable to?

Alex Miller (Clojure team)16:01:07

oh cljs, sorry that got lost

Alex Miller (Clojure team)16:01:50

the cljs spec impl is inside ClojureScript so the stuff above does not directly correlate

Filipe Silva16:01:33

ah I see... so maybe I should ask about cljs.spec.alpha in #clojurescript instead

Alex Miller (Clojure team)16:01:50

I don't know anything on that

Filipe Silva16:01:05

coolio, thanks for the direction!