clojure-spec

Brian Beckman 2022-10-11T20:31:20.089719Z

Dear friends: Seeking explanation. I noticed that certain with-gen specs describe as unknown. To wit:

(s/def ::foo (s/with-gen (fn [x] (integer? x))
               (fn [] (gen/return 42))))
(s/valid? ::foo 1234)
;; => true
(gen/generate (s/gen ::foo))
;; => 42
(s/describe ::foo)
;; => :clojure.spec.alpha/unknown
But here is one that works:
(s/def ::bar (s/with-gen integer?
               (fn [] (gen/return 43))))
(s/valid? ::bar 2345)
;; => true
(gen/generate (s/gen ::bar))
;; => 43
(s/describe ::bar)
;; => integer?
What gives, please & thanks?

Alex Miller (Clojure team) 2022-10-11T20:56:09.020949Z

(fn [x] (integer? x)) is an anonymous function, which is just an opaque object so there is no way in Clojure to work backward from that to a form

Alex Miller (Clojure team) 2022-10-11T20:57:59.002979Z

with things like integer? we are working some magic to see that's a function tied to a var and demunging a class name to recover it

Alex Miller (Clojure team) 2022-10-11T20:58:55.709149Z

in spec 2, we are able to get rid of all of that and better capture forms by having well separated symbolic and object layers, so eventually this will be improved

👍 1
Brian Beckman 2022-10-11T21:09:44.414719Z

That makes sense, Alex. ty. I did notice that sometimes (specifically when there is no with-gen) describe can report an anonymous function:

(s/def ::baz (fn [x] (integer? x)))
(s/describe ::baz)
;; => (fn [x] (integer? x))

Alex Miller (Clojure team) 2022-10-11T21:16:37.773309Z

in that case, s/def is a macro and can capture the form

👍 1
Alex Miller (Clojure team) 2022-10-11T21:17:45.093869Z

with-gen is a function and the args are evaluated before invocation

Alex Miller (Clojure team) 2022-10-11T21:27:57.860849Z

there is another option too that is a macro and can specify a custom generator:

user=> (s/def ::foo (s/spec (fn [x] (integer? x)) :gen (fn [] (gen/return 42))))
:user/foo
user=> (s/describe ::foo)
(fn [x] (integer? x))

Alex Miller (Clojure team) 2022-10-11T21:28:36.129399Z

(although this is a different known problem in that it omits the custom gen)

👍 1
Brian Beckman 2022-10-11T22:02:54.537809Z

great stuff. tyvm