From: jayessay
Subject: Re: Semantics of LET
Date: 
Message-ID: <m3mzdppxws.fsf@rigel.goldenthreadtech.com>
"Pisin Bootvong" <··········@gmail.com> writes:

> Jeffery Zhang wrote:
> > I have a question regarding the semantics of let.
> > I have a data structure of the format (name () ())
> > I'm writing a function to add things to the lists internal to the
> > datastructure.
> > assuming obj is bound to an instance of this data structure, if I write
> > (let ((lst (second obj)))
> > 	(push 'something lst))
> > The list isn't updated. I store the data globally in a var named *db*,
> > and when I check *db* nothing changed.
> >
> > But if I instead use (push 'something (second obj)) then it does get updated.
> >
> > Then I thought maybe let is making a copy of (second obj) so I tried
> > (let ((lst (second obj)))
> > 	(eq lst (second obj)))
> > and also eql, which are supposed to compared by memory addresses, and
> > both returned T. So now I'm confused, if LET is not making a copy, what
> > could explain the difference between (push 'something lst) and (push
> > 'something (second obj))
> >
> > -Jeff
> 
>  (let ((lst (second obj)))
>   	(push 'something lst))
> 
> is like
> 
>  x = a[0];

This is a very misleading "simile" in the context given by the OP
because x = a[0]; uses _copy_ semantics, while (let ((1st ...))...)
does _not_ make a copy.  Which the OP knows by "experiment" from his
EQ tests.

To OP: Read the other responses (Kaz Kylheku and David Sletten's
response to the related "Question on variable binding and assignment"
are on target).


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com

From: Pisin Bootvong
Subject: Re: Semantics of LET
Date: 
Message-ID: <1147285673.277099.90330@j33g2000cwa.googlegroups.com>
jayessay wrote:
> "Pisin Bootvong" <··········@gmail.com> writes:
>
> > Jeffery Zhang wrote:
> > > I have a question regarding the semantics of let.
> > > I have a data structure of the format (name () ())
> > > I'm writing a function to add things to the lists internal to the
> > > datastructure.
> > > assuming obj is bound to an instance of this data structure, if I write
> > > (let ((lst (second obj)))
> > > 	(push 'something lst))
> > > The list isn't updated. I store the data globally in a var named *db*,
> > > and when I check *db* nothing changed.
> > >
> > > But if I instead use (push 'something (second obj)) then it does get updated.
> > >
> > > Then I thought maybe let is making a copy of (second obj) so I tried
> > > (let ((lst (second obj)))
> > > 	(eq lst (second obj)))
> > > and also eql, which are supposed to compared by memory addresses, and
> > > both returned T. So now I'm confused, if LET is not making a copy, what
> > > could explain the difference between (push 'something lst) and (push
> > > 'something (second obj))
> > >
> > > -Jeff
> >
> >  (let ((lst (second obj)))
> >   	(push 'something lst))
> >
> > is like
> >
> >  x = a[0];
>
> This is a very misleading "simile" in the context given by the OP
> because x = a[0]; uses _copy_ semantics, while (let ((1st ...))...)
> does _not_ make a copy.  Which the OP knows by "experiment" from his
> EQ tests.
>
> To OP: Read the other responses (Kaz Kylheku and David Sletten's
> response to the related "Question on variable binding and assignment"
> are on target).
>
>
> /Jon
>
> --
> 'j' - a n t h o n y at romeo/charley/november com

Ahhh,,, right. But I think I stand correct.

I should have used pointer to make the point. However, the EQ part is
really irrevelant as the problem is not really with PUSH. It is with
SETF.

Once you know that:

(push 'a x)

equals to

(setf x (cons 'a x))

You knew instantly why let, (which in this case, equals to a new
variable assignment) does not work.

push/setf works with places, and places information is lost when you
use some variable to hold the value. This point is easier to show to
anyone with traditional language background using differences between:

x = a[0]
x += 10

and

a[0] += 10


Whether EQ works or not have nothing to do with this. As EQ test
equality of pointer as much as '=' test equality of a number. And
passing of a pointer is still a *copy* of a pointer itself.
In that array example above, if I made "a" array of pointer instead of
int, which would make EQ return true, what good would it improve.

I want to show the problem using traditional language's syntax, and
since the problem is with "place". The only example of place I can
think of in tradition language is array. That's why I used array access
as example.
From: Kaz Kylheku
Subject: Re: Semantics of LET
Date: 
Message-ID: <1147291312.636638.252770@g10g2000cwb.googlegroups.com>
Pisin Bootvong wrote:
> I want to show the problem using traditional language's syntax, and
> since the problem is with "place". The only example of place I can
> think of in tradition language is array. That's why I used array access
> as example.

There are also structure members. E.g. in C,  something like
"list->next" can be an lvalue, i.e. place:

  #include <stdlib.h>

  /* (let ((x (second list)))
       (push 3 x)) */
  {
    cell *x = list->next->data;
    cell *c = malloc(sizeof *c);
    c->data = 3;
    c->next = x;
    x = c;
  }
  /* x is gone now, c is leaked memory, list remains untouched */

  /* (push 3 (second list)) */
  {
    cell *c = malloc(sizeof *c);
    c->data = 3;
    c->next = list->next->data;
    list->next->data = c;
  }
  /* data item in second node of list is modified now */