Fork me on GitHub
Oliver George00:06:18

Thanks again Alex. I suspected that might be the case.


@alexmiller: is there a roadmap online anywhere for what changes are definitely coming? Or even something that discusses some of them?


Oh well 🙂

Alex Miller (Clojure team)01:06:06

there are definitely changes around instrument and the c.s.test namespace coming soon

Alex Miller (Clojure team)01:06:15

and map-of and coll-of work is under way

Alex Miller (Clojure team)01:06:33

there are a bunch of other things on the list but I don’t how that will all pan out


Excellent! I don’t think I’ve actually said this to y’all before about spec, but thanks 🙂. I’ve been working with it for about a week, and it’s just terrific work.


Just how powerful it is didn’t even fully sink in until I’d dived into it for a while.


If I have (s/keys :req-un [::foo ::bar]), am I correct that something in clojure.spec will expect ::foo and ::bar to exist as specs, for some operations? I was trying to add stuff to to support generative testing (by writing custom generators for db-spec, java.sql.Connection, and java.sql.PreparedStatement etc) and I started getting errors that the "unqualified" keys in some of my specs didn’t resolve...


That wasn’t obvious to me from the documentation about s/keys and the -un keys in maps — but it makes sense from the p.o.v. of actually trying to generate maps to pass into functions whose arguments are spec’d as s/keys...


(FWIW, folks can look at the work-in-progress experiment on a gen-testable java.jdbc spec here )

Alex Miller (Clojure team)02:06:31

if you’re trying to gen keys in a map, then yes you would need them to have a definition

Alex Miller (Clojure team)02:06:49

otherwise how would you gen them?

Alex Miller (Clojure team)02:06:01

are you getting this while gen’ing or during something else?


During gen’ing. And, yes, it makes sense. It just wasn’t obvious from the docs...


Because I missed this (very important) phrase "These variants specify namespaced keys used to find their specification"


I just didn’t associate the ::first-name etc with the specs given two examples above since they were "unqualified keywords" in my mind.


Not sure what to suggest to make that clearer…? Perhaps repeat the specs in the :unq/person example?

(s/def ::first-name string?)
(s/def ::last-name string?)
(s/def ::email ::email-type)

(s/def :unq/person
  (s/keys :req-un [::first-name ::last-name ::email]
          :opt-un [::phone]))


(and now I notice that ::phone is not provided as a spec anywhere on that page)


Obvious in hindsight, of course.

Oliver George08:06:34

This is a thought in passing. Often we want confidence that some data is fully realized. It seems like a challenging case. We have realized? as a test and could write a recursive ::realized spec. It is challenging since displaying the data in reporting might "realize" it. So the test modifies the data.

Oliver George08:06:11

Perhaps not a clojure.spec domain issue... data is valid, it just doesn't exist yet!

Oliver George08:06:51

We've seen cases where lazy and dynamic aspects cause surprises. Right now we're considering a class of problems where delayed evaluation makes debugging harder.

Oliver George08:06:30

Just raising in case it's something of interest as spec matures.


how can i spec this structure?

{::items-by-id {"id-1" {::id "id-1"
                  ::title "first-item"} 
          "id-2" {::id "id-2" 
                  ::title "second-item"}}}
i would like to spec that every item ::id is the same id as its key on the parent map.


Are optional docstrings for s/def (CLJ-1965) something you'd like to have or were they left out intentionally?

Alex Miller (Clojure team)12:06:06

@olivergeorge: I don’t expect spec is going to add anything re lazy/realized data

Alex Miller (Clojure team)12:06:38

@seancorfield in my next guide pass I will see if I can do anything to bring that out


Is there a suggested way to maintain metadata about which keys a spec is concerned:

(s/def :bill/delivery inst?)
(s/def :bill/pickup inst?)
(s/def :bill/pickup-gt-delivery (fn [{:keys [bill/delivery bill/pickup]}] (> pickup delivery)))
(s/def ::bill (s/and (s/keys :req [:bill/delivery :bill/pickup])

;some lookup
{:bill/pickup-gt-delivery [:bill/delivery :bill/pickup]}

Alex Miller (Clojure team)21:06:05

no, I don’t think so

Alex Miller (Clojure team)21:06:30

user=> (s/explain-data ::bill {})
{:clojure.spec/problems {[] {:pred [(contains? % :bill/delivery) (contains? % :bill/pickup)], :val {}, :via [:user/bill], :in []}}}

Alex Miller (Clojure team)21:06:06

The explain-data will tell you what it’s missing in the form of predicates but that’s not what you’re asking

Alex Miller (Clojure team)21:06:51

(btw, as of the next alpha, you’ll be able to rewrite pickup-gt-delivery as (fn [{:bill/keys [delivery pickup]}] (> pickup delivery)) )


@alexmiller: cool. thanks for the response!