Fork me on GitHub
#clojure-spec
<
2017-04-19
>
mike_ananev08:04:45

Hi! I would like to add some :doc to my spec? Is there any way to do that? I need some text comments for my spec

mike_ananev08:04:06

for data, not for fn's

Alex Miller (Clojure team)11:04:43

Not currently but maybe eventually

robert-stuttaford14:04:40

is there anything out there that talks about how to write custom generators for s/multi-spec?

robert-stuttaford14:04:57

if we write a generator that returns something sufficient for the dispatch fn to use, will the generator code know to keep generating data for the specs returned by the defmethods?

robert-stuttaford14:04:38

in our case, we dispatch in two different ways based on the value of :type, so we’re thinking we’d gen a map with :type with a valid value from one of the two sets of :type values we keep

Alex Miller (Clojure team)15:04:05

Well that's where retag comes in. However I was looking at something the other day that made me question whether multi-spec was working properly in gen for non-keyword retag cases

Alex Miller (Clojure team)15:04:24

I guess I would turn your question around and ask whether it's doing what you expect

mobileink16:04:04

hi. I have a map with a type key (:oic.core/rt, for resource type), whose value is a vector of type keys. how can I tell spec to form the conjunction of those types so that valid maps satisfy them all? Something like (apply s/and [::foo ::bar]), which doesn’t work.

ghadi16:04:21

No need. spec will automatically check all namespaced keys for which there is a spec registered

mobileink16:04:31

right, but different types will have different specs; for example, :oic.r/temperature requires ::p/temperature

mobileink16:04:03

so i need map-level validation. a map might look like

{::p/temperature 72
            :oic.scale/temperature “F"
            :oic.core/rt [:oic.r/temperature :oic.r/sensor oic.r/humidity]
            :oic.core/if [:oic.if/baseline]            }

mobileink16:04:53

this should fail, because :oic.r/humidity requires ::p/humidity

mobileink16:04:30

it’s easy to use s/get-spec, but how can I then apply the spec?

ghadi16:04:57

Look at s/merge, which merges map specs

mobileink17:04:31

yep, know about that, but i think that’s static - here we won’t know what to merge until runtime. at least, i’ve tried to use it but no luck so far.

mobileink17:04:34

i think i need something like multi-spec with the ability to dispatch multiple times

ghadi17:04:55

Are you changing the meaning of namespaced keys in different maps?

ghadi17:04:07

Or are you having different sets of namespaced keys

mobileink17:04:13

the idea is one schema for each oic.r “resource” at https://github.com/OpenInterConnect/IoTDataModels, but a resource “instance” can have multiple types - listed in :oic.core/rt

mobileink17:04:09

I think i have a possible solution: I use multi-spec, but my multi-methods recur over the vector of keywords. so given :oic.core/rt [::foo ::bar], the dispatch method will dispatch on ::foo, and the defmethod for ::foo will recur with (rest (:oic.core/rt arg)) before calling s/keys. seems to work with a simple example at least. kinda cool imho.

mobileink17:04:38

amazing what you can do with clojure

mobileink17:04:02

e.g.

(defmethod oic-rt :oic.r/temperature [m]
  (let [rts (:oic.core/rt m)
        nextm (merge m {:oic.core/rt (vec (rest rts))})]
    (s/merge
     (if (rest rts)
       (oic-rt nextm))
     (s/keys :req [::p/temperature] :opt [:oic.scale/temperature]))))

mobileink17:04:50

basically a runtime s/merge