I would actually love it if Spec was extended to have the concept of types.

Something where every spec could be tied to a Type, and types could be 
constructed to have Hierarchies.

Not sure what the syntax would be like, but say:

(s/def :String ::name string?)
(s/def :String ::address (s/and string? (complement string/blank?)))
(s/def :Person ::person (s/keys :req [::name ::address]))
(s/def :Homeless ::homeless (s/keys :req [::name]))

(s/defisa :Homeless :Person)

Types would still be predicates, and all spec would be a Type too. Types 
would be optional though. A Type is the OR of all the specs predicates 
defined as that Type and its children types. So in the above, :Homeless is 
(s/or ::person ::homeless).

Now, this idea might need to be refined, but the goal would be so that Spec 
could be used as a modeling languages for other languages. So I could from 
a Spec auto-generate a Java class model, or a Ruby model, etc. Since now I 
can relate predicates to types myself. It could also allow for better 
static analysis.

Also, might make spec extra complicated and confused to mix both predicates 
and types, but that could depend how its done and managed.

On Tuesday, 20 February 2018 02:41:38 UTC-8, Jan Rychter wrote:
>
> 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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to