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
kenny 2020-01-22T16:31:42.065100Z

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 https://github.com/clojure/spec-alpha2/wiki/Schema-and-select#unqualified-keys looks quite similar. The description makes it sound like that syntax will only be available for unqualified keys though.

alexmiller 2020-01-22T16:32:14.065300Z

That’s correct

kenny 2020-01-22T16:32:45.065800Z

Why not support qualified keys with that syntax?

kenny 2020-01-22T16:35:53.066400Z

(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]))
versus
(s/def ::result
  {::failed-requests [{::error-code    string?
                       ::error-message string?
                       ::id            uuid?}]})
The latter seems so much easier to read.

kenny 2020-01-22T16:37:16.067300Z

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

alexmiller 2020-01-22T16:37:38.067900Z

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

kenny 2020-01-22T16:37:52.068200Z

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

Filipe Silva 2020-01-22T16:38:16.068800Z

@alexmiller heya, if you're around can I ping you about https://clojurians.slack.com/archives/C1B1BB2Q3/p1579620754050400?

alexmiller 2020-01-22T16:39:23.069500Z

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

alexmiller 2020-01-22T16:39:44.069900Z

are you talking specifically about spec.alpha?

alexmiller 2020-01-22T16:40:29.070600Z

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

alexmiller 2020-01-22T16:41:08.070900Z

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

kenny 2020-01-22T16:42:10.071Z

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

Filipe Silva 2020-01-22T16:42:33.071300Z

yes that is what I meant

alexmiller 2020-01-22T16:43:13.072Z

not sure I understand the question

Filipe Silva 2020-01-22T16:43:30.072500Z

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

alexmiller 2020-01-22T16:43:59.072900Z

what are 1.10.520 and 1.10.597 applicable to?

kenny 2020-01-22T16:44:03.073100Z

If I'm understanding the syntax here https://github.com/clojure/spec-alpha2/wiki/Schema-and-select#unqualified-keys, you are no longer creating a reusable specification for the nested map.

alexmiller 2020-01-22T16:44:07.073400Z

oh cljs, sorry that got lost

alexmiller 2020-01-22T16:44:16.073700Z

spec.alpha is CLJ only

alexmiller 2020-01-22T16:44:50.074300Z

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

Filipe Silva 2020-01-22T16:45:33.074900Z

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

kenny 2020-01-22T16:46:13.075Z

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

alexmiller 2020-01-22T16:46:17.075200Z

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

alexmiller 2020-01-22T16:47:27.075400Z

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

alexmiller 2020-01-22T16:47:44.075700Z

yeah

alexmiller 2020-01-22T16:47:50.075900Z

I don't know anything on that

Filipe Silva 2020-01-22T16:48:05.076100Z

coolio, thanks for the direction!

kenny 2020-01-22T16:51:05.076200Z

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?

alexmiller 2020-01-22T16:52:40.076400Z

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

kenny 2020-01-22T16:53:21.076600Z

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.

alexmiller 2020-01-22T16:53:22.076800Z

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

alexmiller 2020-01-22T16:55:29.077Z

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

alexmiller 2020-01-22T16:56:33.077200Z

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

alexmiller 2020-01-22T16:56:54.077400Z

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

alexmiller 2020-01-22T16:57:46.077600Z

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".

kenny 2020-01-22T16:58:14.077800Z

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".