This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-07-28
Channels
- # asami (1)
- # aws (9)
- # babashka (16)
- # beginners (32)
- # calva (2)
- # clj-kondo (20)
- # cljdoc (6)
- # clojure (35)
- # clojure-dev (25)
- # clojure-europe (11)
- # clojure-india (1)
- # clojure-norway (2)
- # clojure-spec (26)
- # clojure-uk (1)
- # clojurescript (41)
- # conjure (3)
- # css (9)
- # cursive (18)
- # data-oriented-programming (6)
- # data-science (2)
- # emacs (47)
- # events (1)
- # fulcro (15)
- # graalvm (30)
- # gratitude (7)
- # honeysql (27)
- # inf-clojure (4)
- # introduce-yourself (2)
- # lsp (129)
- # malli (7)
- # missionary (21)
- # nbb (17)
- # off-topic (18)
- # re-frame (6)
- # releases (1)
- # shadow-cljs (120)
- # vim (7)
- # xtdb (15)
This is a bit more relevant to generators, but how can I use the generated result from one generator as the baseline for another? I want to be able yo generate sequences representing events in time or request and response, and for all of them to share an ID, for example
perhaps https://clojure.github.io/test.check/clojure.test.check.generators.html#var-bind? or the let
variant, as hinted in the docstring
or perhaps fmap
https://www.youtube.com/watch?v=F4VZPxLZUdA presentation by Gary Fredericks gives nice examples on how to compose generators
Just guessing because I haven't looked yet, but bind sounds exactly right, thanks! My intuition is from what it means for implementing logic engines, where bind is akin to conjunction
So let's just run this through, I have a generator for maps, and I want some values from g1 to continue through g2, most brutal way would be merging these values on top of what comes out of g2, but there surely is a better way
I'm no expert on the matter, but I remember once doing something like (->> (gen/tuple random-id-gen seq-of-requests-gen) (fmap (fn [[id reqs]] (map #(assoc % :id id) reqs))))
when I just wanted to "give me some random requests with the same random id" etc.
i made a recursive map generator based on example data so my gen looks like (fmap (tuple (map (elements elements))))
and basically you can replace any elements with another fmap (self similar structure)
i saw bind when looking for my solution, but i didn't see how it was going to be better than fmap
merging values from previous generators is ok, those other gens are able to shrink, fmap is a bit inefficient, but maybe you could make a new generator that merging for your problem. so long as your fmap isn't doing a lot of work, i don't think it'll be a problem
i don't know what that means. recover something before it runs doesn't even sound like it makes sense logically
If I have a map generator, can I know what keys it will generate before running it?
I mean going the other way, I already have the map generator, I want to take it apart
i don't get it. are you saying that you are using someone else's gen, that has fixed keys, and you can't see what keys those are from their code?
I was browsing through the generator code today and I got the impression that generator instances are opaque so you can't for example access the source spec. or at least that's my understanding of it
you could make a data structure that creates gens, then put that on as meta-data. but you would be creating a wrapper around the whole gen library at that point
It was a matter of efficiency. If I want to use bind to inject values from one generator to the next, there's no reason to generate those values in the second generator as well, right?
this is just a guess (and perhaps not a good idea), but if you really want to do that kind of optimization (e.g. the value is really expensive to generate and you know the qualified kw you want to replace) then perhaps you could leverage the overrides
arg of clojure.spec.alpha/gen
:thinking_face: for example something not completely unlike this: (bind random-id-gen (fn [id] (c.s.a/gen ::coll-of-maps {::id (fn [] (return id))})))
, where you don't want to execute the default generator for ::id for each map
It's not critical, maybe I'm overly concerned about stepping into pathological situations
I simply have functions that return generators that wrap another generator and replace the values in the generated map (using fmap) with the explicitly defined ones. Eg see https://github.com/wardle/hermes/blob/main/src/com/eldrix/hermes/rf2.clj I have lots of cases where I need to be careful to use the same identifier in many generated structures.