From: Greg Menke
Subject: Using a cons to hold a list's head and tail
Date: 
Message-ID: <m3d7d6xl5u.fsf@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)

[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

From: Colin Walters
Subject: Re: Using a cons to hold a list's head and tail
Date: 
Message-ID: <87n1cayy3e.church.of.emacs@meta.verbum.org>
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.
From: romeo bernardi
Subject: Re: Using a cons to hold a list's head and tail
Date: 
Message-ID: <5Hwd6.28519$L94.285482@twister2.tin.it>
"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.
From: romeo bernardi
Subject: Re: Using a cons to hold a list's head and tail
Date: 
Message-ID: <i4xd6.28566$L94.286963@twister2.tin.it>
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)
From: Kalle Olavi Niemitalo
Subject: Re: Using a cons to hold a list's head and tail
Date: 
Message-ID: <87hf2aoof7.fsf@PC486.y2000.kon.iki.fi>
"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?