请分享您的想法到 Clojure 2024 状态调查!

欢迎!请查看 关于 页面了解更多关于这个网站如何运作的信息。

0
test.check
我认为 Clojure.core/for 的语法与 test.check 的组合符十分契合。例如


(defn gen-even-subset
  "返回一个生成器,生成给定元素的偶数基数子集"
   [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)
        (set))))
这结合了 fmap、bind 和 such-that 的功能,转换成了一个熟悉的语法。


这里的一个缺点是,可能会倾向于使用多个子句来生成独立生成器,从而在情况下通常可以使用 gen/tuple 时,形成了对 gen/bind 的使用。对此的一个方法是,添加一个额外的支持子句,也许可以称为 :parallel,它使用 :let 的语法来提供 gen/tuple 的功能

(gen/for [:parallel [n1 gen/nat


                      n2 gen/nat]
           :let [sum (+ n1 n2)]]
  {:nums [n1 n2] :sum sum})
与 gen/tuple 相比,这个的优点是将生成器在语法上与名称放置在一起,而不是将生成器从名称中分离。


:parallel 功能尚未添加到当前的补丁中。

请求

0
_评论者:gfredericks_
我认为 {{:when}} 的意义可能会存在设计上的模糊性。特别是,在以下人为编造的例子中

(for [n nat


      v (vec (return n))
      :let [sum (reduce + v)]
      :when (pos? sum)]
  v)
In my default design this can hang, for the same reason that this code can hang


In my default design this can hang, for the same reason that this code can hang


(绑定 nat
      (fn [n]
        (such-that
          (fn [v] (pos? (reduce + v)))
          (vector (return n)))))


但它也可以这样写


(such-that
  (fn [v] (pos? (reduce + v)))
  (bind nat (fn [n] (vector (return n)))))


所以问题在于是对前面的生成器仅应用 {{:when}} 过滤器,还是对所有的前面生成器都应用。我有一个模糊的概念,认为后者在某些情况下可能效率更低,但我不太确定具体是什么。因此,我认为我们的选择是

# 决定始终以一种方式或另一种方式执行
提供第三个关键字 ({{:when-all}}?),具有不同的行为
不编写这个宏,因为它太难以理解

我个人倾向于选择选项 1,只对前面的生成器应用 :when。
0
by

评论者:gfredericks

附上了我的初始草案。实现所需的思考比我预期的要多,因此我包含了关于宏结构的一些内联注释。

0
by

评论者:gfredericks

附上 TCHECK-15-p1.patch,已更新以适用于当前 master。

0
by

评论者:gfredericks

附上 TCHECK-15-p2.patch,在 docstring 中添加有关独立子句、缩小和元组的注释。

0
by

评论者:gfredericks

附上 TCHECK-15-p3.patch,修复了命名空间别名的其中一个错误和重复。

0
by

评论者:gfredericks

附上 TCHECK-15-p4.patch,修复了解构时的一个错误(并添加了一个回归测试)。

0

评论者:gfredericks

此外,我还将此代码放入了我的测试检查工具库中:https://github.com/fredericksgary/test.chuck#for

0

评论者:michaelblume

我怀疑是否可以通过分析代码并检查绑定是否可以并行运行来避免:parallel?

0

评论者:gfredericks

在理论上这是可能的,但我们需要访问一个无错误的代码遍历器。

此外,你可能会争论说,这会使代码的含义更加微妙。

0
参考资料: https://clojure.atlassian.net/browse/TCHECK-15(由gfredericks报告)
...