Clojure 为什么filterv';s谓词是否需要无副作用?

Clojure 为什么filterv';s谓词是否需要无副作用?,clojure,side-effects,Clojure,Side Effects,我终于学会了Box2D(使用)。在我的“hello world测试”中,我发现需要一个函数来检查框列表,销毁并从列表中删除超出范围的框 我编写的处理此问题的基本函数是*: (defn handle-out-of-bounds! [boxes] (filterv (fn [{:keys [body]}] (when-not (inbounds? (bc/position body)) (bc/destroy! body)))

我终于学会了Box2D(使用)。在我的“hello world测试”中,我发现需要一个函数来检查框列表,销毁并从列表中删除超出范围的框

我编写的处理此问题的基本函数是
*

(defn handle-out-of-bounds! [boxes]
  (filterv (fn [{:keys [body]}]
             (when-not (inbounds? (bc/position body))
               (bc/destroy! body)))
           boxes))
这里值得注意的是,
destroy,顾名思义,会产生副作用

我决定让kicks查看
filterv
的源代码,因为我从来没有这样做过,并注意到文档字符串中有警告:

。pred必须没有副作用

为什么?<代码>过滤器
我可以看到。它是惰性的,因此除非显式强制求值,否则不能保证谓词将在任何给定点实际运行
filterv
然而,这是对列表的严格缩减;内部使用瞬态向量。唯一值得怀疑的是瞬态的使用,但我不知道这会有什么影响

filterv
的谓词中,是否存在不执行副作用的有效原因,或者仅仅是一个概念上的原因



*
我在写它之后意识到我的逻辑是关闭的,并且这个函数实际上是坏的,但这不是重点。我也可以分别处理销毁和移除,但这又是一个问题。

其他人以前对此感到困惑,例如,请参见中的同一个问题

那些发表评论的人似乎也同意,有关声明没有动机
filterv
是急切的,副作用
pred
没有问题


如果语句错误,可能的解释是文档字符串中的简单复制粘贴错误
mapv
filterv
,他们简单地复制了
map
filter
的文档字符串,并用“vector”代替了“lazy sequence”。

既然这是推测,我就等着看是否还有其他东西进来,但如果你是对的,我不会感到惊讶。我已经打开了……让我们看看是怎么回事。很酷,谢谢。如果能澄清/修复这个问题,那就太好了。