From: Donovan Parks
Subject: Scope of Variables between Functions
Date: 
Message-ID: <af4vn3$3eus$1@casey.uvic.ca>
Hello,

I am having some trouble understanding how lisp handles the scope of
variables.  I thought that any symbol contained in the parameter list of a
procedure was local to that procedure and that parameters were passed by
value.  Surely, this is the case (as I'm taking it straight from my course
notes), but I am lost at how the following code operates:

(defun move-gen (board)
    (let ((children '()))
      (dotimes (i 3)
           (setq children (cons (set-position i board) children)))
      children))

(defun set-position (position board)
 (setf (nth position board) 'X)
 board)


Now, consider these commands;

Command: (movegen '(- - -))
Result: ((X X X) (X X X) (X X X))

I am expecting to get a result of ((X - -) (- X -) (- - X)).

Now, when I trace these two functions I get:

1. Trace: (MOVE-GEN '(- - -))
2. Trace: (SET-POSITION '0 '(- - -))
3. Trace: SET-POSITION ==> (X - -)
4. Trace: (SET-POSITION '1 '(X - -))  [what is going on here]
...

Why in step 4 is set-position being called with (X - -).  The value of
'board' in move-gen appears to have been modified.  Can someone try and
explain why this is occuring.  Additionally, even if 'board' in move-gen is
being modified with each call to set-position I still fail to understand the
final result of ((X X X) (X X X) (X X X)).  Obviously, I have a
misunderstanding on how lisp executes code.  Thanks for any help.

How would I get the results I require, namely ((X - -) (- X -) (- - X)).
Perhaps the contrast between the two would clarify things for me.

Regards,
Donovan Parks

From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <874rftkig1.fsf@darkstar.cartan>
"Donovan Parks" <······@uvic.ca> writes:

> I am having some trouble understanding how lisp handles the scope of
> variables.  I thought that any symbol contained in the parameter list of a
> procedure was local to that procedure and that parameters were passed by
> value.  Surely, this is the case (as I'm taking it straight from my course
> notes), but I am lost at how the following code operates:
> 
> (defun move-gen (board)
>     (let ((children '()))
>       (dotimes (i 3)
>            (setq children (cons (set-position i board) children)))

Lookup PUSH.

>       children))
> 
> (defun set-position (position board)
>  (setf (nth position board) 'X)
>  board)
> 
> 
> Now, consider these commands;
> 
> Command: (movegen '(- - -))
> Result: ((X X X) (X X X) (X X X))
> 
> I am expecting to get a result of ((X - -) (- X -) (- - X)).

Do get this result you should not only NREVERSE CHILDREN before
returning it, if order matters, but also pass a fresh copy of
BOARD before calling SET-POSITION.

> Now, when I trace these two functions I get:
> 
> 1. Trace: (MOVE-GEN '(- - -))
> 2. Trace: (SET-POSITION '0 '(- - -))
> 3. Trace: SET-POSITION ==> (X - -)
> 4. Trace: (SET-POSITION '1 '(X - -))  [what is going on here]
> ...
> 
> Why in step 4 is set-position being called with (X - -).  The value of
> 'board' in move-gen appears to have been modified.

Yes, that's what SET-POSITION does, or, more precisely, that's
what (setf (nth position board) 'x) does.  Upon entry to
SET-POSITION, the local variable BOARD gets bound to the value of
the second parameter when you call it.  As you call it like
(set-position i board), the BOARD variable in SET-POSITION is
bound the the _same_ list as the BOARD variable in MOVE-GEN.  So,
if you modify /this list/ inside of SET-POSITION, the BOARD
variable in MOVE-GEN will, still being bound to this very same
list, produce this modified list when evaluated again, as you
can't change its binding from inside SET-POSITION (if it's not a
SPECIAL variable).

Note that by testing with (MOVE-GEN '(- - -)) you are being a bad
boy because SET-POSITION will modify the list literal '(- - -).
But it is ok to call MOVE-GEN this way if you copy it (by calling
COPY-LIST) every time when calling SET-POSITION, as you'll
probably want to do, anyway.

Hope this helps, somehow.

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Rainer Joswig
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <joswig-5DC35E.22005523062002@news.fu-berlin.de>
In article <·············@casey.uvic.ca>,
 "Donovan Parks" <······@uvic.ca> wrote:

> Hello,
> 
> I am having some trouble understanding how lisp handles the scope of
> variables.  I thought that any symbol contained in the parameter list of a
> procedure was local to that procedure and that parameters were passed by
> value.  Surely, this is the case (as I'm taking it straight from my course
> notes), but I am lost at how the following code operates:
> 
> (defun move-gen (board)
>     (let ((children '()))
>       (dotimes (i 3)
>            (setq children (cons (set-position i board) children)))
>       children))
> 
> (defun set-position (position board)
>  (setf (nth position board) 'X)
>  board)
> 
> 
> Now, consider these commands;
> 
> Command: (movegen '(- - -))
> Result: ((X X X) (X X X) (X X X))
> 
> I am expecting to get a result of ((X - -) (- X -) (- - X)).
> 
> Now, when I trace these two functions I get:
> 
> 1. Trace: (MOVE-GEN '(- - -))
> 2. Trace: (SET-POSITION '0 '(- - -))
> 3. Trace: SET-POSITION ==> (X - -)
> 4. Trace: (SET-POSITION '1 '(X - -))  [what is going on here]
> ...
> 
> Why in step 4 is set-position being called with (X - -).  The value of
> 'board' in move-gen appears to have been modified.  Can someone try and
> explain why this is occuring.

You are modifying the same list in every iteration.

with *print-circle* set to T this looks like:

(#1=(X X X) #1# #1#)

Just copy the list each time before you modify it:

(defun set-position (position board)
  (let ((board (copy-list board)))
    (setf (nth position board) 'X)
    board))
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <af5ki1$esd$1@news6.svr.pol.co.uk>
Uzytkownik "Donovan Parks" <······@uvic.ca> napisal w wiadomosci
··················@casey.uvic.ca...
> Hello,
>
> I am having some trouble understanding how lisp handles the scope of
> variables.  I thought that any symbol contained in the parameter list of a
> procedure was local to that procedure and that parameters were passed by
> value.

    If you're talking about ANSI Common Lisp, the latter of your assumptions
is wrong. Google for "Common Lisp Hyperspec" for a HTML version of the ANSI
standard (frontmatter differs from the standard). The way it works is that
in the scope of the function, the symbols' value-binding is bound to the
actual parameters passed in the function call. To give the example:

(defun foo (bar) (list bar))

(foo 'moo) => (moo)

bar is effectively a reference to the symbol moo. If you call (foo '(moo
min)) you get a cons structure

('(moo min) . nil)

Where the first bit in the cons (before the dot, I forget the common name)
is a pointer to the list. Hence, if you modify the (inner) list in any
context, then printing the outer list will show the changes to the inner
list.
    As I read this post over, it seems to make even less sense than when I
wrote it. I hope this helps anyway.
From: Martin Simmons
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3d198c64$0$233$ed9e5944@reading.news.pipex.net>
"Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> wrote in message
·················@news6.svr.pol.co.uk...
>
> Uzytkownik "Donovan Parks" <······@uvic.ca> napisal w wiadomosci
> ··················@casey.uvic.ca...
> > Hello,
> >
> > I am having some trouble understanding how lisp handles the scope of
> > variables.  I thought that any symbol contained in the parameter list of a
> > procedure was local to that procedure and that parameters were passed by
> > value.
>
>     If you're talking about ANSI Common Lisp, the latter of your assumptions
> is wrong.

Actually, he *is* right -- the value is a pointer to the first cons in the list.
--
Martin Simmons, Xanalys Software Tools
······@xanalys.com
rot13 to reply
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <yztbvg85yl6p.fsf@werewolf.i-did-not-set--mail-host-address--so-shoot-me>
"Martin Simmons" <······@xanalys.com> writes:

> "Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> wrote in message
> ·················@news6.svr.pol.co.uk...
> >
> > Uzytkownik "Donovan Parks" <······@uvic.ca> napisal w wiadomosci
> > ··················@casey.uvic.ca...
> > > Hello,
> > >
> > > I am having some trouble understanding how lisp handles the scope of
> > > variables.  I thought that any symbol contained in the parameter list 
> > > of a
> > > procedure was local to that procedure and that parameters were passed by
> > > value.
> >
> >     If you're talking about ANSI Common Lisp, the latter of your 
> >assumptions
> > is wrong.
> 
> Actually, he *is* right -- the value is a pointer to the first cons in the 
> list.

    No, that's why he is wrong, and I'm right: Symbols are like pointers. 
Pass-by-value would be that if the value were changed locally, the change
would not be seen outsdide the function. There is nothing like that in CL
(And don't say rebinding the symbol). I suggest that you reread what he 
said, as I assume that you know CL considerably better than I do.

> --
> Martin Simmons, Xanalys Software Tools
> ······@xanalys.com
> rot13 to reply

-- 
You're trapped in my mental fog box! I'm gonna tear you up with this shit!!!
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <lkk7olhp4t.fsf@pc022.bln.elmeg.de>
Marcin Tustin <·····@witch.goat> writes:

> "Martin Simmons" <······@xanalys.com> writes:
> 
> > "Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> wrote in message
> > ·················@news6.svr.pol.co.uk...
> > >
> > > Uzytkownik "Donovan Parks" <······@uvic.ca> napisal w wiadomosci
> > > ··················@casey.uvic.ca...
> > > > Hello,
> > > >
> > > > I am having some trouble understanding how lisp handles the scope of
> > > > variables.  I thought that any symbol contained in the parameter list 
> > > > of a
> > > > procedure was local to that procedure and that parameters were passed by
> > > > value.
> > >
> > >     If you're talking about ANSI Common Lisp, the latter of your 
> > >assumptions
> > > is wrong.
> > 
> > Actually, he *is* right -- the value is a pointer to the first cons in the 
> > list.
> 
>     No, that's why he is wrong, and I'm right: Symbols are like
>     pointers. 

Now that's news to me ;-)

> Pass-by-value would be that if the value were changed locally, the change
> would not be seen outsdide the function. There is nothing like that in CL
> (And don't say rebinding the symbol). I suggest that you reread what he 
> said, as I assume that you know CL considerably better than I do.

It seems you haven't really understood what call-by-value actually
means.

Consider

CL-USER 1 > (defun changer (cell)
              (setf (car cell) 'bingo))
CHANGER

CL-USER 2 > (defun check ()
              (let* ((mycell (cons 'foo 'bar))
                     (memory mycell))
                (changer mycell)
                (eq memory mycell)))
CHECK

CL-USER 3 > (check)
T

See?  CHANGER changed the cons cell it was given all right, but the
only relevant fact is that MYCELL is still bound to the exact same
object as it was before the call to CHANGER.  This is because Lisp is
call-by-value.

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Andreas Hinze
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3D1A1016.B4E50E62@smi.de>
Nils Goesche wrote:
> 
> Consider
> 
> CL-USER 1 > (defun changer (cell)
>               (setf (car cell) 'bingo))
> CHANGER
> 
> CL-USER 2 > (defun check ()
>               (let* ((mycell (cons 'foo 'bar))
>                      (memory mycell))
>                 (changer mycell)
>                 (eq memory mycell)))
> CHECK
> 
> CL-USER 3 > (check)
> T
> 
> See?  CHANGER changed the cons cell it was given all right, but the
> only relevant fact is that MYCELL is still bound to the exact same
> object as it was before the call to CHANGER.  This is because Lisp is
> call-by-value.
> 
Still trying to get it i tried your example and it works as you say. BUT
modifying check like this:

(defun check ()
  (let* ((mycell (cons 'foo 'bar))
         (memory mycell))
    (changer mycell)
    (eq memory mycell)
    (format t "Memory: ~A Mycell: ~A~%" memory mycell)))  ; This line is new

yields:

CL-USER 3 > (check)
Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
NIL

So your check program works because both cells hold the same NEW value.
(That at least shows how hard it is to write good test code ;-)

IMHO cell IS passed to changer by value. But the cons cell has only two
pointer (car/cdr) that points to the values FOO & BAR. And these one are
not copied when changer is called. So the situation is similar to C where
a pointer is passed to a function by value. But changing *p is still visible
in the calling environment.
But, however, that's just my imagination and you should take it with care
(remember, i'm a newbie ;-)

Best
AHz
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <lkfzz9hlzz.fsf@pc022.bln.elmeg.de>
Andreas Hinze <···@smi.de> writes:

> Nils Goesche wrote:
> > 
> > Consider
> > 
> > CL-USER 1 > (defun changer (cell)
> >               (setf (car cell) 'bingo))
> > CHANGER
> > 
> > CL-USER 2 > (defun check ()
> >               (let* ((mycell (cons 'foo 'bar))
> >                      (memory mycell))
> >                 (changer mycell)
> >                 (eq memory mycell)))
> > CHECK
> > 
> > CL-USER 3 > (check)
> > T
> > 
> > See?  CHANGER changed the cons cell it was given all right, but the
> > only relevant fact is that MYCELL is still bound to the exact same
> > object as it was before the call to CHANGER.  This is because Lisp is
> > call-by-value.
> > 
> Still trying to get it i tried your example and it works as you say. BUT
> modifying check like this:
> 
> (defun check ()
>   (let* ((mycell (cons 'foo 'bar))
>          (memory mycell))
>     (changer mycell)
>     (eq memory mycell)
>     (format t "Memory: ~A Mycell: ~A~%" memory mycell)))  ; This line is new
> 
> yields:

As (EQ MEMORY MYCELL) is true, there is no need to print both, actually.

> CL-USER 3 > (check)
> Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
> NIL
> 
> So your check program works because both cells hold the same NEW value.
> (That at least shows how hard it is to write good test code ;-)

Well, both contain the same value as before the call to CHANGER.  This
is what EQ tells you, and you should believe it :-) That the CAR of
the cons cell changed has nothing to do with it; (the identity of) the
cons cell is the value.

> IMHO cell IS passed to changer by value.

Actually, this is not a matter of opinion.  Yes, it is passed by
value, as everything is in a function call in Lisp, always and without
exceptions.

> But the cons cell has only two pointer (car/cdr) that points to the
> values FOO & BAR.

Personally, I don't think using the word ``pointer'' is a good idea
when talking about Lisp.  This notion is not needed, the HyperSpec
doesn't mention it, it only complicates matters.  Our cons cell
contains the symbols FOO and BAR in its CAR and CDR, resp.

> And these one are not copied when changer is called.

Nothing is copied at all.

> So the situation is similar to C where a pointer is passed to a
> function by value. But changing *p is still visible in the calling
> environment.

I don't think comparing with C helps very much.  Actually the
situation is very simple.  We are talking about the semantics of
function calling, so let's closely look what happens when CHANGER is
called.

First, MYCELL is bound to our fresh cons cell returned from the call
to CONS.  Let's call this cell <X>.

MYCELL is then evaluated, yielding <X>, and MEMORY is bound to <X>,
too.  No pointer business whatsoever, simply say both are bound to
<X>.  Now, we want to evaluate (CHANGER MYCELL).  This is a function
call, so the arguments are evaluated in order.  MYCELL is evaluated
again, yielding <X>.  Now, we are at the beginning of the function
CHANGER.  The local variable CELL is bound to <X>.

The process I just described is exactly what ``call-by-value'' means,
so this discussion is over.

What happens next is that the code in CHANGER changes the
CAR of <X>.  Note that nothing at all has changed about the identity
of <X>, <X> is still the very same cell it has always been :-)

CHANGER returns, we are back in CHECK.  Now, _absolutely nothing_
changed about the binding of MYCELL or MEMORY.  (And even if they
/had/ changed, it would /still/ be call-by-value, because this has
nothing to do with the notion ``call-by-value'').  Both MYCELL and
MEMORY still contain the same object <X> they always did, and that's
what EQ tells us, too.

It might be enlightening to have a look at a slighty different
example.

CL-USER 7 > (defun changer2 (number)
              (incf number))
CHANGER2

CL-USER 8 > (defun check2 ()
              (let* ((x 42)
                     (y x))
                (changer x)
                (eql x y)))
CHECK2

CL-USER 9 > (check2)
T

What happens at the point CHANGER2 is called is the _exact same thing_
I described for CHECK and CHANGER, there is no difference whatsoever
in the calling semantics (call-by-value).

Later in CHANGER2, what (INCF NUMBER) does is:

It evaluates NUMBER, adds 1 and changes the binding of NUMBER to this
new number.  That's just what INCF _does_.  That's how it is defined,
and you should check this with EQL until you've got it :-)  It is this
point, I think, that causes so much confusion among beginners.

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <lkbs9xhl6j.fsf@pc022.bln.elmeg.de>
Nils Goesche <······@cartan.de> writes:

> CL-USER 7 > (defun changer2 (number)
>               (incf number))
> CHANGER2
> 
> CL-USER 8 > (defun check2 ()
>               (let* ((x 42)
>                      (y x))
>                 (changer x)

Call CHANGER2 here, of course:

                  (changer2 x)

>                 (eql x y)))
> CHECK2
> 
> CL-USER 9 > (check2)
> T

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Andreas Hinze
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3D1A1FD7.DC593A17@smi.de>
Nils Goesche wrote:
> 
> > CL-USER 3 > (check)
> > Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
> > NIL
> >
> > So your check program works because both cells hold the same NEW value.
> > (That at least shows how hard it is to write good test code ;-)
> 
> Well, both contain the same value as before the call to CHANGER.  This
> is what EQ tells you, and you should believe it :-) 

Read it again. After calling CHANGER both cells have changed !!! You
initialized it with (FOO . BAR) and got (BINGO . BAR) after calling
CHANGER.
I checked it with LW 4.2 on Windows.

BTW: I stoped believing anything some years ago ;-)

Best
AHz
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <lk7kklhjv0.fsf@pc022.bln.elmeg.de>
Andreas Hinze <···@smi.de> writes:

> Nils Goesche wrote:
> > 
> > > CL-USER 3 > (check)
> > > Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
> > > NIL
> > >
> > > So your check program works because both cells hold the same NEW value.
> > > (That at least shows how hard it is to write good test code ;-)
> > 
> > Well, both contain the same value as before the call to CHANGER.  This
> > is what EQ tells you, and you should believe it :-) 
> 
> Read it again. After calling CHANGER both cells have changed !!! You
> initialized it with (FOO . BAR) and got (BINGO . BAR) after calling
> CHANGER.
> I checked it with LW 4.2 on Windows.
> 
> BTW: I stoped believing anything some years ago ;-)

Well, you should believe at least EQ ;-)  Of course the cells have
changed.  Nobody ever argued that.  But the cell is still the same
object <X>.  It is this object, <X>, which is the ``value'' we are
talking about.  The CAR and CDR of <X> are totally irrelevant here.

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Andy
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3D1A2D4F.393279D@snafu.de>
Nils Goesche wrote:
> 
> Well, you should believe at least EQ ;-)  Of course the cells have
> changed.  Nobody ever argued that.  But the cell is still the same
> object <X>.  It is this object, <X>, which is the ``value'' we are
> talking about.  The CAR and CDR of <X> are totally irrelevant here.
> 
Then my understanding of call-by-value is wrong. I assumed that it means
i can give ANYTHING to a function and it is TOTALLY unchanged after the call.
And not only the "Rootlevel". But then i wonder what's the sense of 
call-by-value is at all.

Best
AHz
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <877kklyb6a.fsf@darkstar.cartan>
Andy <···@snafu.de> writes:

> Nils Goesche wrote:
> > 
> > Well, you should believe at least EQ ;-)  Of course the cells have
> > changed.  Nobody ever argued that.  But the cell is still the same
> > object <X>.  It is this object, <X>, which is the ``value'' we are
> > talking about.  The CAR and CDR of <X> are totally irrelevant here.

> Then my understanding of call-by-value is wrong.

You are not alone there, that's why I wrote such a detailed
explanation :-)

> I assumed that it means i can give ANYTHING to a function and
> it is TOTALLY unchanged after the call.

Nope.

> And not only the "Rootlevel". But then i wonder what's the
> sense of call-by-value is at all.

Well, it's ``sense'' is to distinguish it from other possible
calling schemes.  Erik Naggum gave a nice comparison here:

http://groups.google.com/groups?q=g:thl2399957210d&dq=&hl=en&lr=&ie=UTF-8&selm=3229526943281243%40naggum.net

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Andreas Hinze
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3D1AD557.6EC58CFD@smi.de>
Nils Goesche wrote:
> 
> > Then my understanding of call-by-value is wrong.
> 
> You are not alone there, that's why I wrote such a detailed
> explanation :-)
> 
I looked up Erik's article and also the corresponding chapter in
the Dragon's Book. Now i (hope i) got it :-)

I didn't bother much about that topic before. Since i'm a autodidact
in hacking i'm fine with my (wrong) understanding of the call methods until
now. I.e. in C i simple assume that all what fits into a register is passed
by value and all other by reference. But it works fine the last fifteen years 
and around 100.000 lines of code ;-)

However, with LISP a lot of my knowledge of CS changes into a more detailed 
understanding of what's going on. So after all it still was the right decision
for me to start with LISP.

Thanks for the help
Sincerly
AHz
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn2ik$sn1$1@newsg1.svr.pol.co.uk>
Uzytkownik "Nils Goesche" <···@cartan.de> napisal w wiadomosci
···················@darkstar.cartan...
> Andy <···@snafu.de> writes:
>
> > Nils Goesche wrote:
> > >
> > > Well, you should believe at least EQ ;-)  Of course the cells have
> > > changed.  Nobody ever argued that.  But the cell is still the same
> > > object <X>.  It is this object, <X>, which is the ``value'' we are
> > > talking about.  The CAR and CDR of <X> are totally irrelevant here.
>
> > Then my understanding of call-by-value is wrong.
>
> You are not alone there, that's why I wrote such a detailed
> explanation :-)
>
> > I assumed that it means i can give ANYTHING to a function and
> > it is TOTALLY unchanged after the call.
>
> Nope.
>
> > And not only the "Rootlevel". But then i wonder what's the
> > sense of call-by-value is at all.
>
> Well, it's ``sense'' is to distinguish it from other possible
> calling schemes.  Erik Naggum gave a nice comparison here:
>
>
http://groups.google.com/groups?q=g:thl2399957210d&dq=&hl=en&lr=&ie=UTF-8&se
lm=3229526943281243%40naggum.net

    This explanation tallies with the assumption given above - because the
called function knows nothing about the calling environment (or at least
about where the actual parameter is stored), if the local binding is
changed, only the local environment notices. In the examples we have been
discussing above, this is *so* not the case.
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <87wusg97ii.fsf@darkstar.cartan>
"Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> writes:

> Uzytkownik "Nils Goesche" <···@cartan.de> napisal w wiadomosci
> ···················@darkstar.cartan...
> > Andy <···@snafu.de> writes:
> >
> > > Nils Goesche wrote:
> > > >
> > > > Well, you should believe at least EQ ;-)  Of course the cells have
> > > > changed.  Nobody ever argued that.  But the cell is still the same
> > > > object <X>.  It is this object, <X>, which is the ``value'' we are
> > > > talking about.  The CAR and CDR of <X> are totally irrelevant here.
> >
> > > Then my understanding of call-by-value is wrong.
> >
> > You are not alone there, that's why I wrote such a detailed
> > explanation :-)
> >
> > > I assumed that it means i can give ANYTHING to a function and
> > > it is TOTALLY unchanged after the call.
> >
> > Nope.
> >
> > > And not only the "Rootlevel". But then i wonder what's the
> > > sense of call-by-value is at all.
> >
> > Well, it's ``sense'' is to distinguish it from other possible
> > calling schemes.  Erik Naggum gave a nice comparison here:
> >
> >
> http://groups.google.com/groups?q=g:thl2399957210d&dq=&hl=en&lr=&ie=UTF-8&se
> lm=3229526943281243%40naggum.net
> 
>     This explanation tallies with the assumption given above - because the
> called function knows nothing about the calling environment (or at least
> about where the actual parameter is stored), if the local binding is
> changed, only the local environment notices. In the examples we have been
> discussing above, this is *so* not the case.

Of course it is.  The binding of MYCELL hasn't been changed by
the call to CHANGER.  In fact, I could have called CHANGER as
(CHANGER (FOO)) instead of (CHANGER MYCELL), which is hard to
explain if you assume this was call-by-reference.  Maybe I should
clarify what would happen if this /were/ call-by-reference:

(defun changer (cell)
  (setq cell 42))

(defun check ()
  (let ((mycell (cons 'foo 'bar)))
    (changer mycell)
    mycell))

With call-by-reference semantics, (CHECK) would return 42.  Are
you claiming it does?  This is quite ludicrous.

If you think Lisp uses call-by-reference semantics whenever it
feels like, please give an exact definition in which cases Lisp
uses call-by-value and when call-by-reference to back up your
theory.

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn48v$art$1@newsg4.svr.pol.co.uk>
Uzytkownik "Nils Goesche" <···@cartan.de> napisal w wiadomosci
···················@darkstar.cartan...

> (defun changer (cell)
>   (setq cell 42))
>
> (defun check ()
>   (let ((mycell (cons 'foo 'bar)))
>     (changer mycell)
>     mycell))
>
> With call-by-reference semantics, (CHECK) would return 42.  Are
> you claiming it does?  This is quite ludicrous.

    Yeah, fair point, see apology/retraction (And curse upon
number-constituted stack frames) posted as reply to message
<··············@darkstar.cartan>. Sorry for any offence caused.
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn3ns$tv2$1@newsg3.svr.pol.co.uk>
Uzytkownik "Nils Goesche" <···@cartan.de> napisal w wiadomosci
···················@darkstar.cartan...
> Andy <···@snafu.de> writes:
> > Then my understanding of call-by-value is wrong.
>
> You are not alone there, that's why I wrote such a detailed
> explanation :-)
>
> > I assumed that it means i can give ANYTHING to a function and
> > it is TOTALLY unchanged after the call.
>
> Nope.
>
> > And not only the "Rootlevel". But then i wonder what's the
> > sense of call-by-value is at all.
>
> Well, it's ``sense'' is to distinguish it from other possible
> calling schemes.  Erik Naggum gave a nice comparison here:
>
>
http://groups.google.com/groups?q=g:thl2399957210d&dq=&hl=en&lr=&ie=UTF-8&se
lm=3229526943281243%40naggum.net

    Nils, (And Andy) I should apologise: I have indeed been wrong. Once
again getting back to basics, rather than working from rules of thumb, wins
(Damn those stack frames made of numbers, not symbols!)

> Regards,
> --
> Nils Goesche
> Ask not for whom the <CONTROL-G> tolls.
>
> PGP key ID #xC66D6E6F
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <87ofds96pk.fsf@darkstar.cartan>
"Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> writes:

> Uzytkownik "Nils Goesche" <···@cartan.de> napisal w wiadomosci
> ···················@darkstar.cartan...
> > Andy <···@snafu.de> writes:
> > > Then my understanding of call-by-value is wrong.
> >
> > You are not alone there, that's why I wrote such a detailed
> > explanation :-)
> >
> > > I assumed that it means i can give ANYTHING to a function and
> > > it is TOTALLY unchanged after the call.
> >
> > Nope.
> >
> > > And not only the "Rootlevel". But then i wonder what's the
> > > sense of call-by-value is at all.
> >
> > Well, it's ``sense'' is to distinguish it from other possible
> > calling schemes.  Erik Naggum gave a nice comparison here:
> >
> >
> http://groups.google.com/groups?q=g:thl2399957210d&dq=&hl=en&lr=&ie=UTF-8&se
> lm=3229526943281243%40naggum.net
> 
>     Nils, (And Andy) I should apologise: I have indeed been wrong. Once
> again getting back to basics, rather than working from rules of thumb, wins
> (Damn those stack frames made of numbers, not symbols!)

No reason to apologize.  Many people get this wrong.  I was
expecting you to insist on this for the next couple of weeks and
got a little harsh myself, so I guess I'd rather apologize myself :-)

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Andreas Hinze
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3D202D05.4A65CB16@smi.de>
Marcin Tustin wrote:
> 
>     Nils, (And Andy) I should apologise: I have indeed been wrong. Once
> again getting back to basics, rather than working from rules of thumb, wins
> (Damn those stack frames made of numbers, not symbols!)
> 
No need to apologise. I have also had a hard time to learn what call-by-value
really means. Thanks to Nils again for his patience.
Best 
AHz
From: Joe Marshall
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <CLsS8.328212$cQ3.19601@sccrnsc01>
"Andy" <···@snafu.de> wrote in message ·····················@snafu.de...
> Nils Goesche wrote:
> >
> > Well, you should believe at least EQ ;-)  Of course the cells have
> > changed.  Nobody ever argued that.  But the cell is still the same
> > object <X>.  It is this object, <X>, which is the ``value'' we are
> > talking about.  The CAR and CDR of <X> are totally irrelevant here.
> >
> Then my understanding of call-by-value is wrong. I assumed that it means
> i can give ANYTHING to a function and it is TOTALLY unchanged after the call.
> And not only the "Rootlevel". But then i wonder what's the sense of
> call-by-value is at all.

Well, we had this discussion about a month ago (and it crops up every
few months).  Call-by-value means this:  the *variables* in the caller
*cannot* be modified by the callee.  Contrast this with call-by-reference
in which the variables of the caller *can* be modified by the callee.

Call-by-value means that in this expression:

 (let ((x y))
   (f x y)
   (eq x y))

There is no *function* F that can make the call to EQ return nil.
From: Andreas Hinze
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3D1AD8C8.5C88847E@smi.de>
Joe Marshall wrote:
> 
> Call-by-value means that in this expression:
> 
>  (let ((x y))
>    (f x y)
>    (eq x y))
> 
> There is no *function* F that can make the call to EQ return nil.
Yes, my fault was a wrong understanding of what evaluation yields.
Call-by-value simple means to pass the _evaluated_ value of the argument
to a function (compared to passing a reference). 
But i assumed that evaluating the argument gives a "copy" of the hole argument 
to F. That means calling F with a argument that evaluates to a cons will neither
change the cons nor it's car or cdr. 
But now i understand that evaluating that argument yields in a cons that has the 
same car/cdr as the argument itself.
And with that Nils is right, of course.

Sincerly
AHz
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn2aa$stg$1@newsg3.svr.pol.co.uk>
Uzytkownik "Andy" <···@snafu.de> napisal w wiadomosci
·····················@snafu.de...
> Nils Goesche wrote:
> >
> > Well, you should believe at least EQ ;-)  Of course the cells have
> > changed.  Nobody ever argued that.  But the cell is still the same
> > object <X>.  It is this object, <X>, which is the ``value'' we are
> > talking about.  The CAR and CDR of <X> are totally irrelevant here.
> >
> Then my understanding of call-by-value is wrong. I assumed that it means
> i can give ANYTHING to a function and it is TOTALLY unchanged after the
call.
> And not only the "Rootlevel". But then i wonder what's the sense of
> call-by-value is at all.

    Your understnding of call-by-value matches with mine, and I suspect,
most of the human race familiar with the term. Nils Goesche seems to be
speaking his own language. Oh well. Did anyone say "Read the HyperSpec"?
They should have.
From: Coby Beck
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <P4HT8.197$P53.92231@news20.bellglobal.com>
Marcin Tustin wrote:
> Uzytkownik "Andy" <···@snafu.de> napisal w wiadomosci
> ·····················@snafu.de...
>> Nils Goesche wrote:
>>>
>>> Well, you should believe at least EQ ;-)  Of course the cells have
>>> changed.  Nobody ever argued that.  But the cell is still the same
>>> object <X>.  It is this object, <X>, which is the ``value'' we are
>>> talking about.  The CAR and CDR of <X> are totally irrelevant here.
>>>
>> Then my understanding of call-by-value is wrong. I assumed that it
>> means i can give ANYTHING to a function and it is TOTALLY unchanged
>> after the call. And not only the "Rootlevel". But then i wonder
>> what's the sense of call-by-value is at all.
>
>     Your understnding of call-by-value matches with mine, and I
> suspect, most of the human race familiar with the term.

There is such a thing as "common misconception."  I think you are correct
that most people understand call-by-value as you do but it has been argued
to my satisfaction at least (I confess I have not looked it up for myself)
that this understanding is not correct according to the textbooks on
function calling semantics.  The important thing for programming in lisp is
understanding what will happen (where understanding is defined as being able
to correctly predict behaviour) when you pass different kinds of objects as
parameters to functions.  If you do, be happy with that.  But if you want to
argue about precise meanings of technical terms you should research them
first or be open to changing your opinion.  There was a very long and very
detailed debate about exactly this, including how important it is or isn't
to use technically defined labels as defined technically on this group some
weeks ago.  The subject was "Quest for pass-by-reference semantics in CL"

It makes informative and entertaining reading.

> Nils Goesche
> seems to be speaking his own language.

It may differ from yours, but it is not his own invention! ;o)

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Matthias Blume
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <fobs9p960y.fsf@trex8.cs.bell-labs.com>
"Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> writes:

> Uzytkownik "Andy" <···@snafu.de> napisal w wiadomosci
> ·····················@snafu.de...
> > Nils Goesche wrote:
> > >
> > > Well, you should believe at least EQ ;-)  Of course the cells have
> > > changed.  Nobody ever argued that.  But the cell is still the same
> > > object <X>.  It is this object, <X>, which is the ``value'' we are
> > > talking about.  The CAR and CDR of <X> are totally irrelevant here.
> > >
> > Then my understanding of call-by-value is wrong. I assumed that it means
> > i can give ANYTHING to a function and it is TOTALLY unchanged after the
> call.
> > And not only the "Rootlevel". But then i wonder what's the sense of
> > call-by-value is at all.
> 
>     Your understnding of call-by-value matches with mine, and I suspect,
> most of the human race familiar with the term.

No, the part of the human race actually familiar with the term will
disagree with you.

> Nils Goesche seems to be
> speaking his own language. Oh well. Did anyone say "Read the HyperSpec"?
> They should have.

-- 
-Matthias
From: Kaz Kylheku
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afnjeb$l3d$1@luna.vcn.bc.ca>
In article <················@snafu.de>, Andy wrote:
> Nils Goesche wrote:
>> 
>> Well, you should believe at least EQ ;-)  Of course the cells have
>> changed.  Nobody ever argued that.  But the cell is still the same
>> object <X>.  It is this object, <X>, which is the ``value'' we are
>> talking about.  The CAR and CDR of <X> are totally irrelevant here.
>> 
> Then my understanding of call-by-value is wrong. I assumed that it means
> i can give ANYTHING to a function and it is TOTALLY unchanged after the call.

So if I pass the integer 3 to a function, and 3 happens to be a UNIX
file descriptor, and that function modifies the file, that is no longer
call by value? 

Why are confusing the semantics of the objects involved with function calling
semantics? Call by value is entirely concerned with how that 3 is treated, not
what it means. Passing a copy of a pointer, handle or descriptor is still
call-by-value.

Call by reference (or call by address) means that the function calling
mechanism *itself* generates a reference, by taking the argument expression to
be a place that designates some cell where a value is stored.  It then passes
the location of that place to the function, rather than a copy of its value. If
the expression does not designate a place, then the call cannot happen, or some
trick must take place, such as the generation of an unnamed place to receive
any assigned value which is then discarded.

Passing a copy of an *existing* reference is not call-by-reference.
The function calling mechanism is then simply passing a scalar value,
which just happens to be a reference. It's irrelevant to that mechanism
what this scalar value means, that it's a reference.

> And not only the "Rootlevel". But then i wonder what's the sense of 
> call-by-value is at all.

In Lisp, call by value is a protection mechanism. A lexical scope is an object
with private data, such as variable bindings. Only code occuring within that
scope can access and modify this information. It is possible in Lisp to
grant a function call interface for doing something in a scope in some
disciplined way; that mechanism is the lexical closure.

Call by reference would violate the integrity of scopes, and hence of lexical
closures.

However, if you really want call by reference, you can emulate it with some
macros that are implemented in terms of closures. Imagine you want this
notation:

   (some-function (place (gethash "foo" hash-table)))

where (place expr) generates an object that refers to the place designated
by expr.

You can define place to be a macro which creates a pair of closures for
setting and getting the value of the place (gethash "foo" hash-table).  These
closures are passed down to some-function, which might use this notation to
use them:

  (defun some-function (place)
    (with-places ((x place))
      (setf x 42)))

The macro with-places is just syntactic sugar that lets you make a local
name for a place that allows you to treat it as a simple variable.
It would expand to something like:

    (symbol-macrolet ((x (get-place place)))
      (setf place 42))

so that ultimately, the setf would actually become:

  (setf (get-place place) 42)

which would macroexpand to:

  (set-place place 42)

And of course, the set-place function knows how to invoke the right closure of
the place object to get the job done.

Let's try to hack out an implementation:

  (defstruct place-info	;; could use a cons cell for this instead
    (get-function)
    (set-function))

  (defmacro place (expr)
    `(make-place-info :get-function #'(lambda () ,expr)
                      :set-function #'(lambda (new-val) (setf ,expr new-val))))

  (defun get-place (place) 
    (funcall (place-info-get-function place)))
  
  (defun set-place (place value)
    (funcall (place-info-set-function place) value))

  (defsetf get-place set-place)

  (defmacro with-places (place-binders &body forms)
    `(symbol-macrolet (,@(mapcar #'(lambda (binder) 
                                     (destructuring-bind (sym place) binder
                                       `(,sym (get-place ,place))))
                                 place-binders))
       ,@forms))

We could go further. For example, we could write a macro called
define-pass-by-ref-function, which would be similar to defun, but would
allow us to use a special notation for writing parameters that are places,
eliminating the need for with-places. A reader macro might give us a simpler
notation for lifting a place, like (frob #&(car c)) instead of 
(frob (place (car c))).  Or we could make a macro which knows how to
call pass-by-ref functions: (call-by-ref frob (car c)). this would
look up the definition of frob, figure out which parameters need to be
wrapped as places and which don't, and do the right thing.
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn25m$hku$1@newsg2.svr.pol.co.uk>
Uzytkownik "Andreas Hinze" <···@smi.de> napisal w wiadomosci
······················@smi.de...
> Nils Goesche wrote:
> >
> > Consider
> >
> > CL-USER 1 > (defun changer (cell)
> >               (setf (car cell) 'bingo))
> > CHANGER
> >
> > CL-USER 2 > (defun check ()
> >               (let* ((mycell (cons 'foo 'bar))
> >                      (memory mycell))
> >                 (changer mycell)
> >                 (eq memory mycell)))
> > CHECK
> >
> > CL-USER 3 > (check)
> > T
> >
> > See?  CHANGER changed the cons cell it was given all right, but the
> > only relevant fact is that MYCELL is still bound to the exact same
> > object as it was before the call to CHANGER.  This is because Lisp is
> > call-by-value.
> >
> Still trying to get it i tried your example and it works as you say. BUT
> modifying check like this:
>
> (defun check ()
>   (let* ((mycell (cons 'foo 'bar))
>          (memory mycell))
>     (changer mycell)
>     (eq memory mycell)
>     (format t "Memory: ~A Mycell: ~A~%" memory mycell)))  ; This line is
new
>
> yields:
>
> CL-USER 3 > (check)
> Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
> NIL
>
> So your check program works because both cells hold the same NEW value.
> (That at least shows how hard it is to write good test code ;-)

    This quite clearly shows that we have a call-by-reference. In a call by
value, the symbol CELL in CHANGER would refer to a new piece of memory
distinct from the memory where the value of the actual parameter to the
CHANGER call is stored, ie CELL would be bound to a different cons from
MEMORY, or from MYCELL. As changing the car of CELL changes MEMORY and
MYCELL, we see either that a) We have a call by value, but lisp then updates
the actual parameter anyway
b) We have a call-by-reference, where CELL is bound to the same cons as
MEMORY. These two cases can only be distinguished in an environment where
the execution of changer could be interrupted, or in a concurrent execution.
As CL does not do any kind of weird lazy evaluation, there is no reason for
a).

> IMHO cell IS passed to changer by value. But the cons cell has only two
> pointer (car/cdr) that points to the values FOO & BAR. And these one are
> not copied when changer is called. So the situation is similar to C where
> a pointer is passed to a function by value. But changing *p is still
visible
> in the calling environment.
> But, however, that's just my imagination and you should take it with care
> (remember, i'm a newbie ;-)
>
> Best
> AHz
From: Kaz Kylheku
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn6v0$hta$1@luna.vcn.bc.ca>
In article <············@newsg2.svr.pol.co.uk>, Marcin Tustin wrote:
> 
> Uzytkownik "Andreas Hinze" <···@smi.de> napisal w wiadomosci
> ······················@smi.de...
>> Nils Goesche wrote:
>> >
>> > Consider
>> >
>> > CL-USER 1 > (defun changer (cell)
>> >               (setf (car cell) 'bingo))
>> > CHANGER
>> >
>> > CL-USER 2 > (defun check ()
>> >               (let* ((mycell (cons 'foo 'bar))
>> >                      (memory mycell))
>> >                 (changer mycell)
>> >                 (eq memory mycell)))
>> > CHECK
>> >
>> > CL-USER 3 > (check)
>> > T
>> >
>> > See?  CHANGER changed the cons cell it was given all right, but the
>> > only relevant fact is that MYCELL is still bound to the exact same
>> > object as it was before the call to CHANGER.  This is because Lisp is
>> > call-by-value.
>> >
>> Still trying to get it i tried your example and it works as you say. BUT
>> modifying check like this:
>>
>> (defun check ()
>>   (let* ((mycell (cons 'foo 'bar))
>>          (memory mycell))
>>     (changer mycell)
>>     (eq memory mycell)
>>     (format t "Memory: ~A Mycell: ~A~%" memory mycell)))  ; This line is
> new
>>
>> yields:
>>
>> CL-USER 3 > (check)
>> Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
>> NIL
>>
>> So your check program works because both cells hold the same NEW value.
>> (That at least shows how hard it is to write good test code ;-)
> 
>     This quite clearly shows that we have a call-by-reference. In a call by
> value, the symbol CELL in CHANGER would refer to a new piece of memory
> distinct from the memory where the value of the actual parameter to the

You simply don't understand what the term ``value'' means in the context of the
language Lisp. In Lisp, values are references to objects. A variable having a
value, in Lisp terms, is a symbol having a binding to an object via its
reference.  (Some Lisp values are efficiently encoded in a few bits, and those
bits replace a reference to indirect storage. The semantics remain the same
however, because no operators are provided to destructively manipulate these
encodings).

The term ``call by value'' means that the argument expressions in the function
call are decimated to their resulting values before the call takes place. These
values are what is received in the subordinate function. The function has no
knowledge of or access to the original expressions which produced the values.

Call by value has nothing to do with symbols, or deep vs. shallow copying
semantics.

So for example if x refers to a vector, and we call (frob x), that
expression x is evaluated to yield the vector value, a reference.
That reference is passed to frob, by value.

Pass by reference would mean that x is evaluated to designate a place,
and that place is passed to the function. So for instance the calls

  (frob (gethash h key))
  (frob (car c))
  (frob (aref a 3))

would each pass a setf'able place to the frob function. The frob function
might look like this:

  (defun frob (place)
    ;; ...
    (setf place 42))

Moreover, a call like (frob 3) would then be in error, because 3 is
not an assignable place.

*That* would be call by reference. 

The essence of call by reference is that a reference to a place, an lvalue if
you will, is created in the call, and transported through it. If a value being
passed already has reference semantics, that is not call by reference. That is
passing a reference by value.
From: Kaz Kylheku
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn7d5$i21$1@luna.vcn.bc.ca>
In article <············@luna.vcn.bc.ca>, Kaz Kylheku wrote:
>   (frob (gethash h key))

Of course, here it is to be understood that ``key'' refers to a hash,
and ``h'' to a key. In case the notation isn't obvious.
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <87sn3496uc.fsf@darkstar.cartan>
"Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> writes:

> Uzytkownik "Andreas Hinze" <···@smi.de> napisal w wiadomosci
> ······················@smi.de...
> > (defun check ()
> >   (let* ((mycell (cons 'foo 'bar))
> >          (memory mycell))
> >     (changer mycell)
> >     (eq memory mycell)
> >     (format t "Memory: ~A Mycell: ~A~%" memory mycell)))  ; This line is
> new
> >
> > yields:
> >
> > CL-USER 3 > (check)
> > Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
> > NIL
> >
> > So your check program works because both cells hold the same NEW value.
> > (That at least shows how hard it is to write good test code ;-)
> 
>     This quite clearly shows that we have a call-by-reference.

No.  See my other posting for an example what /would/ be
call-by-reference.

> In a call by value, the symbol CELL in CHANGER would refer to a
> new piece of memory distinct from the memory where the value of
> the actual parameter to the CHANGER call is stored, ie CELL
> would be bound to a different cons from MEMORY, or from
> MYCELL.

Please give any reference text on Programming Language Semantics
that defines call-by-value this way.

> As changing the car of CELL changes MEMORY and MYCELL,

The _variables_ MEMORY and MYCELL have /not/ changed.  They are
still bound to the same cons cell.  That the CAR of the specific
cons cell MEMORY and MYCELL are bound to has changed is totally
unrelated to this question.

> we see either that a) We have a call by value, but lisp then
> updates the actual parameter anyway b) We have a
> call-by-reference, where CELL is bound to the same cons as
> MEMORY.

It is a), and what an ``updated actual parameter'' is, has yet to
be defined.  What you /mean/ is, apparently, that when I call
(CHANGER MYCELL), the variable MYCELL gets updated, (which it
doesn't because it is still bound to the same cons cell.  There
is nothing ``samer'' than EQ in Lisp).  Again: How could I call
(CHANGER (FOO)) then?  How is the ``actual parameter'' (FOO)
``updated''?  Why is the ``actual parameter'' not updated in

(defun changer (cell)
  (setq cell 42))

(defun check ()
  (let ((mycell (cons 'foo 'bar)))
    (changer mycell)
    mycell))

?  How do you think Lisp decides which calling semantics to use,
then?  Do you think it first makes a ``test execute'' for every
called function to find out which calling semantics to use?  What
you are suggesting here is totally ridiculous, sorry.

> These two cases can only be distinguished in an
> environment where the execution of changer could be
> interrupted, or in a concurrent execution.  As CL does not do
> any kind of weird lazy evaluation, there is no reason for a).

Sounds like pure madness to me:-)

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Matthias Blume
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <fofzz1964q.fsf@trex8.cs.bell-labs.com>
"Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> writes:

> Uzytkownik "Andreas Hinze" <···@smi.de> napisal w wiadomosci
> ······················@smi.de...
> > Nils Goesche wrote:
> > >
> > > Consider
> > >
> > > CL-USER 1 > (defun changer (cell)
> > >               (setf (car cell) 'bingo))
> > > CHANGER
> > >
> > > CL-USER 2 > (defun check ()
> > >               (let* ((mycell (cons 'foo 'bar))
> > >                      (memory mycell))
> > >                 (changer mycell)
> > >                 (eq memory mycell)))
> > > CHECK
> > >
> > > CL-USER 3 > (check)
> > > T
> > >
> > > See?  CHANGER changed the cons cell it was given all right, but the
> > > only relevant fact is that MYCELL is still bound to the exact same
> > > object as it was before the call to CHANGER.  This is because Lisp is
> > > call-by-value.
> > >
> > Still trying to get it i tried your example and it works as you say. BUT
> > modifying check like this:
> >
> > (defun check ()
> >   (let* ((mycell (cons 'foo 'bar))
> >          (memory mycell))
> >     (changer mycell)
> >     (eq memory mycell)
> >     (format t "Memory: ~A Mycell: ~A~%" memory mycell)))  ; This line is
> new
> >
> > yields:
> >
> > CL-USER 3 > (check)
> > Memory: (BINGO . BAR) Mycell: (BINGO . BAR)
> > NIL
> >
> > So your check program works because both cells hold the same NEW value.
> > (That at least shows how hard it is to write good test code ;-)
> 
>     This quite clearly shows that we have a call-by-reference.

Please, don't start this nonsense again.  We've been through this before.
Lisp is call-by-value.  The effect you observe has nothing to do with that.

See the archives for the lengthy (and sometimes rather unfortunate)
discussion.

> In a call by
> value, the symbol CELL in CHANGER would refer to a new piece of memory
> distinct from the memory where the value of the actual parameter to the
> CHANGER call is stored, ie CELL would be bound to a different cons from
> MEMORY, or from MYCELL. As changing the car of CELL changes MEMORY and
> MYCELL, we see either that a) We have a call by value, but lisp then updates
> the actual parameter anyway
> b) We have a call-by-reference, where CELL is bound to the same cons as
> MEMORY. These two cases can only be distinguished in an environment where
> the execution of changer could be interrupted, or in a concurrent execution.
> As CL does not do any kind of weird lazy evaluation, there is no reason for
> a).
> 
> > IMHO cell IS passed to changer by value. But the cons cell has only two
> > pointer (car/cdr) that points to the values FOO & BAR. And these one are
> > not copied when changer is called. So the situation is similar to C where
> > a pointer is passed to a function by value. But changing *p is still
> visible
> > in the calling environment.
> > But, however, that's just my imagination and you should take it with care
> > (remember, i'm a newbie ;-)
> >
> > Best
> > AHz
> 
> 

-- 
-Matthias
From: Marcin Tustin
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <afn1hm$s2e$1@newsg1.svr.pol.co.uk>
Uzytkownik "Nils Goesche" <······@cartan.de> napisal w wiadomosci
···················@pc022.bln.elmeg.de...
>
> It seems you haven't really understood what call-by-value actually
> means.
>
> Consider
>
> CL-USER 1 > (defun changer (cell)
>               (setf (car cell) 'bingo))
> CHANGER
>
> CL-USER 2 > (defun check ()
>               (let* ((mycell (cons 'foo 'bar))
>                      (memory mycell))
>                 (changer mycell)
>                 (eq memory mycell)))
> CHECK
>
> CL-USER 3 > (check)
> T
>
> See?  CHANGER changed the cons cell it was given all right, but the
> only relevant fact is that MYCELL is still bound to the exact same
> object as it was before the call to CHANGER.  This is because Lisp is
> call-by-value.

    This proves exactly nothing. If MEMORY and MYCELL are bound to the same
object, and that object is changed, then they are still bound to the same
object.
From: Nils Goesche
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <871yaoamju.fsf@darkstar.cartan>
"Marcin Tustin" <·······@GUeswhatthisbitisfor.mindless.com> writes:

> Uzytkownik "Nils Goesche" <······@cartan.de> napisal w wiadomosci
> ···················@pc022.bln.elmeg.de...
> >
> > It seems you haven't really understood what call-by-value actually
> > means.
> >
> > Consider
> >
> > CL-USER 1 > (defun changer (cell)
> >               (setf (car cell) 'bingo))
> > CHANGER
> >
> > CL-USER 2 > (defun check ()
> >               (let* ((mycell (cons 'foo 'bar))
> >                      (memory mycell))
> >                 (changer mycell)
> >                 (eq memory mycell)))
> > CHECK
> >
> > CL-USER 3 > (check)
> > T
> >
> > See?  CHANGER changed the cons cell it was given all right, but the
> > only relevant fact is that MYCELL is still bound to the exact same
> > object as it was before the call to CHANGER.  This is because Lisp is
> > call-by-value.
> 
>     This proves exactly nothing. If MEMORY and MYCELL are bound to the same
> object, and that object is changed, then they are still bound to the same
> object.

Yes.  The important point being that the binding of MYCELL hasn't
been changed by the call to CHANGER.

Regards,
-- 
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID #xC66D6E6F
From: Joe Marshall
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <ekzR8.133920$R61.50247@rwcrnsc52.ops.asp.att.net>
"Donovan Parks" <······@uvic.ca> wrote in message ··················@casey.uvic.ca...
> Hello,
>
> I am having some trouble understanding how lisp handles the scope of
> variables.  I thought that any symbol contained in the parameter list of a
> procedure was local to that procedure and that parameters were passed by
> value.  Surely, this is the case (as I'm taking it straight from my course
> notes), but I am lost at how the following code operates:

This is true, but remember that you are passing *aggregate* data,
so if you modify the contents of the data the modification will be
seen by everyone.

If you modify the *variable* (via setq) rather than what the variable
is holding, then there is no way for other code to see that modification.
From: Martin Simmons
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <3d198d3e$0$233$ed9e5944@reading.news.pipex.net>
"Joe Marshall" <·············@attbi.com> wrote in message
···························@rwcrnsc52.ops.asp.att.net...
>
> "Donovan Parks" <······@uvic.ca> wrote in message
··················@casey.uvic.ca...
> > Hello,
> >
> > I am having some trouble understanding how lisp handles the scope of
> > variables.  I thought that any symbol contained in the parameter list of a
> > procedure was local to that procedure and that parameters were passed by
> > value.  Surely, this is the case (as I'm taking it straight from my course
> > notes), but I am lost at how the following code operates:
>
> This is true, but remember that you are passing *aggregate* data,
> so if you modify the contents of the data the modification will be
> seen by everyone.

To be clear, he is passing a pointer to aggregate data.  In a language like C,
if you pass aggregate data by value then modifying it will not affect the
caller's copy of the data.  It isn't possible to pass aggregate data by value in
Lisp.
--
Martin Simmons, Xanalys Software Tools
······@xanalys.com
rot13 to reply
From: Joe Marshall
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <jHsS8.5318$Uu2.501@sccrnsc03>
"Martin Simmons" <······@xanalys.com> wrote in message ····························@reading.news.pipex.net...
> "Joe Marshall" <·············@attbi.com> wrote in message
> ···························@rwcrnsc52.ops.asp.att.net...
> >
> > "Donovan Parks" <······@uvic.ca> wrote in message
> ··················@casey.uvic.ca...
> > > Hello,
> > >
> > > I am having some trouble understanding how lisp handles the scope of
> > > variables.  I thought that any symbol contained in the parameter list of a
> > > procedure was local to that procedure and that parameters were passed by
> > > value.  Surely, this is the case (as I'm taking it straight from my course
> > > notes), but I am lost at how the following code operates:
> >
> > This is true, but remember that you are passing *aggregate* data,
> > so if you modify the contents of the data the modification will be
> > seen by everyone.
>
> To be clear, he is passing a pointer to aggregate data.  In a language like C,
> if you pass aggregate data by value then modifying it will not affect the
> caller's copy of the data.  It isn't possible to pass aggregate data by value in
> Lisp.

Yeah, I keep forgetting that C has this funky way of dealing with structs.

(Incidentally, it *is* possible to pass aggregate data by value in Lisp:
    (let ((x '(foo bar baz)))  (apply #'f x))

 But that's a hack.)
From: Donovan Parks
Subject: Re: Scope of Variables between Functions
Date: 
Message-ID: <af8053$2r7q$1@casey.uvic.ca>
Hello,

Thanks for all the help.  I've managed to get my code working as desired,
but am still a little fuzzy on the scope rules.  Hopefully, with time and
from playing around this will work itself out.

Regards,
Donovan