This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-08-29
Channels
- # admin-announcements (1)
- # announcements (3)
- # babashka (18)
- # beginners (35)
- # cider (4)
- # clj-kondo (52)
- # cljs-dev (2)
- # clojure (92)
- # clojure-spec (18)
- # clojurescript (17)
- # conjure (11)
- # core-async (1)
- # datomic (11)
- # emacs (5)
- # fulcro (11)
- # graalvm (10)
- # helix (21)
- # kaocha (6)
- # malli (1)
- # membrane (37)
- # off-topic (110)
- # re-frame (1)
- # reagent (12)
- # reitit (5)
- # rewrite-clj (1)
- # sci (1)
- # shadow-cljs (40)
- # vim (21)
- # vrac (17)
I'm doing an experiment of integrating clojure.spec into babashka, together with generators. I'm running into a slight problem: the generated results aren't random, due to this line being evaluated at compile time, I think: https://github.com/clojure/test.check/blob/7e7c2116fa721211e8f5642a249e4a0f327445f4/src/main/clojure/clojure/test/check/random.clj#L175 One solution is to fork clojure.test.check, unless someone may have a better idea... I could also try alter-var-root
Huh, interesting. Sorry no better ideas here but I suppose a fork could become a PR for test.check.
Seem to work :)
borkdude@DESKTOP-JN2UNTV ~/dev/babashka (spec) $ ./bb "(require '[clojure.spec.alpha :as s] '[clojure.spec.gen.alpha :as gen]) (s/def ::foo int?) (gen/generate (s/gen ::foo))"
-2
borkdude@DESKTOP-JN2UNTV ~/dev/babashka (spec) $ ./bb "(require '[clojure.spec.alpha :as s] '[clojure.spec.gen.alpha :as gen]) (s/def ::foo int?) (gen/generate (s/gen ::foo))"
-11621
borkdude@DESKTOP-JN2UNTV ~/dev/babashka (spec) $ ./bb "(require '[clojure.spec.alpha :as s] '[clojure.spec.gen.alpha :as gen]) (s/def ::foo int?) (gen/generate (s/gen ::foo))"
-13
The patch:
(def next-rng
"Returns a random-number generator. Successive calls should return
independent results."
(let [a (atom (delay (r/make-java-util-splittable-random (System/currentTimeMillis))))
thread-local
(proxy [ThreadLocal] []
(initialValue []
(delay
(first (r/split (swap! a #(second (r/split (deref %)))))))))]
(fn []
(let [rng @(.get thread-local)
[rng1 rng2] (r/split rng)]
(.set thread-local (delay rng2))
rng1))))
(defn make-random
"Given an optional Long seed, returns an object that satisfies the
IRandom protocol."
([] (next-rng))
([seed] (r/make-java-util-splittable-random seed)))
(alter-var-root #'r/next-rng (constantly next-rng))
(alter-var-root #'r/make-random (constantly make-random))
@alexmiller Let me know if a PR is in order
I guess we could use clojure.core/force
to work with normal values after the initial delay has been forced.
So this works with GraalVM as well:
(def next-rng
"Returns a random-number generator. Successive calls should return
independent results."
(let [a (atom (delay (r/make-java-util-splittable-random (System/currentTimeMillis))))
thread-local
(proxy [ThreadLocal] []
(initialValue []
(first (r/split (swap! a #(second (r/split (force %))))))))]
(fn []
(let [rng (.get thread-local)
[rng1 rng2] (r/split rng)]
(.set thread-local rng2)
rng1))))
(defn make-random
"Given an optional Long seed, returns an object that satisfies the
IRandom protocol."
([] (next-rng))
([seed] (r/make-java-util-splittable-random seed)))