懒惰不能按预期工作

Pra*_*nav 6 functional-programming clojure lazy-evaluation chunking

(defn seq-trial
  []
  (map #(do (println "hello " %) (inc %)) (range 10)))

(take 3 (seq-trial))
Run Code Online (Sandbox Code Playgroud)

评估时上面的代码snippt打印出以下内容 -

(你好0你好1你好2你好3你好4 hello 5你好6 hello 7你好8你好9 1 2 3)

因为map返回了一个懒惰的序列,我希望这只能打印 -

(你好0你好1你好2 1 2 3)

为什么在这里评估整个列表?

sw1*_*1nn 8

这是因为称为分块的性能优化.本质上,序列是在称为块的n个项的组中实现的.这意味着您需要注意映射函数中的任何副作用.最终结果是正确的,你仍然得到一个返回正确长度的序列

默认的块大小为32,因此如果您将范围增加到大于该值的值,您将了解更好的内容:

user> (defn seq-trial
  []
  (map #(do (println "hello " %) (inc %)) (range 100)))

user> (take 3 (seq-trial))
hello  0 ; 32 item 'chunk' realized...
hello  1

...

hello  30
hello  31
(1 2 3)  ; the expected returned value
Run Code Online (Sandbox Code Playgroud)

如果您需要避免分块,可以选择

  • 副作用和懒惰评价不混合. (2认同)