Fork me on GitHub
#clojure-spec
<
2018-08-28
>
misha05:08:46

You control what goes into that atom, and when. After all, global spec registry is an atom too.

Ulrich17:08:58

I do not understand this mismatch, as I see it. Do you know the reason why :gen takes a function and not a generator? (s/exercise boolean? 1 gen/boolean) ok but (s/exercise (s/spec boolean? :gen gen/boolean) 1) bad. So I write (s/exercise (s/spec boolean? :gen (constantly gen/boolean)) 1). Is there a better way?

seancorfield17:08:50

https://www.dropbox.com/s/plwu44v61adscap/Screenshot%202018-08-28%2010.39.11.png?dl=0 The first s/spec form works for me, using (constantly gen/boolean) does not...

Alex Miller (Clojure team)18:08:24

Specs defer gens via functions to avoid loading clojure.spec.gen.alpha when not necessary. When you call exercise, it takes an overrides map which is a map of spec name to function returning generator.

Alex Miller (Clojure team)18:08:40

(s/exercise boolean? 1 gen/boolean) is not ok, that last gen/boolean is just not being used (boolean? has a built-in generator)

Alex Miller (Clojure team)18:08:13

I usually do something like (s/exercise (s/spec boolean? :gen #(gen/boolean)))

Alex Miller (Clojure team)18:08:58

I suspect something is wacky in the macrology that’s making the constantly version not work there

seancorfield18:08:04

@alexmiller I'm curious as to why the unwrapped version worked in my REPL then...?

seancorfield18:08:26

Seems to work both with and without the #( ... ) around gen/boolean...

Alex Miller (Clojure team)18:08:02

not sure - since this one has a built-in, that might be masking something too

Alex Miller (Clojure team)18:08:47

oh, so gen/boolean (where gen is clojure.spec.gen.alpha) is actually already a thunk

Alex Miller (Clojure team)19:08:36

so gen/boolean works as is and #(gen/boolean) is a function that invokes gen/boolean and returns the generator, so is exactly the same thing

Alex Miller (Clojure team)19:08:16

but (constantly gen/boolean) is a function that returns gen/boolean not invoked, which is a function rather than a generator

Alex Miller (Clojure team)19:08:35

so going way back to the top @ulrich.becker said “(s/exercise (s/spec boolean? :gen gen/boolean) 1) is bad”, but it’s not bad - that’s exactly what you want here (the missing piece of information being that clojure.spec.gen.alpha already wraps gens in thunks

seancorfield19:08:41

Ah!! 💡 Now it all makes sense. That also explains why this did not work: (s/exercise (s/spec boolean? :gen (fn [] (println "Gen!") gen/boolean)) 1)

seancorfield19:08:44

(I wanted to see how often the thunk was called and when I corrected it to call (gen/boolean) the answer was "just once", regardless of the exercise size)