lispcommon-lispclisp

How to replace an append with a cons in Common Lisp?


How I can replace an append with a cons in my lisp program that reverses a list and all it's substrings?

(defun revert (l)
  (cond
    ((atom l) l)
    (t (append (revert (cdr l))
               (list (revert (car l)))))))

(write (revert '(2 3 5 6 7 8 9 (4 5 (6)))))

With append the result is: (((6) 5 4) 9 8 7 6 5 3 2)

By replacing append with cons i get something like this: ((((((((NIL (((NIL (NIL 6)) 5) 4)) 9) 8) 7) 6) 5) 3) 2)

I tried to watch some youtube tutorials but I still don't know how to do it correctly


Solution

  • As you have seen, you cannot simply replace append with cons, because they are two very different operators: append concatenates two lists in a single list, while cons takes an element and a list and returns a new list with the element in first position, and the rest of the list the second parameter.

    One very simple way of solving your problem is simply to define your version of append using cons. For instance:

    (defun my-append (list1 list2)
      (cond ((null list1) list2)
            (t (cons (car list1) (my-append (cdr list1) list2))))))
    

    and the substituting append with my-append in the revert function.

    Another way, is to define a new function that takes two lists and reverses the first one to the beginning of the second one. For instance:

    (defun revert (l)
      (rev2 l nil))
    
    (defun rev2 (l1 l2)
      (cond ((null l1) l2)
            ((atom (car l1)) (rev2 (cdr l1) (cons (car l1) l2)))
            (t (rev2 (cdr l1) (cons  (revert (car l1)) l2)))))