Clojure 累加器上的reduce和map产生堆栈溢出
为什么我需要用mapvin替换map这段代码以防止堆栈溢出:Clojure 累加器上的reduce和map产生堆栈溢出,clojure,stack-overflow,lazy-evaluation,Clojure,Stack Overflow,Lazy Evaluation,为什么我需要用mapvin替换map这段代码以防止堆栈溢出: #!/bin/bash lein-exec (println (reduce (fn [acc _] ;;(mapv #(inc %) acc))
#!/bin/bash lein-exec
(println (reduce (fn [acc _]
;;(mapv #(inc %) acc))
(map #(inc %) acc))
(repeat 2 0)
(range (long 1e6))))
~
我不明白懒惰时acc是如何处理的。感谢您的洞察力。基本上,您得到的是大量嵌套的惰性序列,当戳到它们时,会导致堆栈溢出 让我们看一个小例子:
(reduce (fn [acc _]
(map inc acc))
(repeat 2 0)
(range 3))
由于map是惰性的,因此上面的结果将是下一个:
(map inc (map inc (map inc (0 0)))
因此,您并不急于将acc映射到inc,而只是将惰性序列一个一个地放入另一个,这将在以后实现
回到原始示例,范围为1e6,结果如下:
(map inc
(map inc
(<... rougly 1e6 nested lazy sequences here ...>
(map inc (0 0))) ...)
实现这一点将消耗大约1e6个堆栈帧,这肯定会导致堆栈溢出
如果不涉及mapv惰性,并且acc立即实现,那么在reduce完成后,您的示例的结果将是[1000000 1000000]