【发布时间】:2014-03-19 18:33:57
【问题描述】:
所以我是 lisp 的新手,我对我遇到的问题感到很困惑:
(defun factorial (x)
(if (>= x 1)
(* x (factorial (- x 1)))
1))
阶乘函数可以输出3000!不过没问题
(defun sum (x)
(if (<= x 1)
1
(+ x (sum (- x 1)))))
(sum 10000) 的堆栈溢出,我正在使用 clisp。
谁能解释一下为什么会这样?
【问题讨论】:
-
不确定,但可能是语法错误 - sum 和 (- x 1) 之间应该有空格吗?
-
会更漂亮,但这不是错误:/。我很不确定为什么会这样,难道是 lisp 有最大数量的递归调用吗?
-
确实如此;如果您的解释器没有针对尾递归进行优化,那么您将拥有一个非常高的堆栈。你传递函数的数字是多少?这只是对阶乘的重新实现,对吧?
-
是的,我在搞乱这样的基本功能,我通过 (factorial 5000) 和 (sum 5000) 工作正常,但是到 (sum 6000) 它不再工作并且它堆叠溢出,我该如何解决?
-
@jstaab 即使实现优化了尾调用,这些函数也不是以适用的方式编写的。每个堆栈帧都需要保持活动状态,直到递归调用返回,以便可以执行算术运算。 (一个非常聪明的编译器可能会想办法优化它,也许是 tail recursion modulo cons。)