I've been using the macro below to make "types" in the context of
clara-rules, where "type" has a specific semantic. If you're going to do
something like this, you definitely should have a very well-defined notion
of what "type" means.
(defmacro def-derive
"Macros to wrap useful pattern of defining a spec and calling
derive on the spec and a \"parent\" spec to create a hierarchy."
([child-name parent-name]
`(def-derive ~child-name ~parent-name ~parent-name))
([child-name parent-name spec]
`(do
(#?(:clj clojure.spec.alpha/def :cljs cljs.spec.alpha/def)
~child-name (#?(:clj clojure.spec.alpha/merge :cljs
cljs.spec.alpha/merge) ~parent-name ~spec))
(derive ~child-name ~parent-name))))
On Wednesday, February 21, 2018 at 5:34:00 PM UTC-8, Didier wrote:
>
> 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 [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.