Calling s/valid? will tell me if the data is valid *if it has been conformed*. But what if it hasn't? Can I use the data? Is it "valid" according to the spec I wrote?
If your spec includes coercions, you have inherently made the “is valid?” question include the coercion. Your ::test-spec accepts anything that can be used as the argument to keyword. This is why Cognitect keep recommending people do not do this. And I’m jumping into this thread because we _do_ include coercions in some of our specs at work… we’ve been heavy users of spec since the early alpha builds and we ran those alphas in production. But we are very conscious about our specs that coerce: we know and accept that they will work on “any string that can be coerced to <desired type>”. If we specifically want to check whether some data is <desired type> we use a different spec. We do this for parameters in our REST API, for long, double, Boolean, date, etc – we have two specs for each: one that is a spec for the target type in the domain model (which in these cases is just defined as the appropriate built-in predicate), and one that is a spec for the API level (which accepts either the target type or a string that can be coerced to the target type). Then we use the appropriate spec at the appropriate “level” in our application. Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN An Architect's View -- http://corfield.org/ "If you're not annoying somebody, you're not really alive." -- Margaret Atwood ________________________________ From: clojure@googlegroups.com <clojure@googlegroups.com> on behalf of Jan Rychter <jrych...@gmail.com> Sent: Tuesday, February 20, 2018 2:41:38 AM To: Clojure Subject: s/valid? does not tell me if the data is valid as supplied I've been using spec for a while now, in a reasonably large code base (>30k lines of Clojure and ClojureScript) and there is an issue that bit me several times. I use conformers for coercing data that is *almost* what I need, usually when reading from JSON (RethinkDB). Common conformers are keyword and set. And it works really well, except for one problem: there is no way to know if data has been conformed or not. Calling s/valid? will tell me if the data is valid *if it has been conformed*. But what if it hasn't? Can I use the data? Is it "valid" according to the spec I wrote? This is a very real problem: I've spent considerable time chasing bugs where there was a code path which did not call s/conform. The data passed all validations done with valid? and the bug manifested itself far down the road, where something expected a keyword instead of a string, or a set instead of a vector. Here is a specific minimal example demonstrating what I'm talking about: (ns spectest (:require [clojure.spec.alpha :as s])) (s/def ::test-spec (s/and (s/conformer keyword) keyword?)) (s/conform ::test-spec "a") ;; :a (s/valid? ::test-spec "a") ;; true I expected the last valid? to return false, because my code does not expect a string, it expects a keyword, according to the spec. I might be missing something, but I would much rather see valid? tell me if the data is valid for use (as supplied) and have a separate valid-when-conformed? which tells me if the data is, well, valid when conformed. It seems to me that the current valid? that does two things is confusing and not very useful for contracts. At the very least I'd really like to see a function that tells me if the data is valid *as supplied*, as this is the function that I'd want to use when enforcing contracts everywhere in my code. Alternatively, I could stop using conformers altogether, and write explicit data conversion functions. That might not be a bad idea, but it seems other people started using conformers, too, so eventually I'll hit the same problem again. --J. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com<mailto:clojure+unsubscr...@googlegroups.com>. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.