Welcome! Please see the About page for a little more info on how this works.

0 votes
in test.check by
Currently {{gen/choose}} is the generator that everything else is based off of, and it's also a user-facing generator. Its current implementation takes a {{[0,1)}} double and scales it to the desired range. This approach degrades w.r.t. distribution as you get higher, and presumably has pretty terrible properties once your range is larger than {{2^53}}. It could also be optimized better for when the range is a power of 2 (no need to go through {{Double}}). Seeing as how {{gen/choose}} is user facing, we should attempt to redesign it so that it doesn't degrade in this fashion, and can handle bigints.

h2. Requirements

h3. {{gen/choose}} should have a uniform distribution regardless of bounds

h3. {{gen/choose}} should accept arbitrary integer bounds and handle them correctly

h2. Things to investigate

* Note that the [SplittableRandom|https://github.com/openjdk-mirror/jdk/blob/adea42765ae4e7117c3f0e2d618d5e6aed44ced2/src/share/classes/java/util/SplittableRandom.java#L263-308] class generates integer ranges without going through floating point. We should check if this is faster, since it's definitely a more uniform distribution.
* Is it worth optimizing for the power-of-two case, the same with {{SplittableRandom}} does in the link above?
* When it's possible for the generator to return a long instead of a bigint is somewhat subtle. E.g., if you call {{(gen/choose Long/MIN_VALUE Long/MAX_VALUE)}}, then when analyzing the size of the range you'll have to use a bigint (because {{2^64}} is not representable as a long). {{gen/choose}} should generate longs when both args are in long range, probably?
* Is it actually possible to satisfy the requirements above without a performance hit? You'd think it was just a generator-creation-time change, but {{bind}} can blur the line between generator creation and generation time.

3 Answers

0 votes
by

Comment made by: gfredericks

On second thought, I might be more in favor of leaving {{choose}} the way it is, discouraging its use by users, and adding a {{uniform-integer}} generator that is specifically designed to handle arbitrary ranges. A big question is what it should do in JavaScript, and I have a couple ideas about that.

0 votes
by

Comment made by: gfredericks

I'm reconsidering whether this is a good idea, compared to just designing a new set of cleaner generators.

0 votes
by
Reference: https://clojure.atlassian.net/browse/TCHECK-70 (reported by gfredericks)
...