2024 年 Clojure 状况调查! 中分享您的想法。

欢迎!请参阅 关于 页面以获取更多关于如何使用此系统的工作信息。

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}} 功能尚未添加到当前的补丁中。

请问

10 个答案

0
_评论来自:gfredericks_

我认为关于 {{:when}} 的含义可能存在一些设计上的模糊性。特别是,在以下构造的示例中


(for [n nat
      v (vec (return n))
      :let [sum (reduce + v)]
      :when (pos? sum)]
  v)


在我默认的设计中,这可能会挂起,原因与以下代码挂起相同


(bind 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}} 过滤器应用于之前的生成器,还是应用于所有之前的生成器。我模糊地觉得后者在某些情况下可能不太高效,但不清楚是什么原因。所以我认为我们的选项有

# 总是决定以某一种方式做或者另一种方式
# 提供一个第三keywords ({{:when-all}}?) 以实现不同的行为
# 不编写这个宏,因为它太难理解了

我的直觉是选择第一种选项,只将 :when 应用到之前的生成器上。
0

评论者:gfredericks

附上我的初步草案。实现过程比我预期的要复杂得多,有一定的微妙之处,所以我包括了说明宏结构的内联注释。

0

评论者:gfredericks

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

0

评论者:gfredericks

附上TCHECK-15-p2.patch,在文档字符串中添加关于独立子句、收缩和元组的注释。

0

评论者:gfredericks

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

0

评论者:gfredericks

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

0

评论者:gfredericks

此外,我已将此放入我的测试库test.check中: https://github.com/fredericksgary/test.chuck#for

0

评论:michaelblume

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

0

评论者:gfredericks

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

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

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