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 [EMAIL 
PROTECTED]))))))
              forms))))

         

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to