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.

Reply via email to