[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Writing Destructive Functions
- To: info-mcl@cambridge.apple.com, york@oakland-hills.lucid.com
- Subject: Re: Writing Destructive Functions
- From: jbk@world.std.com (Jeffrey B Kane)
- Date: Tue, 29 Sep 1992 13:19:48 -0400
" You can use SETF on the various list component accessors to alter the
contents of a list.
(defun replace-first (list new-element)
(setf (car list) new-element)
list)"
The problem that I'm having is not doing a subsitution for the first
element, but destructively adding elements to the head of a list. An
example is
(defun add-to-front (theList new-element)
; do something magical)
then if you call it with
> (setf test-list '(a b c))
(A B C)
> (add-to-front test-list 'k)
(K A B C)
> test-list
(K A B C)
Unfortunately this does not seem to be possible, since we cannot truely
pass a pointer to "test-list", but only what "test-list" points to.
+-----------+
| test-list |
+-----------+
|
v
+-----------+ +-----------+ +-----------+
| | | -> | | | -> | | | -> nil
+-----------+ +-----------+ +-----------+
| | |
v v v
A B C
What we get passed to our function is a new pointer to the 1st cons cells.
+-----------+
| list |
+-----------+
|
v
+-----------+ +-----------+ +-----------+
| | | -> | | | -> | | | -> nil
+-----------+ +-----------+ +-----------+
| | |
v v v
A B C
We can change the values of this cons cell to our hearts content with
things like:
(setf (car list) 'new-element)
or
(setf list (cons new-element list))
etc, but when we return "test-list" still points to this first cons cell.
What we want is to change the cons cell that "test-list" points to, i.e.
after the funtion returns, test-list now points to:
+-----------+
| test-list |
+-----------+
|
v old 1st cons
+-----------+ +-----------+ +-----------+ +-----------+
| | | -> | | | -> | | | -> | | | -> nil
+-----------+ +-----------+ +-----------+ +-----------+
| | | |
v v v v
K A B C
So far the only answer that I have come up with is a macro:
> (defmacro replace-first (list new-element)
`(setf ,list (cons ,new-element ,list)))
REPLACE-FIRST
> (setf test-list '(a b c d))
(A B C D)
> (replace-first test-list 'k)
(K A B C D)
> test-list
(K A B C D)
but for various reasons (including all the negative ones about macros) I
wanted to do this with a real function. If I could find some way to pass
a pointer to the symbol "test-list" and not what "test-list" points to, I
would be in good shape.
Jeffrey