Dkyo Jeong
Dkyo Jeong

Reputation: 25

How to make deep-reverse function in Lisp

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

Answers (2)

coredump
coredump

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

jkiiski
jkiiski

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

Related Questions