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/bind}},而当 {{gen/tuple}} 简单且可能更易于缩小。

对此的解决方案可能是添加一个额外的受支持的子句,可能称为 {{: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}}?) 以实现不同的行为
# 因为其难以理解,所以不编写此宏

我的直觉是要选择选项1,仅将 :when 应用到前面的生成器上。
0

评论者:gfredericks

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

0

评论者:gfredericks

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

0

评论者:gfredericks

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

0

评论者:gfredericks

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

0

评论者:gfredericks

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

0

评论者:gfredericks

同时,也可能有用,我已经将它放入我的测试.check实用程序库中: https://github.com/fredericksgary/test.chuck#for

0

评论者:michaelblume

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

0

评论者:gfredericks

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

此外,你可以认为这会使代码的含义更加微妙。

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