2

I try to replace a certain element E in a list with another list K at all the main list levels.

(defun replaceList(l e k)
  (cond
    ((null l) nil)
    ((equal e (car l)) (cons k (replaceList (cdr l) e k)))
    ((listp (car l))
     ((equal e (car (car l))) (cons k (replaceList (cdr (car l)) e k))))
    (t (cons (car l) (replaceList (cdr l) e k)))))

Example:

(replaceList '(3 1 2 (6 1) 7 (5 (5 (3 1))) 9) '1 '(99 99))
--> (3 (99 99) 2 (6 (99 99)) 7 (5 (5 (3 (99 99) ) ) ) 9)

I get something with lambda expression as error message.

Also,i tried instead of the listp(car l) "block" : ((listp (car l)) (cons k (replaceList (cdr (car l)) e k))). I get something weird : (2 1 3 ( 6 1 7) 7 1 2 ) -> (2 (99 99) 3 (99 99) (99 99) 7)

1
  • 2
    "I get something with lambda expression as error message" -- please copy and paste the exact error message. Commented Dec 11, 2017 at 18:32

1 Answer 1

6

Error

Your "lambda expression message" is due to an extra set of parens around equal in the listp clause. Remember, Lisp parentheses are meaningful.

Use the standard library!

ANSI Common Lisp has subst which does what you want:

(subst '(99 99) 1 '(3 1 2 (6 1) 7 (5 (5 (3 1))) 9) :test #'equal)
==> (3 (99 99) 2 (6 (99 99)) 7 (5 (5 (3 (99 99)))) 9)

Your algorithm

Since you are operating on the tree, not list (you say "all the main list levels"), you should treat car and cdr identically:

(defun my-subst (new old tree &key (test #'eql))
  (cond ((funcall test old tree)
         new)
        ((atom tree)
         tree)
        (t
         (cons (my-subst new old (car tree) :test test)
               (my-subst new old (cdr tree) :test test)))))
(my-subst '(99 99) 1 '(3 1 2 (6 1) 7 (5 (5 (3 1))) 9) :test #'equal)
==> (3 (99 99) 2 (6 (99 99)) 7 (5 (5 (3 (99 99)))) 9)

Or, simplified (without &key and funcall):

(defun my-subst (new old tree)
  (cond ((equal old tree)
         new)
        ((atom tree)
         tree)
        (t
         (cons (my-subst new old (car tree))
               (my-subst new old (cdr tree))))))
Sign up to request clarification or add additional context in comments.

4 Comments

Hello,@sds. Thank you for your answer.But there is not any possible modification to my code to make it work? Our professor insisted to not work with standard library functions like 'subst'( yes,i know,it's a little bit weird,but i think she wants to make us understand the algorithm behind this......).Thank you for the helping links also :)
@EduardAdrian: isn't my-subst what you are looking for? You can change the order of arguments, of course. Let me reiterate: if you are not using car and cdr symmetrically, you are not doing the right thing.
It might be,but i don't understand the &key (test #'eql) and funcall structure. We are at a very basic level,i think we will learn about that later. That's why i asked for a very simplistic way of solving the exercise.
@EduardAdrian: I added a simplified version.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.