I think you’re looking for conformer 
<http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/conformer>;
 
the spec it produces will pass along the converted value instead of the 
original input. It could be used like:
(defn str->double [s]
  (try
    (Double/valueOf s)
    (catch NumberFormatException _
      :clojure.spec/invalid)))

(s/def ::transforming-check (s/and string? (s/conformer str->double) ::
bigger-than-zero?))

I hope that helps with your original problem, but I’ll defer to the more 
experienced folks here for your questions about the spirit/aim of 
clojure.spec.

On Tuesday, October 11, 2016 at 2:30:18 PM UTC-4, [email protected] wrote:
>
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to