Fork me on GitHub

@schmee spec-tools has a spec visitor, which traverses specs recursively, one use case is the recursive describe. Has regression (& progression) tests for all core-specs:


cool, I’ll try it out later today!


I'm still new with spec. Is it considered unidiomatic to use conformers to coerce, as in the following. What would be the idiomatic approach

(s/def :conformers/int
  (s/conformer (fn [x]
                   (integer? x) x
                   (re-matches #"\d+" x) (edn/read-string x)
                   :else :cljs.spec.alpha/invalid))))

(s/def :data.subscription/quantity :conformers/int)


I've asked a stackoverflow question just so in case someone answers it won't get lost in the mists of slack history


@danieleneal AFAIK the jury is still out on that one


but spec-tools mentioned above has a lot of stuff for that


ah cool - so it might be a case that the boundaries around idiomatic use will emerge with time


my 2 cents go to separating conforming from specs. There is CLJ-2116 for it.


@ikitommi what do you do for the coercing bit


@danieleneal spec-tools but I'm biased as co-authoring the lib ;) haven't seen anything else for it, really. Cognitect people have said many times that runtime transformations are not is scope of spec :(


Got a bit of a spec design and validation question: We've got a few messages flying around and are working on adding spec's for them now (i know, wrong way round), the messages generally look like this:

{:type "msg1"
 :version "1.0.0"
 :payload {:msg1-specific-key "val"}}
The trouble is the payload key being reused across all the the different :type fields, making writing a spec for :payload very tricky as it lacks the context of the :type value. I'm thinking we should have gone for a flat structure:
{:type "msg1"
 :version "1.0.0"
 :msg1-specific-key "val"}
A multi spec would then have something to go on. Just wondering if there's anything I've missed that would let us write a decent :payload spec? Feels like the current format just doesn't work with spec very well at the moment.


@tcoupland if you're using a multimethod with your multi-spec you can implemtent arbitrarily complex dispatch logic.


You can get at what's in the :payload, and transform it, use or to pick from multiple options.


Of course, if your data looks really similar that might be tricky, but then how specific does your spec really need to be? 🙂


yeah, i'm worried that the dispatch function would get a bit nuts, also it wldn't really solve the problem of attaching the type to a specific payload


Time for version "2.0.0" 😉


I was fiddling with some spec tooling last night, and there is something I'd like to express that is difficult in spec. I'd like to be able to express "this is a collection of As for some comparable type A".


I don't know much about types, but I think in Haskell this can be expressed as Comparable a => List a. It would be useful in situations like spec-ing the args of clojure.core/sort. Especially since vectors are comparable


That way you could express "this is a collection of As or a collection of vectors of As for some comparable scalar A"


Can't you write:

(s/coll-of #(instance? Comparable %))


Seeing how spec is working on values, you don't really need type constraints


Yes, totally. It's on the data/test-generation side that this becomes a little awkward.


Ah, OK. Then yes I see your point 😉


I'd like my cake and I'd like to eat it too 🙂


I think that (s/coll-of (s/and any? #(instance? Comparable %))) is closest in meaning to Haskell's Ord a => List a


Probably will get super slow though