Lisp 关于两个函数的堆栈溢出

Lisp 关于两个函数的堆栈溢出,lisp,clisp,Lisp,Clisp,因此,我是lisp新手,对我遇到的问题感到非常困惑: (defun factorial (x) (if (>= x 1) (* x (factorial (- x 1))) 1)) 阶乘函数可以输出3000!但是没有问题 (defun sum (x) (if (<= x 1) 1 (+ x (sum (- x 1))))) (defun sum(x) (如果(您的函数不是尾部递归的,那么编译器(和解释器)会为每次迭代增加堆栈

因此,我是lisp新手,对我遇到的问题感到非常困惑:

(defun factorial (x)
  (if (>= x 1)
      (* x (factorial (- x 1)))
      1))
阶乘函数可以输出3000!但是没有问题

(defun sum (x)
  (if (<= x 1)
      1
      (+ x (sum (- x 1)))))
(defun sum(x)

(如果(您的函数不是尾部递归的,那么编译器(和解释器)会为每次迭代增加堆栈,最终耗尽堆栈

中列出了您的选项;相关选项包括:

  • 编译函数
  • 增加Lisp堆栈大小
  • 使用迭代而不是递归重写
  • 使用尾部递归重写并编译

  • 不确定,但可能是语法错误-sum和(-x1)之间是否应该有空格?会更漂亮,但这不是一个错误:/。我很不确定为什么会发生这种情况,可能是因为lisp的递归调用数量最多吗?这肯定是真的;如果你的解释器没有针对尾部递归进行优化,你将有一个非常高的堆栈。你传递函数的数量是多少?这只是一个重新实现阶乘运算,对吗?是的,我在处理这样的基本函数,我通过了(阶乘5000)和(求和5000),这两个函数运行得很好,但是要通过(求和6000)它不再工作,堆栈溢出,我该如何修复?@jstaab即使实现优化了尾部调用,这些函数也不会以适用的方式编写。每个堆栈帧都需要保持活动状态,直到递归调用返回,以便执行算术运算。(一个非常聪明的编译器可能会找到一种方法来优化它,也许是la。)