test-check

johanatan 2017-12-01T00:20:31.000068Z

btw, is it generally considered bad practice to call gen/sample oneself nested within a huge gen/let (or other combinator construct)?

2017-12-01T00:21:00.000381Z

Yes

2017-12-01T00:21:09.000209Z

Or in a generator at all

2017-12-01T00:21:35.000018Z

Same with gen/generate

johanatan 2017-12-01T00:21:40.000157Z

hmm, I have through discipline been able to almost always avoid this but sometimes things get so hairy that the way to avoid it is not easy to see.

johanatan 2017-12-01T00:21:56.000041Z

is there any standard/general procedure one can apply to help escape that situation?

2017-12-01T00:24:19.000096Z

You're passing to sample a generator that's based on other things you generated?

johanatan 2017-12-01T00:24:24.000340Z

yep

alexmiller 2017-12-01T00:24:31.000148Z

Use bind

2017-12-01T00:24:32.000345Z

I think it can be hard to talk about these things abstractly, but I'm happy to look at whatever code you can share

johanatan 2017-12-01T00:24:51.000187Z

@alexmiller would bind work within a gen/let ?

johanatan 2017-12-01T00:25:18.000291Z

ah, yep. that seems like it would work.

johanatan 2017-12-01T00:25:19.000160Z

thx!

2017-12-01T00:26:22.000023Z

Nice

johanatan 2017-12-01T00:32:47.000351Z

is there a function that goes from list of generators to generator of a list?

johanatan 2017-12-01T00:32:59.000461Z

[there should be but i'm not seeing it]

2017-12-01T00:33:01.000179Z

Tuple

johanatan 2017-12-01T00:33:05.000219Z

ah, cool. thx

2017-12-01T00:33:12.000010Z

Used with apply

johanatan 2017-12-01T00:33:19.000343Z

right

johanatan 2017-12-01T05:05:14.000023Z

would it be possible to have a generator of an infinite/lazy sequence of arbitrary type?

johanatan 2017-12-01T05:05:49.000093Z

[like lazy-random-states but with an arbitrary generator for the values]

johanatan 2017-12-01T05:07:18.000083Z

[the reason i'd like this is i have some logic deeply nested inside a gnarly structure of gen/let, gen/bind, gen/fmap et al and realized in the very innermost loop that i need to pull N (dynamically determined) values of a particular type]

johanatan 2017-12-01T05:07:58.000128Z

it's probably possible to restructure the code to generate these on the outside but it's a bit difficult given that the amount to be generated is dynamic/ computed/ derived from other values

johanatan 2017-12-01T05:09:32.000020Z

so, if i could at the outermost level bind to a lazy sequence, then inside the nests I could pull from that lazy sequence without violating "thou shall not call gen/sample manually"

johanatan 2017-12-01T05:10:10.000093Z

pull via a regular take that is

2017-12-01T12:04:11.000213Z

I've thought about use cases like that before the trickiest part is thinking about how you shrink that structure

2017-12-01T12:04:49.000071Z

you could setup a generator of infinite lazy sequences using a recursive gen/bind, but I think it would never stop shrinking

2017-12-01T12:05:51.000155Z

and even with lower-level help from the library, it still needs to have a strategy for that the tension comes from not easily being able to tell how much of the infinite source of data the user actually used

2017-12-01T12:07:02.000094Z

there are certainly hacky ways to try to do that, and that might be the best answer, but the "hacky" part has made me hesitant to commit to anything

2017-12-01T12:08:26.000381Z

one less hacky trade-off you can make is to relax the "requirement" that there actually be an infinite number of things generated -- e.g., if you generate a large vector of items and then use (gen/fmap cycle ...)

2017-12-01T12:08:57.000168Z

then that will naturally shrink to an infinite repetition of one very small piece of data so it only works if you can tolerate repeats

2017-12-01T12:09:23.000162Z

I remember making this recommendation for spec when it generates function stubs

johanatan 2017-12-01T18:38:54.000013Z

ah, nice thoughts. would definitely be cool if something like this can be added in a not-too-hacky way but for now yea i'll go with a finite but repeating structure

johanatan 2017-12-01T19:17:59.000600Z

if i were to attempt a bind to the (gen/fmap cycle ...) structure you mentioned, that would be an infinite loop yea?

2017-12-01T19:20:53.000220Z

no I don't think so

2017-12-01T19:22:13.000182Z

unless the function that accepts the infinite sequence needs to consume the whole thing before returning a generator

johanatan 2017-12-01T22:48:11.000221Z

i made these helpers to realize your idea above:

(defn- repeating-seq
  ([gen] (repeating-seq gen 1000))
  ([gen size] (with-meta (gen/fmap cycle (gen/vector gen size size)) {:size size})))

(defn- take-repeating-seq [n seq]
  (gen/fmap #(take n (drop (%1 1) (%1 0))) (gen/tuple seq (gen/choose 1 ((meta seq) :size)))))

2017-12-01T23:23:51.000186Z

Huh...

2017-12-01T23:24:23.000353Z

So you'd use take-repeating-seq several times on the same generated sequence?

johanatan 2017-12-01T23:34:30.000248Z

yea

2017-12-01T23:37:06.000031Z

You just don't know how many times you need to it until you're doing it?

johanatan 2017-12-01T23:38:49.000009Z

mm, well actually i've restructured the code since i did that so haven't had to use it yet. but i see it as a sort of escape hatch if one gets too deep

johanatan 2017-12-01T23:41:25.000167Z

[of course i could be totally confused 🙂 ] i always feel about halfway confused when deep in generator code