From: Gerald Smith
Subject: Circular List
Date: 
Message-ID: <uwGc9O#f9GA.330@nih2naac.prod2.compuserve.com>
(setf x '(foo bar) )

I want to mutate the first element of the list to obtain
the list  ((FOO BAR) BAR)

..so I execute the line below to accomplish the mutation.
(progn (setf (first x) x)  'done) ;===> DONE


Now I realize I have created a circular list, however I can
still access the data in the list for testing purposes,
if I am careful.

(equal 'bar
       (second
          (first x))) ;===> T

..which is about the same as doing this:
(equal 'bar
       (second
          (first '((foo bar) bar) ))) ;===> T


The problem is, when I try the below, it does not
return T as I expected. Does anyone know why?
(equal 'foo
       (first
          (first x))) ;===> NIL

From: Gareth McCaughan
Subject: Re: Circular List
Date: 
Message-ID: <86somba8d9.fsf@g.pet.cam.ac.uk>
Gerald Smith wrote:

> (setf x '(foo bar) )
...
> (progn (setf (first x) x)  'done) ;===> DONE
...
> The problem is, when I try the below, it does not
> return T as I expected. Does anyone know why?
> (equal 'foo
>        (first
>           (first x))) ;===> NIL

After that SETF, your `list' looks like this.

        __\,+-----+-----+
       /  / |     |     |
       \____|__,  | BAR |
            |     |     |
            +-----+-----+

So, (first x) == x
    (first (first x)) == (first x) == x

and x certainly isn't EQUAL to FOO.

-- 
Gareth McCaughan       Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk  Cambridge University, England.
From: Donald Fisk
Subject: Re: Circular List
Date: 
Message-ID: <355C78DF.8A23C24F@bt-sys.bt.co.uk>
Gerald Smith wrote:
> (setf x '(foo bar) )

> I want to mutate the first element of the list to obtain
> the list  ((FOO BAR) BAR)

> ..so I execute the line below to accomplish the mutation.
> (progn (setf (first x) x)  'done) ;===> DONE

> Now I realize I have created a circular list, however I can
> still access the data in the list for testing purposes,
> if I am careful.

> (equal 'bar
>        (second
>           (first x))) ;===> T

> ..which is about the same as doing this:
> (equal 'bar
>        (second
>           (first '((foo bar) bar) ))) ;===> T

> The problem is, when I try the below, it does not
> return T as I expected. Does anyone know why?
> (equal 'foo
>        (first
>           (first x))) ;===> NIL

Because you've overwritten foo with the list itself, which
no longer contains foo because you've overwritten it.

To do what you want to do, you need a third cons-cell, something
your setf doesn't give you.   Try

	(setf (first x) (cons (first x) (rest x)))

It helps to draw out the cons cells on paper so that you can
see what's going on.

(BTW Erik, I hope you don't mind my quoting you in my new .sig)

-- 
Le Hibou (mo bheachd fhe/in: my own opinion)
"it's just that in C++ and the like, you don't trust _anybody_,
and in CLOS you basically trust everybody.  the practical result
is that thieves and bums use C++ and nice people use CLOS."
	-- Erik Naggum
From: Steve Gonedes
Subject: Re: Circular List
Date: 
Message-ID: <6ji662$31e@bgtnsc03.worldnet.att.net>
Gerald Smith <··········@CompuServe.COM> writes:

 
< The problem is, when I try the below, it does not
< return T as I expected. Does anyone know why?
< (equal 'foo
<        (first
<           (first x))) ;===> NIL

The car of x - is x.

(eq x (first x))
(eq x (first (first x)))

also (eq 'bar (second x))
From: Gerald Smith
Subject: Re: Circular List
Date: 
Message-ID: <#n#GBoGg9GA.296@nih2naab.prod2.compuserve.com>
Thanks everyone for pointing out to me that FOO no longer
exists in the list.

I  _thought_  the original list '(foo bar) was first "captured",
temporarily stored somewhere, then _after_ that capture occured,
I thought the original foo was overwritten.

Obviously I need to study mutation in greater depth.
From: Rainer Joswig
Subject: Re: Circular List
Date: 
Message-ID: <yaw3o1jq.fsf@lise.lavielle.com>
Gerald Smith <··········@CompuServe.COM> writes:

> (setf x '(foo bar) )
> 
> I want to mutate the first element of the list to obtain
> the list  ((FOO BAR) BAR)
> 
> ..so I execute the line below to accomplish the mutation.
> (progn (setf (first x) x)  'done) ;===> DONE


How about:

USER(5): (setf (first x) (copy-list x))
(FOO BAR)
USER(6): x
((FOO BAR) BAR)

> The problem is, when I try the below, it does not
> return T as I expected. Does anyone know why?
> (equal 'foo
>        (first
>           (first x))) ;===> NIL

Because the car of the cons cell points back to the cons cell itself.
Foo is gone.

Turning on *print-circle* while experimenting might help.

Greetings,

Rainer Joswig