Reputation: 25
I am trying to make deep-reverse function in lisp. For example:
(a (b c d) e) -> (e (d c b) a)
Here is my code.
(defun deeprev (l)
(cond ((null l) nil)
((list (car l)) (append (deeprev (cdr l)) (deeprev (car l))))
(t (append (deeprev (cdr l))(car l)))
)
)
Whenever I compile and load, I have an error:
Error: Attempt to take the car of E which is not listp
Upvotes: 0
Views: 444
Reputation: 38799
In your function, you assume that if the l
input variable is not nil
, then it is necessarily a cons-cell, because you unconditionally takes (car l)
inside the (list ...)
function. That's why you have an error. There are many other things that are not nil
which could be bound to l
at this point, like numbers or symbols.
By the way, (list ...)
just builds a list, you would need to use listp
instead. Since you ruled out the nil
case and a list is defined as either nil
or a cons
, you could have used also consp
.
Upvotes: 3
Reputation: 8411
The easiest option would be to just REVERSE
the current list, and use MAPCAR
to reverse all sublist with the same function.
(defun tree-reverse (tree)
"Deep reverse TREE if it's a list. If it's an atom, return as is."
(if (listp tree)
(mapcar #'tree-reverse
(reverse tree))
tree))
(tree-reverse '(a (b c d) e)) ;=> (E (D C B) A)
Upvotes: 4