Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

Marvelous! The super-user's going to boot me! What a finely tuned response to the situation!


devel / comp.lang.lisp / setf local variable change the value of global variable

SubjectAuthor
* setf local variable change the value of global variableJinsong Zhao
+- Re: setf local variable change the value of global variableSpiros Bousbouras
+- Re: setf local variable change the value of global variableHis Kennyness
+* Re: setf local variable change the value of global variableTom Russ
|`* Re: setf local variable change the value of global variableSpiros Bousbouras
| `- Re: setf local variable change the value of global variableTom Russ
`- Re: setf local variable change the value of global variableKaz Kylheku

1
setf local variable change the value of global variable

<tp0pkj$23610$1@dont-email.me>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17305&group=comp.lang.lisp#17305

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: jszhao@yeah.net (Jinsong Zhao)
Newsgroups: comp.lang.lisp
Subject: setf local variable change the value of global variable
Date: Tue, 3 Jan 2023 16:39:47 +0800
Organization: A noiseless patient Spider
Lines: 19
Message-ID: <tp0pkj$23610$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 3 Jan 2023 08:39:47 -0000 (UTC)
Injection-Info: reader01.eternal-september.org; posting-host="dc0c0cdb32c4f78a49062d2c2d198ade";
logging-data="2201632"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/skKYPHtVSwxHgo2GesBbr"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.6.1
Cancel-Lock: sha1:nQwCeNB6I6neBDivdiCathL7mkQ=
Content-Language: en-US
 by: Jinsong Zhao - Tue, 3 Jan 2023 08:39 UTC

Hi there,

I am very confused by the following code:

* (setf *l* '(1 2 3 4))
(1 2 3 4)
* (let ((a *l*))
(setf (car a) '(0 1)))
(0 1)
* *l*
((0 1) 2 3 4)

If I change (setf (car a) ...) to (setf a ...), *l* will not be changed.
I don't know why the value of *l* is changed.

I will appreciate any hint to reference reading.

Best,
Jinsong

Re: setf local variable change the value of global variable

<B9QytV61tW1ziYiAr@bongo-ra.co>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17306&group=comp.lang.lisp#17306

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: spibou@gmail.com (Spiros Bousbouras)
Newsgroups: comp.lang.lisp
Subject: Re: setf local variable change the value of global variable
Date: Tue, 3 Jan 2023 09:13:33 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 46
Message-ID: <B9QytV61tW1ziYiAr@bongo-ra.co>
References: <tp0pkj$23610$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 3 Jan 2023 09:13:33 -0000 (UTC)
Injection-Info: reader01.eternal-september.org; posting-host="817d65f1a233b85b66820c584140ca69";
logging-data="2209857"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19Ce3DRgiFzsDANwNI8tXQq"
Cancel-Lock: sha1:X9kAEvbOJzlrz7kIEU00OfqbSvM=
In-Reply-To: <tp0pkj$23610$1@dont-email.me>
X-Server-Commands: nowebcancel
X-Organisation: Weyland-Yutani
 by: Spiros Bousbouras - Tue, 3 Jan 2023 09:13 UTC

On Tue, 3 Jan 2023 16:39:47 +0800
Jinsong Zhao <jszhao@yeah.net> wrote:
> Hi there,
>
> I am very confused by the following code:
>
> * (setf *l* '(1 2 3 4))
> (1 2 3 4)
> * (let ((a *l*))
> (setf (car a) '(0 1)))
> (0 1)
> * *l*
> ((0 1) 2 3 4)
>
> If I change (setf (car a) ...) to (setf a ...), *l* will not be changed.
> I don't know why the value of *l* is changed.

First , you are modifying a quoted object and that's undefined behaviour.
This actually has come up recently a few times in the group. So lets say
that you had instead

(setf *l* (list 1 2 3 4))
(let ((a *l*))
(setf (car a) '(0 1)))

The first form creates somewhere in memory a list with the elements 1 2 3 4
and has *l* point to that list. When you do (let ((a *l*)) ...) then within
the scope of let , a also points to the same place in memory. Then you do
(setf (car a) '(0 1)) which says "Change the first element of the list that
a points to to '(0 1) ". Since *l* also points to the same place in memory ,
when you print the value of *l* [which automatically dereferences *l* and shows
you the object that *l* points to rather than the memory address *l* holds]
, you see the changed list. If you were to do instead

(let ((a *l*))
(setf a '(0 1)))

then the Common Lisp system will create a new list with the elements 0 1
and the setf will have a point to that list. So the value of the list
that *l* points to does not get affected.

--
The gore was over the top with several zombies snacking on poor Mrs.
Menard (Olga Karlatos). At least they waited until she showered and was
nice and clean before they chowed down.
www.imdb.com/review/rw1720388/

Re: setf local variable change the value of global variable

<e89e05ea-e110-4194-8c09-7482a12056aan@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17307&group=comp.lang.lisp#17307

  copy link   Newsgroups: comp.lang.lisp
X-Received: by 2002:a05:6214:186d:b0:4c7:3b70:82f with SMTP id eh13-20020a056214186d00b004c73b70082fmr2060795qvb.25.1672753415858;
Tue, 03 Jan 2023 05:43:35 -0800 (PST)
X-Received: by 2002:a05:6830:94:b0:671:cacb:681a with SMTP id
a20-20020a056830009400b00671cacb681amr2398576oto.311.1672753415475; Tue, 03
Jan 2023 05:43:35 -0800 (PST)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.lisp
Date: Tue, 3 Jan 2023 05:43:35 -0800 (PST)
In-Reply-To: <tp0pkj$23610$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=69.126.224.120; posting-account=tRMeSwoAAAD8BcJTybK3VX4CBYcEA0ts
NNTP-Posting-Host: 69.126.224.120
References: <tp0pkj$23610$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <e89e05ea-e110-4194-8c09-7482a12056aan@googlegroups.com>
Subject: Re: setf local variable change the value of global variable
From: kentilton@gmail.com (His Kennyness)
Injection-Date: Tue, 03 Jan 2023 13:43:35 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: His Kennyness - Tue, 3 Jan 2023 13:43 UTC

On Tuesday, January 3, 2023 at 3:39:53 AM UTC-5, Jinsong Zhao wrote:
> Hi there,
>
> I am very confused by the following code:
>
> * (setf *l* '(1 2 3 4))
> (1 2 3 4)
> * (let ((a *l*))
> (setf (car a) '(0 1)))
> (0 1)
> * *l*
> ((0 1) 2 3 4)
>
> If I change (setf (car a) ...) to (setf a ...), *l* will not be changed.
> I don't know why the value of *l* is changed.
>
> I will appreciate any hint to reference reading.
>
> Best,
> Jinsong

Congratulations, you have reached a classic step in mastering Lisp. This addresses the issue: https://gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html

As the author says, there is no such thing as a list; the `list` function produces a linked list chain of `cons` cells, structures with two famous parts, the `car` and the `cdr`.

So *i* does not really hold the whole list, it just holds a pointer to the first cons cell.

Likewise, `(let [a *i*]....)` does not make `a` into a copy of the "list" pointed to by *i*, it just makes `a` into a copy of the same _pointer_ (to the same cons cell as *i*).

That ^^ explains why changing `(car a)` also changes `(car *i*)`

> > If I change (setf (car a) ...) to (setf a ...), *l* will not be changed..

You did not show all your code there, so it is hard to answer except to say `(setf a ...)` certainly changes `a` from being the same as *i* to being something different, and thus leaving *i* alone. I hesitate here because we are seeing that, in Lisp, we can indeed alter existing cons cells, so if the ellipsis in `(set a ...)` included a mutating action on the chain of cons cells pointer to by *i*, we could still end up "changing" *i*.

tl;dr: resist the syntactic sugar that is the "list" concept, and remember to think about chains of cons cells, each an object with identity, and each with two parts, a car and a cdr.

Re: setf local variable change the value of global variable

<63b90ce3-99e4-4357-9865-3018d252111dn@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17308&group=comp.lang.lisp#17308

  copy link   Newsgroups: comp.lang.lisp
X-Received: by 2002:a0c:fecb:0:b0:531:7c3c:729 with SMTP id z11-20020a0cfecb000000b005317c3c0729mr1396456qvs.86.1672782723894;
Tue, 03 Jan 2023 13:52:03 -0800 (PST)
X-Received: by 2002:a05:6808:a09:b0:35e:8b6f:f6e6 with SMTP id
n9-20020a0568080a0900b0035e8b6ff6e6mr3088827oij.248.1672782723188; Tue, 03
Jan 2023 13:52:03 -0800 (PST)
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.lisp
Date: Tue, 3 Jan 2023 13:52:03 -0800 (PST)
In-Reply-To: <tp0pkj$23610$1@dont-email.me>
Injection-Info: google-groups.googlegroups.com; posting-host=2603:8000:7603:1703:d0fe:f483:42fc:ff79;
posting-account=05zmAwoAAAAJZM-3jv1hCWLHGZQceqwA
NNTP-Posting-Host: 2603:8000:7603:1703:d0fe:f483:42fc:ff79
References: <tp0pkj$23610$1@dont-email.me>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <63b90ce3-99e4-4357-9865-3018d252111dn@googlegroups.com>
Subject: Re: setf local variable change the value of global variable
From: taruss@google.com (Tom Russ)
Injection-Date: Tue, 03 Jan 2023 21:52:03 +0000
Content-Type: text/plain; charset="UTF-8"
 by: Tom Russ - Tue, 3 Jan 2023 21:52 UTC

On Tuesday, January 3, 2023 at 12:39:53 AM UTC-8, Jinsong Zhao wrote:
> Hi there,
>
> I am very confused by the following code:
>
> * (setf *l* '(1 2 3 4))
> (1 2 3 4)
> * (let ((a *l*))
> (setf (car a) '(0 1)))
> (0 1)
> * *l*
> ((0 1) 2 3 4)
>
> If I change (setf (car a) ...) to (setf a ...), *l* will not be changed.
> I don't know why the value of *l* is changed.

Other posters have explained that you are modifying the underlying list structure.
That is one of the traps of allowing SETF to modify parts of lists like (CAR A).*

Assuming that you don't want to have this effect, there are a couple of alternatives:

1. Make a copy of the list. Bindings and assignment of lists just involve pointers,
so if you want a copy you need to be explicit. This will let you modify a copy of the
list structure.

.. (let ((a (copy-list *I*)))
.. (setf (car a) '(0 1)))

Now COPY-LIST will only copy the top-level "backbone" of the list. If you want to
have a complete copy that doesn't share any cons cells you need to use COPY-TREE
instead.

2. Don't use destructive list operations. For your case that would look like

.. (let ((a *I*))
.. (setf a (cons '(0 1) (cdr a))))

This builds new list structure (via CONS) rather than modifying the existing list structure.
It is important to remember, though, that now A and *I* share some list structure, namely
the CDR of the original list or (2 3 4).
You can test this using the object equality predicate EQ: **
(EQ (CAR A) (CAR *I*)) ==> NIL
(EQ (CDR A) (CDR *I*)) ==> T
(EQ (CDDR A) (CDDR *I*)) ==> NIL

* Before lisp had that support, you would have had to call a more cumbersome function
RPLACA (short for "replace car") which was a little more likely to warn you that you were
mutating the list structure rather than just assigning variables.

** But you have to be a bit careful about EQ, as it can be tricky. For example
(EQ 3 3) may be either T or NIL depending on details of the implementation.
http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm

Re: setf local variable change the value of global variable

<Oln0scahcTQYfjuvG@bongo-ra.co>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17309&group=comp.lang.lisp#17309

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: spibou@gmail.com (Spiros Bousbouras)
Newsgroups: comp.lang.lisp
Subject: Re: setf local variable change the value of global variable
Date: Wed, 4 Jan 2023 04:10:26 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 18
Message-ID: <Oln0scahcTQYfjuvG@bongo-ra.co>
References: <tp0pkj$23610$1@dont-email.me> <63b90ce3-99e4-4357-9865-3018d252111dn@googlegroups.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
Injection-Date: Wed, 4 Jan 2023 04:10:26 -0000 (UTC)
Injection-Info: reader01.eternal-september.org; posting-host="9668084d938c0abfb49d05e745aec493";
logging-data="2515324"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX187IlN+osjM6E7FsxwiBccq"
Cancel-Lock: sha1:IwV2I5JT8oomiZboajoEljWgl0A=
In-Reply-To: <63b90ce3-99e4-4357-9865-3018d252111dn@googlegroups.com>
X-Organisation: Weyland-Yutani
 by: Spiros Bousbouras - Wed, 4 Jan 2023 04:10 UTC

On Tue, 3 Jan 2023 13:52:03 -0800 (PST)
Tom Russ <taruss@google.com> wrote:
> 2. Don't use destructive list operations. For your case that would look like
>
> . (let ((a *I*))
> . (setf a (cons '(0 1) (cdr a))))
>
> This builds new list structure (via CONS) rather than modifying the existing
> list structure.
> It is important to remember, though, that now A and *I* share some list
> structure, namely
> the CDR of the original list or (2 3 4).
> You can test this using the object equality predicate EQ: **
> (EQ (CAR A) (CAR *I*)) ==> NIL
> (EQ (CDR A) (CDR *I*)) ==> T
> (EQ (CDDR A) (CDDR *I*)) ==> NIL

3rd line should return T .

Re: setf local variable change the value of global variable

<634f92b1-7d25-40f3-91dd-34a24b625bbfn@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17310&group=comp.lang.lisp#17310

  copy link   Newsgroups: comp.lang.lisp
X-Received: by 2002:a37:b2c7:0:b0:6ff:8c91:5609 with SMTP id b190-20020a37b2c7000000b006ff8c915609mr1703177qkf.132.1672944430958;
Thu, 05 Jan 2023 10:47:10 -0800 (PST)
X-Received: by 2002:a05:6808:a09:b0:35e:8b6f:f6e6 with SMTP id
n9-20020a0568080a0900b0035e8b6ff6e6mr3611550oij.248.1672944430448; Thu, 05
Jan 2023 10:47:10 -0800 (PST)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.lisp
Date: Thu, 5 Jan 2023 10:47:10 -0800 (PST)
In-Reply-To: <Oln0scahcTQYfjuvG@bongo-ra.co>
Injection-Info: google-groups.googlegroups.com; posting-host=2603:8000:7603:1703:d0fe:f483:42fc:ff79;
posting-account=05zmAwoAAAAJZM-3jv1hCWLHGZQceqwA
NNTP-Posting-Host: 2603:8000:7603:1703:d0fe:f483:42fc:ff79
References: <tp0pkj$23610$1@dont-email.me> <63b90ce3-99e4-4357-9865-3018d252111dn@googlegroups.com>
<Oln0scahcTQYfjuvG@bongo-ra.co>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <634f92b1-7d25-40f3-91dd-34a24b625bbfn@googlegroups.com>
Subject: Re: setf local variable change the value of global variable
From: taruss@google.com (Tom Russ)
Injection-Date: Thu, 05 Jan 2023 18:47:10 +0000
Content-Type: text/plain; charset="UTF-8"
X-Received-Bytes: 2033
 by: Tom Russ - Thu, 5 Jan 2023 18:47 UTC

On Tuesday, January 3, 2023 at 8:10:32 PM UTC-8, Spiros Bousbouras wrote:
> On Tue, 3 Jan 2023 13:52:03 -0800 (PST)
> Tom Russ <tar...@google.com> wrote:
> > 2. Don't use destructive list operations. For your case that would look like
> >
> > . (let ((a *I*))
> > . (setf a (cons '(0 1) (cdr a))))
> >
> > This builds new list structure (via CONS) rather than modifying the existing
> > list structure.
> > It is important to remember, though, that now A and *I* share some list
> > structure, namely
> > the CDR of the original list or (2 3 4).
> > You can test this using the object equality predicate EQ: **
> > (EQ (CAR A) (CAR *I*)) ==> NIL
> > (EQ (CDR A) (CDR *I*)) ==> T
> > (EQ (CDDR A) (CDDR *I*)) ==> NIL
> 3rd line should return T .
Correct. Thanks.

Re: setf local variable change the value of global variable

<20230106092401.291@kylheku.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17311&group=comp.lang.lisp#17311

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: 864-117-4973@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.lisp
Subject: Re: setf local variable change the value of global variable
Date: Fri, 6 Jan 2023 17:38:25 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 63
Message-ID: <20230106092401.291@kylheku.com>
References: <tp0pkj$23610$1@dont-email.me>
Injection-Date: Fri, 6 Jan 2023 17:38:25 -0000 (UTC)
Injection-Info: reader01.eternal-september.org; posting-host="508fcadb86f9c0285c3cda746543545a";
logging-data="3392985"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19k4YDw5+/1gH71V/mjZWjEfg1eqepb7jo="
User-Agent: slrn/1.0.3 (Linux)
Cancel-Lock: sha1:E9WDLsoFRfFqyZyMrGf4yEEj37w=
 by: Kaz Kylheku - Fri, 6 Jan 2023 17:38 UTC

On 2023-01-03, Jinsong Zhao <jszhao@yeah.net> wrote:
> Hi there,
>
> I am very confused by the following code:
>
> * (setf *l* '(1 2 3 4))
> (1 2 3 4)
> * (let ((a *l*))
> (setf (car a) '(0 1)))
> (0 1)
> * *l*
> ((0 1) 2 3 4)
>
> If I change (setf (car a) ...) to (setf a ...), *l* will not be changed.
> I don't know why the value of *l* is changed.

Lists (other than the empty list nil) are made of binary pair objects
called conses. A list value is a pointer/reference to a cons whose car
holds the first item, and whose cdr holds the rest of the list:
another cons, or perhaps nil if there are no more items.

When you bind the variable a to *l*, a points to the same cons cell as
*l*. The list object has not been duplicated, only the pointer.

To understand computer programming to the fullest extent, you have to
become very familiar with pointers, because they are everywhere. Not
only machine address pointers, but pointer-like entities: symbolic links
and hard links in file systems, WWW hyperlinks, parent pointers in git
commits, object IDs in databases, ...

A key question in computer science (and mathematics) is what makes two
things X and Y "same", and there can be more than one valid answer.

E.g. two character strings X and Y can be "same" if they have the same
characters, like "abc" and "abc". But it's possible that X and Y,
if they are the same, are actually the same object; i.e. X and Y
are just different names referring to the same entity.

Under the Law of Identity (https://en.wikipedia.org/wiki/Law_of_identity)
a thing X should always be the same as itself. The people who designed
IEEE 754 floating-point disagreed: a NaN value is not equal to itself,
even if it's the same one (same bit pattern).

On the other hand you can have a sameness notion such that, say, "John"
and "JOHN" are considered the same. Those specific two wouldn't
be the same object, but this kind of case-insensitive sameness
is compatible with the Law of Identity; "John" is still "John".

When a variable in some programming language is copied from another, we
expect the value of the copy and original to be the same (with odd
exceptions like floating-point NaN values). That sameness could be due
to the values being in fact references to the same entity; you always
have to ask that question and suspect it, almost no matter what
language you are working in.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor