为什么filterv的谓词需要没有副作用?

时间:2018-08-22 02:05:07

标签: clojure side-effects

我正在最终学习Box2D(使用cljbox2d port)。在我的“ hello world测试”中,我发现需要一个功能,该功能可以检查盒子列表,从列表中删除盒子并从列表中删除。

我编写来处理此问题的基本功能是*

(defn handle-out-of-bounds! [boxes]
  (filterv (fn [{:keys [body]}]
             (when-not (inbounds? (bc/position body))
               (bc/destroy! body)))
           boxes))

这里要注意的是destroy!顾名思义,会产生副作用。

由于我从未真正发现filterv的原因,因此决定踢它,并注意到文档字符串中有警告:

  

。 。 。 pred必须没有副作用。

为什么? filter我可以看到。这是懒惰的,因此您无法保证谓词实际上会在任何给定的点运行,除非您明确强制执行评估。 filterv严格限制了该列表;内部使用瞬态矢量。唯一可疑的是瞬态的使用,但我不知道这会如何影响。

实际上是不是在filterv谓词中产生副作用的有效原因,还是仅仅是概念上的原因?


*在写完之后我意识到我的逻辑已关闭,并且该功能实际上已损坏,但这还不重要。我也可以分别处理销毁和清除工作,但是,除了这个问题之外。

1 个答案:

答案 0 :(得分:1)

以前,其他人对此感到困惑,例如在this mailing list post中看到相同的问题。

发表评论的人似乎也同意,所讨论的陈述没有动机。 filterv渴望,副作用pred没问题。

如果该语句错误,则可能的解释是doc字符串中存在简单的复制和粘贴错误。 mapvfilterv were introduced by Stuart Halloway,他们只是复制了mapfilter的文档字符串,并用“ vector”代替了“ lazy sequence”。