-
Notifications
You must be signed in to change notification settings - Fork 406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support non-constant arbitrary functions #171
Conversation
Argh! Tests passed locally -- will investigate why they are failing for Travis. |
Oh, OK. These are all MIMA failures. This change is definitely not binary-compatible. |
awesome! But maybe there is a same issue as my library.
|
Ouch! Good catch. Yes, that's definitely a bug. |
import language.higherKinds | ||
import language.implicitConversions | ||
|
||
sealed trait Cogen[-T] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sealed abstract class
is better for keep binary compatibility.
following expression should returns
|
@non This is great stuff! I have worked in a similar direction in the So the question is how to go forward. The realistic approach is probably to try to get the immutable gen and cogen into a 1.13 release, and keep my other changes for 2.0. I'll make an attempt to dig into your solution as soon as possible. |
There does seem to be a problem with @rickynils that sounds fine. Let me know if you see any issues or want me to make any changes. |
@non If you rebase this PR, you can bump |
This commit introduces a (seed: Long) parameter to many methods that need to generate random values, as well as an Rng object that implements a simple linear-congruent RNG. The jvm tests pass. Currently getting permgen/OOM errors in the js tests, not sure if this indicates a problem with the implementation. Still to do: there are still probably places where seeds are not being threaded through correctly.
This type allows values to perturb the RNG, meaning that we can build something resembling a true Gen[A => B]. The basic strategy is as follows: Given a Cogen[A] and a Gen[B], we can create an A => B. When we are given a particular A value, we use Cogen[A] to permute the RNG seed we have, and then use Gen[B] to generate a B value. In this way, the B values created are dependent on the A values provided, and we have a "real" function. This commit doesn't actually do any of that yet, but it does introduce a Cogen[A] type, and define a bunch of useful instances.
There is some ugliness in here (for example, .retrieve.get is a pattern I've copied from elsewhere in the code). However, the instances I've produced do seem to work. The next step is to figure out how to use code-gen to create these methods, as well as updating the Arbitrary code.
This commit adds support for code-generation for Gen. To use it, you'd do something like: import scalacheck._ import Arbitrary.arbitrary Gen.function1[Int, Int](arbitrary[Int]) // returns a Gen[Int => Int] instance // uses implicit Cogen[Int] The only step that is left (besides writing tests) is to start generating new Arbitrary[_] instances that use these methods to provide better arbitrary functions.
This commit updates the code-generation script to use the Gen.functionN methods to produce better arbitrary functions. This is a breaking API change. We probably need to add more Cogen instances for end-users to avoid breaking their tests. However, Scalacheck's own tests still pass. At this point the feature is added, and what is needed is clean up and fleshing out the stable of Cogen instances.
Thanks to @xuwei-k for catching this.
Alright, I just did what you suggested: I rebased against I'm still working on the issue that @xuwei-k noticed with |
This commit swaps out the 64-bit linear-congruent RNG for a variant on Bob Jenkin's simple RNG [1]. It provides much better support for the kind of reseeding that Cogen needs. [1] http://burtleburtle.net/bob/rand/smallprng.html
This commit adds properties to ensure that Cogen + Gen are producing all the possible functions for types. It ensures that our RNG is doing a good job using the entropy from function arguments to reseed itself to produce novel output values.
These last commits fix the issue that @xuwei-k found. At this point I consider the PR feature complete. @rickynils is there anything else you'd like me to do? Scalacheck probably needs documentation explaining how |
👍 |
Support non-constant arbitrary functions
This is awesome! |
Now that snapshots are published automatically, you can try out this in |
scalacheck generate non-constant Function Arbitrary since 1.13.0 typelevel/scalacheck#171
I found this page while looking for documentation on the topic of |
This PR adds support for better
Arbitrary[FunctionN[...]]
instances. It does a few things:scala.util.Random
.Gen
methods to explicitly receive (and pass) RNG seeds (Long
values)Cogen
type to permutate RNG seed states.Cogen
instances for many built-in types.Gen
andArbitrary
instances for functionsbuild.sbt
to get tests running faster for ScalaJS.There is a bit of sketchiness in
Gen
due to its use ofOption[A]
instead ofA
. I was forced to use.get
(like a few other existing methods do) which is not ideal. I can't tell if you'd expect this to be a major problem for ScalaCheck users.We should also add a bunch more
Cogen
instances. I chose not to do this until I got a sense of whether this PR was going in the right direction.Finally, while I bet most people using arbitrary functions would use primitive types, there is a bunch of work around updating documentation to explain this approach (and how to define custom
Cogen
instances).Fixes #136