带递归的惰性序列:某些情况下,带有repl

时间:2018-09-11 04:06:56

标签: emacs clojure cider

我玩clojure,更确切地说是懒惰。 我尝试了这段代码:

(defn even-numbers
  ([] (even-numbers 0))
  ([n] (cons n (lazy-seq (even-numbers (+ n 2))))))
(take 1 (even-numbers 0))

这很惯用,我不认为这有什么问题。

问题是我在emacs中使用了苹果酒。如果我首先评估defn,然后评估函数调用,则会出现堆栈溢出。评估整个缓冲区是可以的。

我怀疑应该指责启蒙模式,因为禁用它时不会溢出。我只想了解这里发生的事情。

[编辑]我很确定这个问题与苹果酒的启发模式有关。禁用它,我永远不会出现堆栈溢出。

考虑一下经过略微修改的摘录,对其进行深入研究:

(ns clojure-noob.bizarerrie)

(defn even-numbers
  ([] (even-numbers 0))
  ([n] (do (println (even-numbers (+ n 2)))
           (cons n (lazy-seq (even-numbers (+ n 2)))))))
(take 1 (even-numbers 0))

在每种情况下也会产生堆栈溢出。由于启蒙模式会尝试解析表达式以在执行过程中将其输出;直观地说,它会尝试打印(even-numbers (+ n 2))表单(例如我刚刚添加的println),这会导致堆栈溢出。

1 个答案:

答案 0 :(得分:0)

由于尝试实现无限延迟序列,您会得到堆栈溢出。您需要通过调用 take

函数来指定要在该序列中实现多少个值
(take 10 (even-numbers 0)) ; if you want to realize first 10 values