Fork me on GitHub
#clojure-spec
<
2017-12-15
>
andy.fingerhut07:12:34

Are there any handy examples someone can link to for writing a spec for a function, where one of its arguments is a predicate function, e.g. a spec for clojure.core/filter ?

taylor07:12:57

this example isn’t exactly taking a predicate but it demonstrates a HOF taking another fn http://taylorwood.github.io/2017/10/15/fspec.html#higher-order-functions

andy.fingerhut07:12:13

Thanks. Nicely written examples there.

andy.fingerhut07:12:07

I've got the doc strings for seq? and seqable?, but I can't for the life of me think what the difference is between them, i.e. why would you pick one over the other in a spec?

curlyfry08:12:38

@andy.fingerhut seqable? is for things that can be made into a seq (but aren't necessarily seqs themselves). For example, (seq? []) returns false, but (seqable? []) returns true.

andy.fingerhut08:12:46

Got it. Thanks.

andy.fingerhut08:12:13

seqable? seems far more often useful in :args specs, then.

andy.fingerhut08:12:18

Looks like a spec like this probably needs a custom generator, if I see an error message like "Couldn't satisfy such-that predicate after 100 tries."? (s/def ::set/relation (s/and set? #(every? map? %)))

taylor08:12:36

yeah with s/and I believe the generator is based off just the first spec

taylor08:12:08

so, very unlikely it will generate sets with all maps

andy.fingerhut08:12:16

This page: https://clojure.github.io/test.check/generator-examples.html gives this example of a generator: (def sorted-vec (gen/fmap sort (gen/vector gen/int)))

andy.fingerhut08:12:41

When I try to def sorted-vec in my REPL I get an assertion error "Arg to vector must be a generator"

andy.fingerhut08:12:37

Sorry, pilot error. I had my gen alias'ed to clojure.spec.gen.alpha, not clojure.test.check.generators as stated at the top of that examples page

andy.fingerhut08:12:47

Does a generator for predicate any? ever produce values that aren't equal to themselves in Clojure, e.g. Double/NaN ?

gfredericks12:12:29

test.check's gen/any sure can not sure what any? got wired up to

gfredericks12:12:54

I feel like in both cases we need a secondary concept, like gen/any-sane

gfredericks12:12:25

just making NaN opt-in all the time seems like encouraging bad testing

lopalghost12:12:34

@andy.fingerhut have you tried using coll-of to spec a set of maps?

lopalghost12:12:53

eg (s/coll-of map? :kind set?)

gfredericks12:12:33

gen/any-equatable

andy.fingerhut13:12:31

gen/any-anumber

andy.fingerhut13:12:53

because, you know, it is not, not a number

gfredericks13:12:40

yeah but I'm talking about for something like gen/any where you are potentially generating large data structures and if there are any NaNs hiding anywhere in that giant tree then the whole thing becomes sometimes equal to itself but sometimes not

andy.fingerhut13:12:49

right. gen/any-anumber was a bad joke 🙂

lopalghost13:12:33

reminds me of one of my favorite clojure expressions: > (number? ##NaN) > true

andy.fingerhut13:12:54

I feel a JIRA coming on ...

andy.fingerhut13:12:33

@lopalghost I have not tried coll-of, but thanks for the suggestion. Will do.

andy.fingerhut13:12:40

I guess the generator for any? also sticks with things considered "values" in Clojure, i.e. it doesn't generate instances of java.util.Set ?

andy.fingerhut13:12:22

those also play havoc with one's usual ideas for clojure.core/= if they are inside of other sets, or keys of maps.

gfredericks13:12:55

yeah, definitely

gfredericks14:12:09

generating literally anything would be quite a tall order

didibus21:12:05

Is there a way to override the generator of the args spec of an fspec? Using instrument and :gen I thought would be able to do it, but I can't figure how.

Alex Miller (Clojure team)21:12:26

I don't think so, or at least it's not easy (and I think there is a ticket about this)

didibus21:12:21

Ok, thanks