From: ······@gmail.com
Subject: argument passing with side effect
Date: 
Message-ID: <1163154457.439588.93180@i42g2000cwa.googlegroups.com>
Hi,

I'm new to lisp and have a little question.
I have the following code :

(setf a '(blah))

(defun do-it (x)
  (setf x 'it)
  (print x))

(defun do-it-in (x)
  (setf (car x) 'in)
  (print x))

(do-it (car a)) ; print IT
(print a)       ; print (BLAH)

(do-it-in a)    ; print (IN)
(print a)       ; print (IN)

Where it prints (BLAH) I was expecting (IT).
Could you explain the behavior or point me to a reference ?

I asked this because I was trying to write a simple lisp interpreter in
lisp.
So you might thing of 'a' in the code to be the environment to be
passed to my 'eval' function and
'do-it' the function to add a new binding in the environment. Is-it the
correct way to go ?
Or is it better to pass-and-return the environment around, maintaining
the code free of side-effects ?
In this later case, is there a common idiom in lisp to pass it around
(maybe like the state monad way of haskell) ?

Thanks a lot,
Thu

From: Pascal Bourguignon
Subject: Re: argument passing with side effect
Date: 
Message-ID: <87velnpom7.fsf@thalassa.informatimago.com>
······@gmail.com writes:
> I'm new to lisp and have a little question.
> I have the following code :
>
> (setf a '(blah))

You have an error here, since you pass a to do-it-in and it sets the
car of the list, it breaks because here you have a literal list.  When
you plan to modify lists, use (list 'blah) instead of (quote (blah)),
to build a new mutable list.

> (defun do-it (x)
>   (setf x 'it)
>   (print x))
>
> (defun do-it-in (x)
>   (setf (car x) 'in)
>   (print x))
>
> (do-it (car a)) ; print IT
> (print a)       ; print (BLAH)
>
> (do-it-in a)    ; print (IN)
> (print a)       ; print (IN)
>
> Where it prints (BLAH) I was expecting (IT).
> Could you explain the behavior or point me to a reference ?

In lisp, the arguments are passed _by_ _value_.
Only some lisp values are references to some object.

(setf a 1) puts the number 1 in the memory slot named a:

   +-----+
a: |  1  |
   +-----+

(setf a (list 1 2 3)) puts a reference to the cons whose car is 1 in
                      the memory slot named a:

   +-----+     +-----+-----+   +-----+-----+   +-----+-----+
a: |  *--|---->|  1  |  *--|-->|  2  |  *--|-->|  3  | NIL |
   +-----+     +-----+-----+   +-----+-----+   +-----+-----+

So, when you pass a to do-it-in, the content of the memory slot named
a is copied into the the memory slot named x:

In the first case, you get two totally independenant memory slots:

   +-----+
a: |  1  |
   +-----+

   +-----+
x: |  1  |
   +-----+


In the second case, you get two independant memory slots that happen
to point to the same lisp object:

   +-----+     +-----+-----+   +-----+-----+   +-----+-----+
a: |  *--|---->|  1  |  *--|-->|  2  |  *--|-->|  3  | NIL |
   +-----+     +-----+-----+   +-----+-----+   +-----+-----+
                  ^
   +-----+        |
x: |  *--|--------+
   +-----+


(setf (car x) 0) would modify the CAR of the first cons cell, so you'd
get:

   +-----+     +-----+-----+   +-----+-----+   +-----+-----+
a: |  *--|---->|  0  |  *--|-->|  2  |  *--|-->|  3  | NIL |
   +-----+     +-----+-----+   +-----+-----+   +-----+-----+
                  ^
   +-----+        |
x: |  *--|--------+
   +-----+

So a (print a) would show (0 2 3).


And (setf x 42) would just modify the memory slot named x:

   +-----+     +-----+-----+   +-----+-----+   +-----+-----+
a: |  *--|---->|  0  |  *--|-->|  2  |  *--|-->|  3  | NIL |
   +-----+     +-----+-----+   +-----+-----+   +-----+-----+
          
   +-----+
x: | 42  |
   +-----+

and leave the memory slot named a unchanged.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"You question the worthiness of my code? I should kill you where you
stand!"
From: ······@gmail.com
Subject: Re: argument passing with side effect
Date: 
Message-ID: <1163156338.114097.43150@h54g2000cwb.googlegroups.com>
thanks Pascal !

(and what about the second part of the question ?)
Thu

On Nov 10, 11:44 am, Pascal Bourguignon <····@informatimago.com> wrote:
> ······@gmail.com writes:
> > I'm new to lisp and have a little question.
> > I have the following code :
>
> > (setf a '(blah))You have an error here, since you pass a to do-it-in and it sets the
> car of the list, it breaks because here you have a literal list.  When
> you plan to modify lists, use (list 'blah) instead of (quote (blah)),
> to build a new mutable list.
>
>
>
> > (defun do-it (x)
> >   (setf x 'it)
> >   (print x))
>
> > (defun do-it-in (x)
> >   (setf (car x) 'in)
> >   (print x))
>
> > (do-it (car a)) ; print IT
> > (print a)       ; print (BLAH)
>
> > (do-it-in a)    ; print (IN)
> > (print a)       ; print (IN)
>
> > Where it prints (BLAH) I was expecting (IT).
> > Could you explain the behavior or point me to a reference ?In lisp, the arguments are passed _by_ _value_.
> Only some lisp values are references to some object.
>
> (setf a 1) puts the number 1 in the memory slot named a:
>
>    +-----+
> a: |  1  |
>    +-----+
>
> (setf a (list 1 2 3)) puts a reference to the cons whose car is 1 in
>                       the memory slot named a:
>
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
> a: |  *--|---->|  1  |  *--|-->|  2  |  *--|-->|  3  | NIL |
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
>
> So, when you pass a to do-it-in, the content of the memory slot named
> a is copied into the the memory slot named x:
>
> In the first case, you get two totally independenant memory slots:
>
>    +-----+
> a: |  1  |
>    +-----+
>
>    +-----+
> x: |  1  |
>    +-----+
>
> In the second case, you get two independant memory slots that happen
> to point to the same lisp object:
>
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
> a: |  *--|---->|  1  |  *--|-->|  2  |  *--|-->|  3  | NIL |
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
>                   ^
>    +-----+        |
> x: |  *--|--------+
>    +-----+
>
> (setf (car x) 0) would modify the CAR of the first cons cell, so you'd
> get:
>
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
> a: |  *--|---->|  0  |  *--|-->|  2  |  *--|-->|  3  | NIL |
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
>                   ^
>    +-----+        |
> x: |  *--|--------+
>    +-----+
>
> So a (print a) would show (0 2 3).
>
> And (setf x 42) would just modify the memory slot named x:
>
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
> a: |  *--|---->|  0  |  *--|-->|  2  |  *--|-->|  3  | NIL |
>    +-----+     +-----+-----+   +-----+-----+   +-----+-----+
>
>    +-----+
> x: | 42  |
>    +-----+
>
> and leave the memory slot named a unchanged.
>
> --
> __Pascal Bourguignon__                    http://www.informatimago.com/
>
> "You question the worthiness of my code? I should kill you where you
> stand!"
From: Pascal Bourguignon
Subject: Re: argument passing with side effect
Date: 
Message-ID: <87k623pnlt.fsf@thalassa.informatimago.com>
······@gmail.com writes:
> (and what about the second part of the question ?)

It's as you want, and it depends whether you're doing a toy or a real system.

Well, given that you use Common Lisp instead of scheme, perhaps you're
doing a real system, then you can handle state.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.
From: ······@gmail.com
Subject: Re: argument passing with side effect
Date: 
Message-ID: <1163157548.731293.270560@i42g2000cwa.googlegroups.com>
Thank you,
Thu

On Nov 10, 12:06 pm, Pascal Bourguignon <····@informatimago.com> wrote:
> ······@gmail.com writes:
> > (and what about the second part of the question ?)It's as you want, and it depends whether you're doing a toy or a real system.
>
> Well, given that you use Common Lisp instead of scheme, perhaps you're
> doing a real system, then you can handle state.
>
> --
> __Pascal Bourguignon__                    http://www.informatimago.com/
> The rule for today:
> Touch my tail, I shred your hand.
> New rule tomorrow.