I'm aware of the Erlang implementation. Actually, people have even implemented it on Python and Javascript.
So far as I know in order to use these implementation you have to specify static type information about the test functions. Moreover, I don't think any of the alternative implementations have the flexibility of Haskell QC's Arbitrary typeclass for generating test data.
Obviously anything can be implemented equivalently across any Turing equivalent language. QC is deeply tied to the kinds of power you get from strong static typing, though. I'd be willing to bet that even though it exists on a few other platforms, it is not as useful or easy as it is in Haskell -- perhaps measurable by the average test coverage divided by the time spent writing tests in similarly developed programs.
"In reality when you move beyond very simple properties, then you almost always need to specify generators. Generation is more complex than just saying, give me an int. [...] So as soon as you move beyond very simple properties, you have to write the generators in Haskell also, so that you have to write them in the Erlang version is not a disadvantage."
Hm. I'd agree there. It's always very important to write a decent Arbitrary typeclass instance. I've never found it terribly hard -- it's always exactly as hard as trying to decide what the potential input space you support should be -- and I don't expect it to be in Erlang either.
The difference is that once you start combining Arbitrary instances you need to have strict, careful control over these input spaces, something "trivial" when you're abusing the Hindley-Miller type system. I've never written QC tests in Erlang, let alone at higher levels of complexity, but I can only imagine that it's a short while before you're forced to manually do inference a static type system auto-infers.
I don't think Hughes is talking about writing the implementation of the generators. He's talking about writing then down in your tests, e.g.
?FORALL(N,int(),
?FORALL(M,int(),
N+M==M+N)).
In Haskell you can specify the `int()`'s in the type instead of in the code. What I think Hughes is saying is that for real world testing scenarios, the standard type generators aren't fine grained enough. For example, you need to specify `positiveint()`, or `elementinlist(L)`.
So far as I know in order to use these implementation you have to specify static type information about the test functions. Moreover, I don't think any of the alternative implementations have the flexibility of Haskell QC's Arbitrary typeclass for generating test data.
Obviously anything can be implemented equivalently across any Turing equivalent language. QC is deeply tied to the kinds of power you get from strong static typing, though. I'd be willing to bet that even though it exists on a few other platforms, it is not as useful or easy as it is in Haskell -- perhaps measurable by the average test coverage divided by the time spent writing tests in similarly developed programs.