From: Pascal Bourguignon
Subject: Re: Remove every atom
Date: 
Message-ID: <87wsvy6nnf.fsf@thalassa.informatimago.com>
·············@gmail.com writes:

> Hi everyone,
>
> I'm still new to Lisp. I've been learning Lisp for quite a while and
> still having lots of difficulties with recursion. Do you suggest any
> books, places... where I could learn more about recursion?

"The Little Lisper".  The latest editions are "The Little Schemer".
There are additionnal volumes:  "The Seasonned Schemer" and "The
Reasoned Schemer".

Otherwise any CS university should teach about recursion...


> As well, I'm doing in Lisp exercise (not a homework problem). This is
> to remove an atom e from all levels of a list.
> It should work this way:
>
> (delete-in 'a '(a b (d (c a)) a d))
> (B (D (C))
>
> I worked out the solution.
>
> (defun delete-in (e l)
>   (cond ((null l) nil)
> 	((equal e (car l)) (delete-in e (cdr l)))
> 	((atom (car l)) (cons (car l) (delete-in e (cdr l))))
> 	(t (cons (delete-in e (car l))
> 		   (delete-in e (cdr l))))))
>
> Then I tried to code the solution another way, which is this way:
>
> (defun delete-in (e l)
>   (cond ((null l) nil)
> 	((equal e l) nil)
> 	((atom l) l)
> 	(t (cons (delete-in e (car l))
> 		 (delete-in e (cdr l))))))
>
> Of course the result is not right:
>
>  (delete-in 'a '(a b (d (c a)) a d))
> (NIL B (D (C NIL)) NIL D)
>
> How should I think about these two ways of recursion for doing the
> same thing?

Obviously, they are not doing the same thing!


> Is there a way to modify the
> second one so that it works?

Yes, transform it to the first!


Ok, another way would be to realize that NIL is a symbol is an atom.
Unfortunately, it's the atom that is used to denote empty lists.  So
if you want to do the job by testing the argument of the function
instead of its CAR, you'll have to return something else than a list
to be able to distinguish empty lists from the symbol NIL.  And of
course, you need to distinguish between a NIL in the middle of the
list (stored in a CAR) from the NIL denoting the end of a list (in a
CDR).

Note how the correct solution treats NIL:

C/USER[87]> (delete-in 'a '(a nil b nil (nil c nil d a e nil . NIL) . NIL))
(NIL B NIL (NIL C NIL D E NIL))

So it's much simplier to implement the requirements as you did the
first time.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.