【问题标题】:Why does Clojure xform with side effects not behave as expected?为什么具有副作用的 Clojure xform 的行为不符合预期?
【发布时间】:2019-12-30 18:19:53
【问题描述】:

我发现向 Clojure 转换器添加副作用可能会导致以下意外行为:

(def counter (atom 0))

(def increment-counter-xform
  (map (fn [sample]
         (swap! counter inc)
         sample)))

(eduction increment-counter-xform (range 100))
@counter ;; => 100, as expected

(reset! counter 0)
(eduction increment-counter-xform (range 1000))
@counter ;; => 129, but I expected 1000

为什么上面的代码块对于少量样本会增加计数器的预期次数,但对于大量样本却不会?看来,即使range 的参数非常大,计数器的增量也永远不会超过 129 次。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    问题在于eduction 返回一个惰性序列。我认为 Clojure 有一些启发式方法,它可以在不强制的情况下实现多少项惰性序列,在这种情况下,它实现了 129 个项。如果示例代码中的倒数第二行更改为

    ,一切都会按预期进行
    (vec (eduction increment-counter-xform (range 1000)))
    

    之所以有效,是因为vec 强制实现整个序列。

    【讨论】:

      猜你喜欢
      • 2012-12-07
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 1970-01-01
      相关资源
      最近更新 更多