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
······@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!"
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!"
······@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.
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.