anybody want a ClojureCheck?

36 views
Skip to first unread message

Stuart Halloway

unread,
Sep 29, 2008, 5:27:59 PM9/29/08
to clo...@googlegroups.com
Hi all,

At the JVM summit Clojure breakout someone suggested a Haskell
QuickCheck/ScalaCheck library for Clojure. I am attaching a small
spike in that direction below. A few questions:

(1) Is anybody interested?

(2) If the answer to (1) is yes, do you like the direction I am going
in the public API, e.g.

(for-all [x Integer y Integer] (some stuff that must be true))

(3) Any suggestions about implementation detail? (E.g. I like using a
multimethod for arbitrary--is there a prettier syntax for ignoring the
argument after using it for dispatch?)

Cheers,
Stuart

;;; clojure_check.clj: quick check framework for Clojure

;; Copyright (c) 2008 Stuart Halloway. All rights reserved.

;; Inspired by Scalacheck et al (http://code.google.com/p/scalacheck/)
;; Licensed under the same CPL as Clojure (http://clojure.org)

;; Uses clojure.contrib.test-is for assertions
;;
;; Example (passing)
;; (for-all [x Integer y Integer] (= (+ x y) (+ y x)))
;;
;; Example (failing)
;; (for-all [x Integer y Integer] (= (+ x y) (- y x)))

(ns clojure-check
(:import (java.util Random))
(:use clojure.contrib.test-is))

(defmulti arbitrary identity)

(def random (Random.))

(defn collection-size []
(.nextInt random 100))
(def *check-count* 50)

(defn choose [rng]
(nth rng (.nextInt random (count rng))))

(defmethod arbitrary Integer [_] (.nextInt random))
(defmethod arbitrary Character [_] (char (.nextInt random)))
(defmethod arbitrary :ascii-character [_] (char (choose (range 32
128))))

(defmethod arbitrary String [_]
(apply str (take (collection-size) (iterate (fn[_] (arbitrary
Character)) nil))))
(defmethod arbitrary :ascii-string [_]
(apply str (take (collection-size) (iterate (fn[_]
(arbitrary :ascii-character)) nil))))

(defmacro binding-values [& vars]
`(vector ~@(map (fn [v] `['~v ~v]) vars)))

(defmacro for-all [args & forms]
(let [vars (take-nth 2 args)
value-generators (map (fn [x] `(arbitrary ~x))(take-nth 2 (rest
args)))]
`(do
~@(map (fn [f]
`(dotimes i# *check-count*
(let ~(apply vector (interleave vars value-generators))
(is (true? ~f) (pr-str (binding-values ~@vars))))))
forms))))


Meikel Brandmeyer

unread,
Sep 30, 2008, 10:14:16 AM9/30/08
to clo...@googlegroups.com
Hello Stuart,

Am 29.09.2008 um 23:27 schrieb Stuart Halloway:

> At the JVM summit Clojure breakout someone suggested a Haskell
> QuickCheck/ScalaCheck library for Clojure. I am attaching a small
> spike in that direction below. A few questions:
>
> (1) Is anybody interested?

YES! Actually this was on my TODO/Wanna-have list for quite some time
now.

> (2) If the answer to (1) is yes, do you like the direction I am going
> in the public API, e.g.
>
> (for-all [x Integer y Integer] (some stuff that must be true))

There are other ports where the names are handled a bit differently
than for QuickCheck. Eg. LectroTest for Perl names it "property".
However "for-all" is ok for me and it fits with names like "for" having
a similar syntax.

> (3) Any suggestions about implementation detail? (E.g. I like using a
> multimethod for arbitrary--is there a prettier syntax for ignoring the
> argument after using it for dispatch?)

One could provide generator functions directly, eg.
(for-all [x gen-integer] (do-something-with x))

However just specifying the class/tag and getting the corresponding
generator looks and feels much nicer. One could set up an own
infrastructure where one has to register the generators...

So maybe it's (ab/mis)use of the multimethods... I don't know. Maybe I'm
thinking a bit practical here, but I would use them also.

For the _. I - personally - like the syntax. I'm kind of used to it due
to OCaml where it is used in patterns for exactly this purpose: there
is something, but we don't care what it is. It also reminds me of
H _ n g m _ n. There we used this notation also. :) In Clojure it would
be only "convention", but I think eg. "unused" doesn't give more
value...

Sincerely
Meikel

Reply all
Reply to author
Forward
0 new messages