Fork me on GitHub

@joshjones: thanks for your answer!


Hi guys, I am new to clojure spec, It looks like it can be used for data validation and coercion. eg checking if if username and password provided, or if phone number in correct format. But I don’t know how I can show proper error message for failed spec? I was not able to attach any meta data to specs. Any advice on this? Maybe someone got similar ideas? Thanks!


@kirill.salykin try explain, explain-str or explain-data


@tcoupland contains failed predicate, but what I want is to have a custom message in explain-data something like, (s/def ::year integer?, :message “wrong format”) I tried to attach it as meta-data - but no luck

Oliver George10:02:54

I don't think that's possible.

Oliver George10:02:31

Would a lib focused on user input validation be more appropriate?

Oliver George10:02:52

(Vs data structure validation)


But clojure.spec looked so good to describe form objects… I guess I’ll find some validation library, thanks

Oliver George11:02:22

I agree it's great for that.


@kirill.salykin I was at a local clojure meetup lately and @akiel presented this library: I totally liked the approach and think this is the direction to go. It basically normalizes a spec and returns a generic error message for it. Everything is based on explain-data.


There is not much in it right now, but it should get you started.


@kirill.salykin I would be happy to hear what you think about it. I’ll certainly separate the validation aspect from the material-ui lib. There are also some slides from the meetup:


What is the right way to provide a predicate which is always true? I want a spec which is a tuple of a keyword and anything. How to spec the anything?


any? was added for this purpose


And how to spec a tuple with an optional element?


[:a] or [:b :c] should be valid. Is this possible with a simple tuple? Or do I need an or?


@witek one way is:

(s/def ::a-or-bc (s/or :a (s/tuple #{:a})
                       :bc (s/tuple #{:b} #{:c})))


depending on whether it's nested, you can also use cat instead of tuple


a wiki of "how do I spec X?" snippets would be useful


oooh...something like that talk at the last Clojure/Conj where you write example data and the computer starts generating specs until it finds one that matches all your example input?


If I have:

(s/fdef resource->relationship
  :args (s/cat :from-fn (s/fspec :args (s/cat :resource :resource/entity)
                                 :ret qualified-keyword?))
  :ret :relationship/entity)
and my from-fn, which is :name runs fine: (:name {:name "item-definition-components", :description "The list of item definition components.", :uri "{item-definition}/components", :list-of "item-definition-component", :family-id :itemdefinitions, :id :itemdefinitions/item-definition-components}) Why is that if I instrument I get:
Call to #'rest-resources-viz.extractor/resource->relationship did not conform to spec:
                            In: [0] val: "" fails at: [:args :from-fn :ret] predicate: qualified-keyword?
                            :clojure.spec/args  (:name {:name "item-definition-components", :description "The list of item definition components.", :uri "{item-definition}/components", :list-of "item-definition-component", :family-id :itemdefinitions, :id :itemdefinitions/item-definition-components})
                            :clojure.spec/failure  :instrument


it looks like it runs it in a different way when instrumented


I am now doubting, is instrument good for use at the repl?

Alex Miller (Clojure team)19:02:06

instrumentation of an fdef with an fspec arg will check that arg by invoking the function you pass it with args generated from the fspec :args

Alex Miller (Clojure team)19:02:31

here it’s invoking the function you passed to resource->relationship with a generated :resource/entity and getting back empty string rather than a qualified keyword

Alex Miller (Clojure team)19:02:48

instrument is primarily designed for use at the repl (or during tests), so it should be good for that

Alex Miller (Clojure team)19:02:29

if from-fn is a keyword, then it will return a string based on the example you have above, not a keyword

Alex Miller (Clojure team)19:02:44

looks like a bug in either your code or your spec to me


no well, I forgot to include the code of the function, but it "keywordizes" the result


in fact, when I launch it with instrument the result is the above, but without it it runs fine, same example...of course I need a repro case 😄


thanks for confirming though


well, (qualified-keyword? (keyword "")) is going to be false


the input you pass in doesn't matter


that error is from the generated data being used to test the spec


ok so I was completely missing that point


oh wow that explains everything


lol thanks...weirdly enough, printlns in resource->relationship where not printing as well


I would have to look at the source for instrument, because if a spec for a function argument fails, it never actually runs the function


yeah it exactly looks like it


thanks (hired) man! You saved my chickens 😸