2024年Clojure现状调查中分享您的观点!

欢迎!请参阅关于页面以了解更多关于此功能的信息。

0
test.check
我认为{{clojure.core/for}}的语法非常适合test.check的组合器。例如


(defn gen-even-subset
  "返回一个生成器,该生成器生成给定元素的偶数基数子集"
   [elements]
    "    [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}}过滤器应用于先前的生成器,还是应用于所有先前的生成器。我有一种模糊的感觉,后者在某些情况下可能效率更低,但我不确定。因此,我认为我们的选择是

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

我的直觉是选择选项1,只将: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已修复析构错误(并添加了回归测试)。

0
by

评论者:gfredericks

此外,我还将此添加到我的test.check实用程序库中供现在使用:https://github.com/fredericksgary/test.chuck#for

0
by

评论者:michaelblume

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

0
by

评论者:gfredericks

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

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

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