为什么 filterv 的谓词需要没有副作用?
Why does filterv's predicate need to be free of side-effects?
我终于学习了 Box2D(使用 cljbox2d port)。在 "hello world tests" 期间,我发现需要一个函数来检查框列表,销毁并从列表中删除超出范围的框。
我写的处理这个的基本函数是*
:
(defn handle-out-of-bounds! [boxes]
(filterv (fn [{:keys [body]}]
(when-not (inbounds? (bc/position body))
(bc/destroy! body)))
boxes))
这里需要注意的是 destroy!
,顾名思义,会产生副作用。
我决定检查一下 filterv
的来源,因为我从来没有真正检查过,并且注意到文档字符串有警告:
. . . pred must be free of side-effects.
为什么?filter
我看出来了。它是惰性的,因此您无法保证谓词在任何给定点实际上 运行 除非您明确强制评估。 filterv
然而是对列表的严格缩减;在内部使用瞬态向量。唯一值得怀疑的是瞬变的使用,但我看不出这会产生什么影响。
实际上不在filterv
的谓词中执行副作用的有效理由,还是仅仅是概念上的原因?
*
写完我才发现我的逻辑不对,这个函数实际上是坏了,但这不是重点。我也可以单独处理销毁和移除,但同样,这不是问题。
其他人之前对此感到困惑,例如在this mailing list post中看到相同的问题。
那些发表评论的人似乎也同意所讨论的说法是没有动机的。 filterv
很急切,副作用 pred
没有问题。
如果陈述有误,可能的解释是文档字符串中存在简单的复制粘贴错误。 mapv
和 filterv
were introduced by Stuart Halloway,他们简单地复制了 map
和 filter
的文档字符串,并用“向量”代替了“惰性序列”。
我终于学习了 Box2D(使用 cljbox2d port)。在 "hello world tests" 期间,我发现需要一个函数来检查框列表,销毁并从列表中删除超出范围的框。
我写的处理这个的基本函数是*
:
(defn handle-out-of-bounds! [boxes]
(filterv (fn [{:keys [body]}]
(when-not (inbounds? (bc/position body))
(bc/destroy! body)))
boxes))
这里需要注意的是 destroy!
,顾名思义,会产生副作用。
我决定检查一下 filterv
的来源,因为我从来没有真正检查过,并且注意到文档字符串有警告:
. . . pred must be free of side-effects.
为什么?filter
我看出来了。它是惰性的,因此您无法保证谓词在任何给定点实际上 运行 除非您明确强制评估。 filterv
然而是对列表的严格缩减;在内部使用瞬态向量。唯一值得怀疑的是瞬变的使用,但我看不出这会产生什么影响。
实际上不在filterv
的谓词中执行副作用的有效理由,还是仅仅是概念上的原因?
*
写完我才发现我的逻辑不对,这个函数实际上是坏了,但这不是重点。我也可以单独处理销毁和移除,但同样,这不是问题。
其他人之前对此感到困惑,例如在this mailing list post中看到相同的问题。
那些发表评论的人似乎也同意所讨论的说法是没有动机的。 filterv
很急切,副作用 pred
没有问题。
如果陈述有误,可能的解释是文档字符串中存在简单的复制粘贴错误。 mapv
和 filterv
were introduced by Stuart Halloway,他们简单地复制了 map
和 filter
的文档字符串,并用“向量”代替了“惰性序列”。