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