Hello, I have a problem which is probably not in the spirit of clojure.spec as being a library for "only" checking/generating valid values, but of substantial practical value for my use case:
Let say I have a function for checking if a double precision number is parsable from a string (where possible performance penalties because of communicating non-parsable strings through try/catch in the implementation is not part of my question): (defn str-parsable-double? [s] "Note the IMPLIED transformation from string to a double" (try (Double/valueOf s) (catch NumberFormatException e false))) and have a spec using this function: (s/def ::str->double str-parsable-double?) We could actually chain checks for a single value as in: (s/def ::str->double (s/and string? str-parsable-double?)) and we could check for the conformity of a value as per: (s/conform ::str->double "3.14") => "3.14" and (s/conform ::str->double "Pizza") => :clojure.spec/invalid Until now everything is ok, now my the questions: In my real world example I need a chain of a combination of checks and transformations in the following way: ::check1 ::check2 ::check-and-transform3 ::check-4-on-transformed-value ::check-5-on-transformed value or something like (s/def ::transforming-check (s/and string? ::str->double ::bigger-than-zero? ::smaller-than-pi ... etc ...)) As the result of (s/conform ::str->double "3.14") is the input value as a string instead of the result, I would need implement ::bigger-than-zero? and the rest of the checks as operating on strings, which would mean that I need in each check to transform the string into a double, which in my case is for performance reasons bad. On the other side I would be able to do the checks in a 2 step fashion, which goes against my understanding of the aim of clojure.check to be able to create through composition a single set of validations for a single value. This also doesn't solve fully the problem with the multiple parsing of the first data type before the transformation: a parsing happens in the ::str->double step as well in the then explicit transformation step before the final checks based then on the actual double. So - is there a way to compose checks in a single one, where some of them change the underlying type of the value for subsequent validations (I may miss something in the Clojure documentation, and pointers to it would be very welcome)? If not - why s/conform returns the input value instead of the result value? As being on the caller site of s/conform I know what I passed and I know what s/conform would give me in the negative outcome of the validation. If s/conform while iterating/recursing through the actual spec would apply the checks on returned values of previous checks instead always on the input - the problem would be solved, without negatives for the calling sites (as because of the previous sentence). This could be solved for example (not sure if I see every detail yet, but at least as a pointer) in that in the clojure.spec code Spec (conform* [_ x] (let [ret (pred x)] (if cpred? ret (if ret x ::invalid)))) the value of cpred? could be passed from the calling site (or if don't miss something be even per default true). In any case, I would be thankfull for any suggestions solving both proplems: how to express such checks in a good way and how to avoid reparsing values again and again (where the current example is for just strings to doubles, but the actual problem could involve any transformations on the value incl. type). With best regards Plamen -- 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.