I'm trying to implement the Towers of Hanoi.I'm not printing out anything between my recursive calls yet, but I keep getting an error saying
'('(LIST) 'NIL 'NIL) should be a lambda expression
I've read that the reason this happens is because of a problem with the parenthesis, however I cannot seem to find what my problem is. I think it's happening in the pass-list
function when I am trying to call the hanoi
function. My code:
(defun pass-list(list)
(hanoi('('(list)'()'())))
)
(defun hanoi ('('(1) '(2) '(3)))
(hanoi '('(cdr 1) '(cons(car 1) 2) '(3)))
(hanoi '('(cons(car 3)1) '(2)'(cdr 3)))
)
This code has many syntax problems; there are erroneous quotes all over the place, and it looks like you're trying to use numbers as variables, which will not work. The source of the particular error message that you mentioned comes from
First, understand that the quotes in
'x
and'(a b c)
are shorthand for the forms(quote x)
and(quote (a b c))
, and that(quote anything)
is the syntax for gettinganything
, withoutanything
being evaluated. So'(1 2 3)
gives you the list(1 2 3)
, and'1
gives you1
.quote
is just a symbol though, and can be present in other lists, so'('(list)'()'())
is the same as(quote ((quote (list)) (quote ()) (quote ())))
which evaluates to the list((quote (list)) (quote ()) (quote ()))
. Since()
can also be writtennil
(orNIL
), this last is the same as('(list) 'NIL 'NIL)
. In Common Lisp, function calls look likewhere each
argi
is a form, andfunction
is either a symbol (e.g.,list
,hanoi
,car
) or a list, in which case it must be alambda
expression, e.g.,(lambda (x) (+ x x))
. So, in your linewe have a function call.
function
ishanoi
, andarg1
is('('(list)'()'()))
. But how will thisarg1
be evaluated? Well, it's a list, which means it's a function application. What's thefunction
part? It'swhich is the same as
But as I just said, the only kind of list that can be
function
is alambda
expression. This clearly isn't alambda
expression, so you get the error that you're seeing.I can't be sure, but it looks like you were aiming for something like the following. The line marked with
**
is sort of problematic, because you're callinghanoi
with some arguments, and when it returns (if it ever returns; it seems to me like you'd recurse forever in this case), you don't do anything with the result. It's ignored, and then you go onto the third line.If
hanoi
is supposed to take a single list as an argument, and that list is supposed to contain three lists (I'm not sure why you'd do it that way instead of havinghanoi
take just three arguments, but that's a different question, I suppose), it's easy enough to modify; just take an argumentabc
and extract the first, second, and third lists from it, and pass a single list tohanoi
on the recursive call:I'd actually probably use
destructuring-bind
here to simplify gettinga
,b
, andc
out ofabc
: