3 ms·
Re-implementations of QuickCheck exist for C,[2] C++,[3] Chicken Scheme,[4] Clojure,[5] Common Lisp,[6] D,[7] Erlang,[8][9] F#,[10] Factor,[11] Io,[12] Java,[13
by joesb 13y ago
Re-implementations of QuickCheck exist for C,[2] C++,[3] Chicken Scheme,[4] Clojure,[5] Common Lisp,[6] D,[7] Erlang,[8][9] F#,[10] Factor,[11] Io,[12] Java,[13][14][15] JavaScript,[16] Node.js,[17] Objective-C,[18] OCaml,[19] Perl,[20] Python,[21] Ruby,[22] Scala,[23] Scheme,[24] Smalltalk[25] and Standard ML.[26]
- tikhonj 13y agoThe problem is that most of those implementations--even the OCaml one--are much more awkward to use than the Haskell version. So people don't. In Haskell, the type system--thanks to typeclasses--can figure out how to generate random inputs automatically, just based on what type is expected. Even if you have a custom type, it's incredibly easy to define how to generate elements and then use it everywhere. Or you could easily randomly generate values in an ad-hoc method wherever they're used. This takes advantage of the fact that in Haskell, values can be polymorphic on their return types. As far as I know, this is a feature unique to typeclasses--and very few languages aside from Haskell support those. (I only know of one other: Rust.) This, combine with Haskell's usual popular abstractions like Applicative Functors, makes writing QuickCheck-style properties and new random generators much easier. Of course, this particular reason has nothing to do with functional programming and everything to do with Haskell's glorious type system. However, functional programming does play a role in QuickCheck's popularity as well. Basically, QuickCheck-style tests are primarily useful for code that does not have side effects. QuickCheck lets you check some invariant by evaluating the same function hundreds or thousands of times with randomly generated input. This style simply does not scale to non-trivial non-local state, much less actual IO. So even if your language had a usable QuickCheck library, it would only be useful for the more functional parts of your code. As the article points out, unit tests push you towards a functional style to some extent. QuickCheck does this far more. And so most people writing rampantly imperative code in wantonly imperative languages simply don't use QuickCheck. Even if some intrepid soul has ported it.
- laureny 13y ago> In Haskell, the type system--thanks to typeclasses--can figure out how to generate random inputs automatically, just based on what type is expected. No. The reason why the type system is able to generate these values is because of algebraic data types, not type classes. Type classes are completely unrelated to this problem.
- tikhonj 13y agoWhat? The way the Arbitrary class works is only possible thanks to typeclasses. Without typeclasses, you would have to explicitly specify which generator to use. Thanks to the typeclass system, Haskell can just infer this. On the other hand, none of the Arbitrary machinery is particularly tied to algebraic data types per se. It would work as well if you had OO style constructors instead. Just take a look at the OCaml version of QuickCheck to see what I mean. OCaml obviously has algebraic data types, but it's still far more awkward to use QuickCheck there.
- kisielk 13y agoAnother limitation of quickcheck that's often overlooked is that simply using quickcheck for testing your function does not guarantee complete coverage of your function. The coverage may also differ between runs. So while it's good for doing a "quick check" of your function it's not a replacement for unit testing.