This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-10-14
Channels
- # announcements (7)
- # aws (1)
- # babashka (1)
- # beginners (19)
- # calva (9)
- # clj-commons (4)
- # clj-kondo (64)
- # clj-on-windows (27)
- # cljsrn (12)
- # clojure (127)
- # clojure-bay-area (3)
- # clojure-europe (25)
- # clojure-hungary (7)
- # clojure-nl (1)
- # clojure-norway (9)
- # clojure-spec (5)
- # clojure-survey (2)
- # clojure-uk (22)
- # community-development (5)
- # core-async (19)
- # cursive (29)
- # datascript (8)
- # events (1)
- # fulcro (2)
- # graalvm (3)
- # jobs (1)
- # lsp (155)
- # malli (18)
- # nbb (6)
- # off-topic (86)
- # pathom (2)
- # rdf (18)
- # re-frame (9)
- # releases (2)
- # scittle (24)
- # shadow-cljs (33)
- # xtdb (4)
OBSERVATION: I noticed a handy feature: specs created via s/with-gen
can automatically filter out nil
. Is it generally true that such specs never produce nil
when the spec-part of s/with-gen
forbids nil
? I guess, stated that way, it’s obvious that it should be generally true.
This is a nice feature for me because my project generators create trees with level-crossing semantical constraints that can go wrong in combinatorial ways. Any time anything goes wrong (e.g., 0 to a negative power somewhere in the tree), I just barf out nil
as if in a maybe monad (it’s about 2% of the time, so it’s fine). It’s nice that I get automatic filtering of the generated values at the spec level. Actually, it’s brilliant! It let me strip out the maybe monad from my code (simplifying it greatly) and just rely on nil
punning and some->
and some->>
operations.
Consider the following:
(s/def ::nil-producing-spec
(s/or :nil nil? :int integer?))
(def nil-producing-generator
(s/gen ::nil-producing-spec))
(gen/sample nil-producing-generator)
;; => (nil nil -1 -2 nil 6 3 nil nil nil)
(s/def ::nil-rejecting-spec
(s/with-gen
integer?
(fn [] nil-producing-generator)))
(gen/sample (s/gen ::nil-rejecting-spec))
;; => (0 -4 -2 -5 0 -64 0 -4 6 0)
I think s/gen
checks the generated values and verifies they pass the spec (https://github.com/clojure/spec.alpha/blob/master/src/main/clojure/clojure/spec/alpha.clj#L287). You could swap integer?
with something like pos-int?
and see that it now filters out more than just nil
s.
spec derived generators automatically filter spec derived values by the validity of the spec