I recall this being discussed some time ago, so I gave it a try...
[1]> (setf x '(1 2 3 4))
(1 2 3 4)
[2]> (setf y `(,x . ,(last x)))
((1 2 3 4) 4)
[3]> (nconc (cdr y) '(5))
(4 5)
[4]> x
(1 2 3 4 5)
[5]> y
((1 2 3 4 5) 4 5)
[6]> (setf (cdr y) (last y))
(5)
[7]> y
((1 2 3 4 5) 5)
- this seems to illustrate the idea, but I'm wondering what better
approaches there are- and particularly, if I'm doing anything
especially horrible.
- Also, given the above, y seems to hold everything necessary for the
list's continued existence, so x could go away. Is this correct?
Thanks,
Gregm
Greg Menke <··········@mindspring.com> writes:
> I recall this being discussed some time ago, so I gave it a try...
>
> [1]> (setf x '(1 2 3 4))
> (1 2 3 4)
>
> [2]> (setf y `(,x . ,(last x)))
> ((1 2 3 4) 4)
>
> [3]> (nconc (cdr y) '(5))
> (4 5)
>
> [4]> x
> (1 2 3 4 5)
>
> [5]> y
> ((1 2 3 4 5) 4 5)
>
> [6]> (setf (cdr y) (last y))
> (5)
>
> [7]> y
> ((1 2 3 4 5) 5)
>
>
> - this seems to illustrate the idea, but I'm wondering what better
> approaches there are- and particularly, if I'm doing anything
> especially horrible.
You are modifying a constant cons cell here, which has undefined
behavior. Use `list' instead, like: (list 1 2 3 4).
> - Also, given the above, y seems to hold everything necessary for
> the list's continued existence, so x could go away. Is this
> correct?
Yes, (car y) refers to the same place as x.
"Greg Menke" <··········@mindspring.com> ha scritto nel messaggio
···················@mindspring.com...
>
> I recall this being discussed some time ago, so I gave it a try...
>
> [1]> (setf x '(1 2 3 4))
> (1 2 3 4)
>
> [2]> (setf y `(,x . ,(last x)))
> ((1 2 3 4) 4)
>
> [3]> (nconc (cdr y) '(5))
> (4 5)
>
> [4]> x
> (1 2 3 4 5)
>
> [5]> y
> ((1 2 3 4 5) 4 5)
>
> [6]> (setf (cdr y) (last y))
> (5)
(setf (cdr y) (cddr y))
> - Also, given the above, y seems to hold everything necessary for the
> list's continued existence, so x could go away. Is this correct?
yes.
P.
On a second thought...
> [3]> (nconc (cdr y) '(5))
> (4 5)
This is not correct, if you want continue to update the structure.
Remember, quoted constants should not be modified.
Use: (list 5) instead of '(5).
> [4]> x
> (1 2 3 4 5)
>
> [5]> y
> ((1 2 3 4 5) 4 5)
>
> [6]> (setf (cdr y) (last y))
> (5)
In order to not traverse the head of the structure multiple times you should
use:
(setf (cdr y) (cddr y)) ;; In case you added 1 item.
(setf (cdr y) (last <the list you added>)) ;; Otherwise
You can also destructively append two such structures using:
(setf (cddr a) (car b))
(setf (cdr a) (cdr b))
--
(Pierpaolo Bernardi)
"romeo bernardi" <········@tin.it> writes:
> > [6]> (setf (cdr y) (last y))
> In order to not traverse the head of the structure multiple times you should
> use:
>
> (setf (cdr y) (cddr y)) ;; In case you added 1 item.
I don't see how (LAST Y) could traverse the head of the
structure, as it's hidden inside (CAR Y). Unless "the head
of the structure" means the cons cell pointed by Y, but then
(CDDR Y) traverses it too.
> You can also destructively append two such structures using:
>
> (setf (cddr a) (car b))
> (setf (cdr a) (cdr b))
If the first list is empty, then A is (NIL . NIL) and this fails
because (CDR NIL) can't be set, right? Can this case be handled
without an explicit check?