Fork me on GitHub
#clojure-spec
<
2018-03-12
>
misha14:03:53

@borkdude what do you mean by “relate” exactly?

misha14:03:21

The only coupling/relation you should have is order.

oconn14:03:56

I’m working on writing a spec for a model that uses multi-spec. Is it possible to use unqualified keywords in a multi-spec? I found this thread https://www.mail-archive.com/[email protected]/msg99107.html and tried altering the example in the docs with no success.

bbrinck14:03:29

> Is it possible to use unqualified keywords in a multi-spec? @oconn Can you explain this a little bit more? I’m not sure I understand the question.

taylor14:03:40

@oconn it’s possible, and the example in the multi-spec doc string uses an unqualified keyword

oconn14:03:10

Oh nice, yeah not sure what I’m doing wrong here.. So here’s the spec

taylor14:03:36

that explain returns “Success!” for me

taylor14:03:35

having trouble inferring what the variant-type "Text" spec is intending to do though

oconn14:03:40

I stripped out a lot of other keys, there are other types as well.

bbrinck14:03:41

@oconn Can you expand a bit on what is happening when you call explain and what you expect to happen?

bbrinck14:03:23

I also see "Success!" printed, but I’m guessing that’s not what you expect (?)

bbrinck14:03:15

(minor thing, but your defmethod appears to have a missing paren at the end)

oconn14:03:23

Yeah, not seeing that but I think it’s because I stripped out some keys before pasting here.

oconn14:03:21

Ok, now I’m getting Success!. Sorry for the trouble

bbrinck14:03:28

np, good luck!

eggsyntax19:03:24

I'm currently using gen/generate to make some sample data for myself, including fairly nested structures which use s/* at multiple levels. It'd be nice during dev to have the produced data be fairly short so it doesn't take up a whole repl screen. Wasn't there some way to tell it to keep those short? I vaguely thought there was. From the documentation it seems like it would be s/*recursion-limit*, but if I do

(binding [s/*recursion-limit* 1] (sgen/generate (s/gen ::my-spec)))
I still get large numbers of items on the s/* specs.

eggsyntax19:03:44

Oh, I see why it's not *recursion-limit*, I think; it's not actually recurring many layers deep, just creating a long sequence at each layer.

eggsyntax19:03:02

But it'd be really nice to have an equivalent way to force shorter sequences. Am I missing something?

misha19:03:49

I'm afraid you are not missing anything, @eggsyntax

eggsyntax19:03:18

Ah well. I guess I can walk it and take 3 or something.

misha19:03:23

you can provide overrides, which wrap original seq specs with just items count upper limit

eggsyntax19:03:20

Oh, so something like (s/with-gen (s/* ...) (take 3 ...))

misha19:03:39

I'd love to be proven wrong on this one, though : )

eggsyntax19:03:28

It'd make a terrific addition to a future version of spec, to have s/*sequence-limit* alongside s/*recursion-limit*.

misha19:03:42

I doubt it is a good idea to have a single global count limit. I'd rather had a way to override :min-count/:max-count opts for maps and seqs specs

eggsyntax19:03:57

From my POV, that'd be nice too -- but for the case of just quickly generating a piece of data in the REPL, it'd be lovely to just bind a global limit.

eggsyntax19:03:03

Hmm, test.check does have :min-elements and :max-elements on a number of its generators, I see....

misha19:03:06

like an extra count args here:

(with-gen* [_ gfn] (every-impl form pred opts gfn))

triss20:03:16

why are all the facilities for defining specs macros? I’m tempted to use spec for pattern matching but the syntax is too heavy…

Alex Miller (Clojure team)21:03:15

they’re macros to capture the form for explanations

Alex Miller (Clojure team)21:03:28

that said, some of that is likely to change in the next rev

pavani21:03:35

@alexmiller How can I validate a schema like this using Spec?

{:billing_contact
                          {
                           (schema/optional-key :street_address) schema/Str
                           (schema/optional-key :city)           schema/Str
                           (schema/optional-key :region)         schema/Str
                           (schema/optional-key :postal_code)    schema/Str}}
I have the following spec but if ::billing_contact has keys other than the optional keys, it considers the map to be valid. I just want to check if the map has either those specified keys in opt or no keys.
(s/def ::street_address string?)
(s/def ::city string?)
(s/def ::region string?)
(s/def ::postal_code string?)
(s/def ::billing_contact (s/keys :opt [::street_address ::city ::region ::postal_code]))
(s/def ::changes (s/keys :req [::billing_contact]))

Alex Miller (Clojure team)22:03:56

You can s/and with an every? predicate that checks every key is a known key set

pavani22:03:46

@alexmiller Thank you for that. I am not sure how exactly I could use that here. Could you please exhibit that with my example?

bbrinck03:03:51

@U7MMSSQKC Perhaps something like (s/def ::billing_contact (s/and (s/keys :opt [::street_address ::city ::region ::postal_code]) #(every? {::street_address ::city ::region ::postal_code} %))) ?

bbrinck03:03:20

Whoops, I forgot the call to keys. Would this work: (s/def ::billing_contact (s/and (s/keys :opt [::street_address ::city ::region ::postal_code]) #(every? #{::city ::street_address ::region ::postal_code} (keys %))))