LISP和休息问题

gma*_*ter 2 lisp common-lisp

所以我是LISP的新手,我正在玩几个基本的函数.

(defun suma (&rest L)
  (cond
    ((null L) 0)
    (T (+ (CAR L) (EVAL (CONS 'suma (CDR L)))))
))


(defun suma2 (&rest L)
  (cond
   ((null L) 0)
   (T (+ (car L) (suma2 (cdr L))))
))
Run Code Online (Sandbox Code Playgroud)

第一个功能正常.第二个函数给出了这个错误:SB-KERNEL :: CONTROL-STACK-EXHAUSTED.

我的问题是:为什么第一个功能正常,第二个功能不是它们基本上做同样的事情?

sep*_*p2k 7

如果你打电话,说,(suma2 1 2 3),L将列表(1 2 3).然后你会打电话(suma2 (cdr L)),即(suma2 '(2 3)).在该调用L中将是列表((2 3)),即包含单个元素的列表:列表(2 3).现在它将(suma2 (cdr L))再次调用,这次(cdr L)是空列表,因此在下一次调用时L是包含空列表的列表.由于这仍然是一个包含一个元素的列表,它将再次递归并再次递归.L永远不会达到空的情况,因为它L总是一个只包含一个元素的列表:结果(cdr L).

因此,您应该更改suma2函数以接受列表而不是可变数量的参数(然后将其称为(suma2 (list 1 2 3))(suma2 '(1 2 3))代替(suma2 1 2 3))或使用applysuma2列表的内容作为其参数而不是列表本身进行调用.


Rai*_*wig 5

你在第二个函数( - > suma2)中的函数调用是错误的.

你希望你的函数被调用如下:

(suma2 1 2 3 4)
Run Code Online (Sandbox Code Playgroud)

但第一次递归调用相当于:

(suma2 '(2 3 4))
Run Code Online (Sandbox Code Playgroud)

您传递一个列表,其中包含预期的单个元素.请参阅文档APPLY.