Fork me on GitHub
Alex Miller (Clojure team)00:06:24

the terminology drifted a bit during dev


Is there anything planned in terms of having predicates/specs with custom error messages/data? I’m speaking from a validation perspective, because the alternative is to wrap explain-data


it also seems that for related reasons, I would be writing a conform-or-explain! function that throws with explain-data when the conform fails


While I’m asking, it would be a useful feature to be able to somehow get the path at which a predicate is being run. This one is coming up as I’m trying to secure a datomic transaction wrapper by looking up if a user has access to a certain :db/id that’s potentially nested within a map.


@adambros: which alpha are you using? I thought they'd added a path result in explain in one of the later alpha builds.


i’m referring to accessing the path from within the predicate


might be bad idea (TM) but its something that would ameliorate my problem


But each predicate only knows what it is called on -- it can't know the whole path, since a predicate is a general function.


If your predicate is string? for example...


it could if there was a dynamic var *path* or something. I think i could solve this another way so its fine


Dynamic vars are evil 😆


im more interested in my other questions, so i probably shouldn’t have asked about it


Ok, what are the other questions? I think I missed those...


custom error message for predicates/specs something like (s/def :title (s/either string? {:message “invalid title"}))


where either’s predicate either succeeds or puts the 2nd argument in explain-data’s result


and the other was about a potential builtin for validation, conform-or-explain! that throws if it cant conform


I get the impression from the discussions here that explain-data is indeed the preferred basis for any custom error messages. I think there is a JIRA ticket for something like conform-or-explain tho'... let me go look...


Hmm, no, maybe it was just a discussion on the clojure-dev mailing list.


seems like it’d be a simple wrapper, with an extra arity for a function to call with the data when it fails


(defn conform-or-explain [spec x & [on-fail]] ...)


by default it’d throw the error in an ex-info


Ah, I remember now, it was a valid or explain wrapper that was discussed -- for use in :pre assertions.


But, yeah, I think the wrapper is so easy to write -- and some folks would want to throw explain-data and some would throw explain as a string so I don't think there's a one size fits all here.


fair enough, sounds like I just need to have some sort of spec namespace that declares these wrappers


One of the great things about Clojure: it's easy to write an adapter layer to make the supplied libraries match each specific application's needs 🙂


We have a bunch of wrappers at World Singles. We have several of our own string functions in a namespace that supplements clojure.string.


We also have some collection functions, a bunch of date stuff, wrappers around system level stuff. Wrappers around JDBC stuff (and, heck, I maintain!).


anyone know of a good way to define a spec for an atom holding a piece of structured data?


seems like I would need to deref in order to perform the spec, so a lot of wrapping even for simple checks


@benzap: I think someone asked this a few days ago and the answer was "There isn't because atoms aren't 'data'". IIRC there was also a suggestion to take a look at coll-of, which might have some bits you could crib to implement an atom-of. I might look into this today.

Alex Miller (Clojure team)15:06:41

personally, I think you should work with state by a) defining your problem in terms of data b) writing nearly every function as a pure function from data to data c) isolating the use of stateful entities to as small number of functions as possible d) focusing on writing great specs for b in terms of a

Alex Miller (Clojure team)15:06:42

not every function has to have a spec


has anybody started a clojure.spec utility library yet because I keep thinking about doing that


should probably call it spook

Alex Miller (Clojure team)19:06:21

you may want to check your urban dictionary before you venture down that path


urban dictionary has all the best words

Alex Miller (Clojure team)19:06:46

totally on a tangent, the urban dictionary was hiring for a full stack clojure position recently

Alex Miller (Clojure team)19:06:02

spock is much better :)

Alex Miller (Clojure team)19:06:22

although I think there is a scala (or groovy?) testing library called that already


splec, shplec


shpec sounds like something sean connery would say


okay so we already have a mascot


(require [com.gfredericks.shpec :as s'])


just realized 'foo' is valid clojure


I only wish the syntax highlighters were more often aware of that


...because I use that all the time


Replete (standalone ClojureScript iOS app) has an update in the App Store with support for cljs.spec.


is there any way to make s/cat specs generate a vector?


stathissideris: both s/coll-of and s/tuple can generate vectors -- are either of those usable for you?


@gfredericks: tuple would work for my validation, but ideally I would like to keep the destructuring that s/cat provides


what you want is a way to gen/fmap the default generator

Alex Miller (Clojure team)21:06:35

use with-gen to override the generator with fmap


alexmiller: but how do you get the default generator to pass to fmap?

Alex Miller (Clojure team)21:06:39

well you could call s/gen on the original spec but I guess you may end up repeating yourself


that was the hack I was about to suggest


we can put a helper for this into shpec


thank you both! I'm not very well-versed with test.check, but I'm saving this part of the log so that I can go do some reading. It will hopefully make more sense after that 🙂


stathissideris: we're suggesting (s/def ::foo <definition>) (s/def ::foo (s/with-gen <definition> (let [g (s/gen ::foo)] #(gen/fmap vec g))))


and <definition> being there twice is the repetition alex mentioned


great thanks, I'll give it a go. In my case <definition> is not too long, so it could be ok


could even try factoring it out to a let and see if that works


...or even a macro is that doesn't work


alexmiller: the default generator for s/and is necessarily pretty hacky; should there be some documentation somewhere suggesting an override?


somehow overriding test.check's normal error message for such-that would be a fancy approach

Alex Miller (Clojure team)21:06:36

I think there is some desire to have a better (programmatic) way to have a conversation about filtering with such-that than just boolean yes/no

Alex Miller (Clojure team)21:06:03

but I'm sure Rich would have more to say about that


that sounds sooper fancy


alexmiller: do you know if recursive specs is the only reason for the no-arg-function-returning-a-generator pattern?

Alex Miller (Clojure team)21:06:17

Stu worked on that but I assume the dynamic loading is another aspect


oh that sounds plausible