From: Pete
Subject: Re: Some Questions.
Date: 
Message-ID: <4gocif$ek2@news1.usa.pipeline.com>
On Feb 24, 1996 03:41:26 in article <Some Questions.>,
·········@red.seas.upenn.edu (Geoffrey B Milord)' wrote: 
 
 
>Can somebody please explain why 1) & 2) do not destructively alter the
input 
>list and 3) does? 
>Thanks alot!!!! 
> 
>1) 
>> (defun mypush (e l) 
>(cond ((null l) (cons e ())) 
>	(t (setf l (cons (car l) (mypush e (cdr l))))))) 
>mypush 
>> (setq li '(a b c)) 
>(a b c) 
>> (mypush 'd li) 
>(a b c d) 
>> li 
>(a b c) 
> 
>2) 
>> (defun mypush (e l) 
>(cond ((null l) (cons e ())) 
>	(t (setq l (cons (car l) (mypush e (cdr l))))))) 
>mypush 
>> (mypush 'd li) 
>(a b c d) 
>> li 
>(a b c) 
> 
>3) 
>> (defun mypush (e l) 
>	(cond ((null (cdr l)) (rplacd l (cons e ()))) 
>		(t (setq l (cons (car l) (mypush e (cdr l))))))) 
>mypush 
>> (mypush 'd li) 
>(a b c d) 
>> li 
>(a b c d) 
>>  
Because a parameter is a local variable bound (read: points to) 
the passed object, a list in this case.  Modifying parameter 
l by making it "point" to some other object does not modify 
the "pointer to" object.  So, when you code (sef l (cons whatever)) 
two things happen.  A new cons cell is constructed and the 
local variable l is bound to this newly created object. 
 
Your code mostly works as (I believe you) intended, although 
the setf's are wasted.  The outermost call returns the newly 
constructed list, but you're not capturing the result.  You can 
see evidence of this by the new list printed when the 
function returns. But the original list is unmodified. 
 
Version 3 only appears to work correcly, however, it constructs 
a new list as it recurses and returns that new list as its value. 
Because you are destructively modifying the last element of 
the list by using rplacd, and the last element is the same 
cons cell for both lists, they appear to be the same list, 
but they're not.  You can verify this by: 
 
(eq li (mypush 'd li)) => NIL 
 
Version 3 would work just the same if you omitted all the 
useless extra baggage and coded it as: 
 
 (defun mypush (e l) 
	(cond ((null (cdr l)) (rplacd l (cons e ()))) 
		(t (mypush e (cdr l))))))) 
 
(Parentheses may not balance as I'm typing this directly 
into my newsreader.) 
 
Now, from a different perspective:  Shouldn't this function 
be named my-append (actually my-nconc) or words to that 
effect? 
 
- 
Pete Grant 
Kalevi, Inc. 
Software Engineering & development