假设我写了:
(def stuff
(lazy-seq stuff))
当我在 REPL 中询问
stuff
的值时,我预期会被陷入无限循环,因为我定义了 stuff
为它自己(这几乎没有说明这个序列的任何信息)。然而,我得到了一个空序列。
> stuff
()
为什么会这样呢?
编辑:我指的是递归数据,而不是递归函数。
我仍然对为什么序列终止感到困惑。相比之下,以下代码陷入了无限循环(并且导致堆栈溢出)。
(def stuff
(lazy-seq (cons (first stuff) [])))
一些背景:这个问题来自于我尝试使用埃拉托色尼筛法实现素数生成器。我的第一次尝试是:
(def primes
(lazy-seq (cons 2
(remove (fn [x]
(let [ps (take-while #(< % x) primes)]
(some #(zero? (mod x %)) ps)))
(range 3 inf))))) ;; My customized range function that returns an infinite sequence
我原本以为这样做行不通,因为 take-while
即使无法计算出更多的质数仍然会继续请求。但让我惊讶的是它的效果还不错。
> (take 20 primes)
(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71)
(defn stuff [] (lazy-seq (stuff)))
。 - leetwinskitake-while
is limited by x, and x is a current primes 'cap', so it will never ask for more primes over the ones that are already generated. Alsorange
already produces infinite seq, no need to customize it.(drop 3 (range))
, or(iterate inc 3)
- leetwinskisome
不会遍历所有质数(包括5本身),并检查它们中是否有任何一个是因子吗? - Yizhe Sunprimes
的定义为什么有效,并在博客文章中写了一些内容:https://phillippe.siclait.com/blog/primes-lazy-sequence - Phillippe Siclait