This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-10-11
Channels
- # announcements (2)
- # babashka (27)
- # beginners (99)
- # biff (16)
- # calva (15)
- # clj-kondo (6)
- # clj-on-windows (38)
- # clojure (54)
- # clojure-austin (1)
- # clojure-europe (30)
- # clojure-france (4)
- # clojure-nl (1)
- # clojure-norway (43)
- # clojure-spec (10)
- # conjure (28)
- # core-async (4)
- # cursive (7)
- # figwheel-main (1)
- # graphql (9)
- # gratitude (3)
- # honeysql (9)
- # introduce-yourself (1)
- # jobs (1)
- # joyride (128)
- # lambdaisland (2)
- # malli (8)
- # membrane (12)
- # nbb (5)
- # off-topic (1)
- # polylith (11)
- # re-frame (9)
- # reitit (1)
- # remote-jobs (5)
- # sci (15)
- # shadow-cljs (50)
- # tools-deps (2)
- # xtdb (12)
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?(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
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
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
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))
with-gen
is a function and the args are evaluated before invocation
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))
(although this is a different known problem in that it omits the custom gen)
great stuff. tyvm