【发布时间】:2018-03-10 10:56:51
【问题描述】:
您能否更广泛、更清楚地解释一下,lazy-seq 如何根据此文档页面使尾递归“安全”?
https://clojuredocs.org/clojure.core/lazy-seq
;; The following defines a lazy-seq of all positive numbers. Note that
;; the lazy-seq allows us to make a recursive call in a safe way because
;; the call does not happen immediately but instead creates a closure.
user=> (defn positive-numbers
([] (positive-numbers 1))
([n] (lazy-seq (cons n (positive-numbers (inc n))))))
#'user/positive-numbers
user=> (take 5 (positive-numbers))
(1 2 3 4 5)
【问题讨论】:
-
当您进行函数调用(在大多数语言中)时,您会将一个新帧压入调用堆栈。如果您重复生成无限的数字序列(递归或循环),您最终会溢出。通过使用惰性求值,您的递归次数仅与
take的参数一样多。 -
@JaredSmith 实际上,无论
take的参数如何,您都只会向堆栈添加少量恒定数量的帧。你自己很容易看出你的解释是行不通的:试着写(last (take 1e6 (range))),并观察即使你的JVM没有空间容纳一百万个堆栈帧,你仍然得到正确的答案。 -
@amalloy 我的立场是正确的。
标签: clojure