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) 
    \n(->> (map list bools elements) 
        Bad indent.
        (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}} 过滤器应用于上一个生成器,还是应用于所有上一个生成器。我有一种模糊的想法,认为在某些情况下后者可能效率更低,但我不确定。因此,我认为我们有两个选择:

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

我的直觉是选择第一种方法,只将 :when 应用于上一个生成器。
0
by

评论由:gfredericks 提出

附带我的初步草案。该实现比我预期的要复杂得多,因此我包含了一些内联注释来解释宏的结构。

0
by

评论由:gfredericks 提出

附加 TCHECK-15-p1.patch,更新以适用于当前主版本。

0
by

评论由:gfredericks 提出

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

0
by

评论由:gfredericks 提出

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

0
by

评论由:gfredericks 提出

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

0

评论由:gfredericks 提出

另外,我还将此放入了我的测试工具库的test.check中:[https://github.com/fredericksgary/test.chuck#for](https://github.com/fredericksgary/test.chuck#for)。

0

评论者:michaelblume

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

0

评论由:gfredericks 提出

从理论上讲,这是可能的,但我们需要访问一个非错误的代码浏览器。

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

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