Recursion Clojure中的递归惰性seq

Recursion Clojure中的递归惰性seq,recursion,clojure,lazy-evaluation,Recursion,Clojure,Lazy Evaluation,我不明白为什么这个懒惰的seq会导致stackoverflow,为什么当您将序列传递给dorun时不会: (defn very-lazy [s] (lazy-seq (if (seq s) [(first s) (very-lazy (rest s))] []))) (dorun (very-lazy (range 200000000))) >nil (take 2 (very-lazy (range 20000000)) >...(1577 (

我不明白为什么这个懒惰的seq会导致stackoverflow,为什么当您将序列传递给dorun时不会:

(defn very-lazy [s]
    (lazy-seq
   (if (seq s)
     [(first s) (very-lazy (rest s))]
     [])))

(dorun (very-lazy (range 200000000)))
>nil

(take 2 (very-lazy (range 20000000))
>...(1577 (java.lang.StackOverflowError

如果是lazy,那么
take 2
应该会导致lazy seq只迭代两次,为什么不发生以及为什么dorun工作?

在示例中,函数返回lazyseq
(0(1(2(3(…))))
)。这就是为什么
dorun
在没有堆栈溢出的情况下运行(有两个元素的序列
0
(1(2(…)
,dorun不求值)和
second
失败(它返回repl尝试求值打印出来的无限嵌套序列)

我猜你在寻找这个解决方案

(defn very-lazy [s]
  (lazy-seq
   (if (seq s)
     (cons (first s) (very-lazy (rest s)))
     [])))

(take 10 (very-lazy (range 200000000)))
-> (0 1 2 3 4 5 6 7 8 9)

在REPL中评估惰性seq通常会导致打印正常使用情况下不会出现的结果时出现问题,例如,在REPL中只键入
(重复1)
是一个坏主意。您可以设置
*打印长度*
以限制输出,例如对于
(设置!*打印长度*10)
(重复1)
将作为
输出(1…)
在回复中。