这段代码有很多语法问题;到处都是错误的引号,看起来你正在尝试使用数字作为变量,这是行不通的。您提到的特定错误消息的来源来自
(hanoi('('(list)'()'())))
首先,了解'x 和'(a b c) 中的quotes 是(quote x) 和(quote (a b c)) 形式的简写,而(quote anything) 是获取anything 的语法,没有@987654330 @被评估。所以'(1 2 3) 给你列表(1 2 3),'1 给你1。 quote 只是一个符号,并且可以出现在其他列表中,所以 '('(list)'()'()) 与 (quote ((quote (list)) (quote ()) (quote ()))) 相同,计算结果为列表 ((quote (list)) (quote ()) (quote ()))。由于() 也可以写成nil(或NIL),所以最后一个与('(list) 'NIL 'NIL) 相同。在 Common Lisp 中,函数调用看起来像
(function arg1 arg2 ...)
其中每个 argi 是一个表单,function 是一个符号(例如,list、hanoi、car)或一个列表,在这种情况下,它必须是一个 lambda 表达式,例如,(lambda (x) (+ x x))。所以,在你的行中
(hanoi('('(list)'()'())))
我们有一个函数调用。 function 是 hanoi,arg1 是 ('('(list)'()'()))。但是如何评估这个arg1?嗯,它是一个列表,这意味着它是一个函数应用程序。 function 部分是什么?这是
'('(list)'()'())
与
相同
'('(list 'NIL 'NIL))
但正如我刚才所说,唯一可以是function 的列表是lambda 表达式。这显然不是 lambda 表达式,因此您会看到您看到的错误。
我不能确定,但您的目标似乎是以下内容。标有** 的行有点问题,因为你用一些参数调用hanoi,当它返回时(如果它返回;在我看来,在这种情况下你会永远递归),你不要对结果做任何事情。它被忽略了,然后你进入第三行。
(defun pass-list(list)
(hanoi (list list) '() '()))
(defun hanoi (a b c)
(hanoi (rest a) (cons (first a) b) c) ; **
(hanoi (cons (first c) a) b (rest c)))
如果 hanoi 应该将单个列表作为参数,并且该列表应该包含三个列表(我不确定您为什么要这样做而不是让 hanoi 只取三个论点,但我想这是一个不同的问题),修改起来很容易;只需获取一个参数 abc 并从中提取第一个、第二个和第三个列表,然后在递归调用中将单个列表传递给 hanoi:
(defun hanoi (abc)
(let ((a (first abc))
(b (second abc))
(c (third abc)))
(hanoi (list (rest a) (cons (first a) b) c))
(hanoi (list (cons (first c) a) b (rest c)))))
我实际上可能会在这里使用destructuring-bind 来简化从abc 中获取a、b 和c:
(defun hanoi (abc)
(destructuring-bind (a b c) abc
(hanoi (list (rest a) (cons (first a) b) c))
(hanoi (list (cons (first c) a) b (rest c)))))