gen/for macro for alternate combinator syntax


  • Type: Enhancement Enhancement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:


I think the syntax of clojure.core/for would be a good fit for test.check's combinators. For example:

(defn gen-even-subset
  "Returns a generator that generates an even-cardinality
   subset of the given elements"
  (gen/for [bools (apply gen/tuple (repeat (count elements) gen/boolean))
            :let [true-count (->> bools (filter identity) (count))]
            :when (even? true-count)]
    (->> (map list bools elements)
         (filter first)
         (map second)

This combines the capabilities of fmap, bind, and such-that into a familiar syntax.

One downside here is the temptation to use multiple clauses for independent generators, resulting in a use of gen/bind when gen/tuple would be simpler and presumably shrink easier. An approach to this is an additional supported clause, perhaps called :parallel, that uses the syntax of :let to provide the functionality of gen/tuple:

(gen/for [:parallel [n1 gen/nat
                     n2 gen/nat]
          :let [sum (+ n1 n2)]]
  {:nums [n1 n2] :sum sum})

Compared to gen/tuple, this has the advantage of placing generators syntactically next to names, rather than segregating the generators from the names.

The :parallel feature has not been added to the current patches.

  1. TCHECK-15.patch
    08/Apr/14 9:24 PM
    7 kB
    Gary Fredericks
  2. TCHECK-15-p1.patch
    13/Apr/14 8:33 PM
    6 kB
    Gary Fredericks
  3. TCHECK-15-p2.patch
    16/Apr/14 9:51 PM
    7 kB
    Gary Fredericks
  4. TCHECK-15-p3.patch
    16/Apr/14 9:58 PM
    7 kB
    Gary Fredericks
  5. TCHECK-15-p4.patch
    13/May/14 10:37 AM
    7 kB
    Gary Fredericks



Vote (3)
Watch (3)


  • Created: