From: [Invalid-From-Line]
Subject: unexpected behaviour
Date: 
Message-ID: <c1vvcs$43t$1@news.ox.ac.uk>
Hi,

I'm fairly new to lisp. I've come across the following behaviour, which
surprised me:

(defun unexpected ()
    (let ((x))
        (setf x '(1 2 3))
        (princ x)              ; prints (1 2 3) on first use of function,
but (0 2 3) after that
        (setf (car x) 0)))

(defun expected ()
    (let ((x))
        (setf x (list 1 2 3))
        (princ x)              ; always prints (1 2 3)
        (setf (car x) 0)))

I'd be very grateful for an explanation of why the function unexpected
prints (1 2 3) the first time it's used but (0 2 3) after that.
I can see roughly what is happening but I don't understand in detail what is
going on.

Thanks in advance for any help,
Frederick

From: Joe Marshall
Subject: Re: unexpected behaviour
Date: 
Message-ID: <ishos9gz.fsf@ccs.neu.edu>
<····@fvdw.com> writes:

> Hi,
>
> I'm fairly new to lisp. I've come across the following behaviour, which
> surprised me:
>
> (defun unexpected ()
>     (let ((x))
>         (setf x '(1 2 3))
>         (princ x)              ; prints (1 2 3) on first use of function,
> but (0 2 3) after that
>         (setf (car x) 0)))
>
> (defun expected ()
>     (let ((x))
>         (setf x (list 1 2 3))
>         (princ x)              ; always prints (1 2 3)
>         (setf (car x) 0)))
>
> I'd be very grateful for an explanation of why the function unexpected
> prints (1 2 3) the first time it's used but (0 2 3) after that.
> I can see roughly what is happening but I don't understand in detail what is
> going on.

In the first case, you are modifying the source code of your program!
(don't do that)
From: [Invalid-From-Line]
Subject: Re: unexpected behaviour
Date: 
Message-ID: <c1vvt4$477$1@news.ox.ac.uk>
"Joe Marshall" <···@ccs.neu.edu> wrote in message
·················@ccs.neu.edu...
> <····@fvdw.com> writes:
>
> > Hi,
> >
> > I'm fairly new to lisp. I've come across the following behaviour, which
> > surprised me:
> >
> > (defun unexpected ()
> >     (let ((x))
> >         (setf x '(1 2 3))
> >         (princ x)              ; prints (1 2 3) on first use of
function,
> > but (0 2 3) after that
> >         (setf (car x) 0)))
> >
> > (defun expected ()
> >     (let ((x))
> >         (setf x (list 1 2 3))
> >         (princ x)              ; always prints (1 2 3)
> >         (setf (car x) 0)))
> >
> > I'd be very grateful for an explanation of why the function unexpected
> > prints (1 2 3) the first time it's used but (0 2 3) after that.
> > I can see roughly what is happening but I don't understand in detail
what is
> > going on.
>
> In the first case, you are modifying the source code of your program!
> (don't do that)

Could you explain a bit more? Thanks.
From: Joe Marshall
Subject: Re: unexpected behaviour
Date: 
Message-ID: <ekscbcre.fsf@ccs.neu.edu>
<····@fvdw.com> writes:

> "Joe Marshall" <···@ccs.neu.edu> wrote in message
> ·················@ccs.neu.edu...
>> In the first case, you are modifying the source code of your program!
>> (don't do that)

>> <····@fvdw.com> writes:
>>
> Could you explain a bit more? Thanks.

>> > (defun unexpected ()
>> >     (let ((x))
>> >         (setf x '(1 2 3))
>> >         (princ x)  ; prints (1 2 3) on first use of function,
>> >         (setf (car x) 0)))

When you have '(1 2 3) like that in your program, it says to the
system "I mean this literal thing right here."  So that chunk of
source code is literally used as the value.

When you later change the first element, you are changing the
literal value.

In this:

>> > (defun expected ()
>> >     (let ((x))
>> >         (setf x (list 1 2 3))
>> >         (princ x)              ; always prints (1 2 3)
>> >         (setf (car x) 0)))

You are saying to the system `make me a list with the elements 1, 2,
and 3' each and every time you run the function.  The list is then
printed and the first element is modified.  The next time you run the
function, you get a whole new list.
From: Pascal Bourguignon
Subject: Re: unexpected behaviour
Date: 
Message-ID: <873c8sxjzv.fsf@thalassa.informatimago.com>
<····@fvdw.com> writes:

> "Joe Marshall" <···@ccs.neu.edu> wrote in message
> ·················@ccs.neu.edu...
> > <····@fvdw.com> writes:
> >
> > > Hi,
> > >
> > > I'm fairly new to lisp. I've come across the following behaviour, which
> > > surprised me:
> > >
> > > (defun unexpected ()
> > >     (let ((x))
> > >         (setf x '(1 2 3))
> > >         (princ x)              ; prints (1 2 3) on first use of
> > >                                ; function,
> > > but (0 2 3) after that
> > >         (setf (car x) 0)))
> > In the first case, you are modifying the source code of your program!
> > (don't do that)
> 
> Could you explain a bit more? Thanks.

This can be understood with all details when you know how Lisp
programs are executed, by the eval/apply couple of functions.  One of
the best tutorial on this matter would be SICP
(http://mitpress.mit.edu/sicp/), but here is an toy you can play with.

I'll simplify and avoid the let, argument bindings, etc, and replace
(setf (car x) 0) by what is actually done once all the macros are
expanded: (rplaca x 0).


[341]> (my-defun a-fun () (setq x '(1 2 3)) (print x) (rplaca x 0) (print x))
A-FUN
[342]> (my-eval '(a-fun))
((1 2 3)) 
((0 2 3)) 
NIL
[343]> (my-eval '(a-fun))
((0 2 3)) 
((0 2 3)) 
NIL


Here is a toy implementation showing what's going on:

(defmacro my-defun (name arg-list &body body)
  `(setf (symbol-function ',name) (lambda  ,arg-list (progn  ,@body))))


Defining a function consists  into storing somewhere a list of the form:

    (lambda argument-list (progn expresion-list))

Evaluating an expressions is relatively simple: either it's a symbol
in which case we fetch the value associated with that symbol, or it's
an atom (a literal value) in which case we just return it, or it's a
list whose first element determines the processing to do.  There are
some special forms that are interpreted specially by the eval
function, but most of them are just plain functions for which eval
just evaluates the arguments and pass them to the apply function to
have it call the function.


(defun my-eval (sexp)
  (cond
   ((symbolp sexp) (symbol-value sexp))
   ((atom sexp)    sexp)
   (t (case (car sexp)
        ((quote)  (cadr sexp))
        ((if)     (if (my-eval (cadr sexp))
                    (my-eval (caddr sexp))
                    (my-eval (cadddr sexp))))
        ((setq)   (setf (symbol-value (cadr sexp)) (my-eval (caddr sexp))))
        ((rplaca) (rplaca (my-eval (cadr sexp)) (my-eval (caddr sexp))))
        ((progn)
         (my-eval (cadr sexp))
         (if (cddr sexp) (my-eval (cons 'progn (cddr sexp)))))
        (otherwise
         (my-apply (symbol-function (car sexp))
                (mapcar (function my-eval) (cdr sexp))))))))


Apply my process specially primitive functions (and compiled
functions, but that's another subject), but it will normally just bind
the arguments, recover the body of the function and invoke eval to
further the processing.


(defun my-apply (fun &rest effective-arg-list)
  (let* ((lambda-exp      (function-lambda-expression fun))
         (formal-arg-list (cadr lambda-exp))
         (sexp            (caddr lambda-exp)))
    (if (eq 'lambda (car lambda-exp))
        ;; let's skip the argument binding
        (my-eval sexp)
        ;; a primive function
        (funcall (function apply) fun effective-arg-list))))


So, what happens when you define a function:

[364]> (my-defun a-fun () (setq x '(1 2 3)) (print x) (rplaca x 0) (print x))
A-FUN

You just store some data in what's called the function slot of the
symbol naming the function:

[365]> (setq l (function-lambda-expression (symbol-function 'a-fun)))
(LAMBDA NIL (PROGN (SETQ X '(1 2 3)) (PRINT X) (RPLACA X 0) (PRINT X)))
[366]> (second (third (second (third l))))
(1 2 3)

If you follow from then you'll see that what is stored in the value
slot of the symbol X is actually that same exact list, and what is
modified with rplaca is the car of the first cons cell of that same
exact list.  Remember, this is a list that is in the lambda expression
of the function.  That means that you are modifying the function itself.


I'm not sure we can call it the _source_ code, but it's definitely the
code of the function, which consists of data in the form of lists.

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: [Invalid-From-Line]
Subject: Re: unexpected behaviour
Date: 
Message-ID: <c20kl4$bs7$1@news.ox.ac.uk>
Thanks! This was very useful. I'll get SICP, too.

"Pascal Bourguignon" <····@thalassa.informatimago.com> wrote in message
···················@thalassa.informatimago.com...
> <····@fvdw.com> writes:
>
> > "Joe Marshall" <···@ccs.neu.edu> wrote in message
> > ·················@ccs.neu.edu...
> > > <····@fvdw.com> writes:
> > >
> > > > Hi,
> > > >
> > > > I'm fairly new to lisp. I've come across the following behaviour,
which
> > > > surprised me:
> > > >
> > > > (defun unexpected ()
> > > >     (let ((x))
> > > >         (setf x '(1 2 3))
> > > >         (princ x)              ; prints (1 2 3) on first use of
> > > >                                ; function,
> > > > but (0 2 3) after that
> > > >         (setf (car x) 0)))
> > > In the first case, you are modifying the source code of your program!
> > > (don't do that)
> >
> > Could you explain a bit more? Thanks.
>
> This can be understood with all details when you know how Lisp
> programs are executed, by the eval/apply couple of functions.  One of
> the best tutorial on this matter would be SICP
> (http://mitpress.mit.edu/sicp/), but here is an toy you can play with.
>
> I'll simplify and avoid the let, argument bindings, etc, and replace
> (setf (car x) 0) by what is actually done once all the macros are
> expanded: (rplaca x 0).
>
>
> [341]> (my-defun a-fun () (setq x '(1 2 3)) (print x) (rplaca x 0) (print
x))
> A-FUN
> [342]> (my-eval '(a-fun))
> ((1 2 3))
> ((0 2 3))
> NIL
> [343]> (my-eval '(a-fun))
> ((0 2 3))
> ((0 2 3))
> NIL
>
>
> Here is a toy implementation showing what's going on:
>
> (defmacro my-defun (name arg-list &body body)
>   `(setf (symbol-function ',name) (lambda  ,arg-list (progn  ,@body))))
>
>
> Defining a function consists  into storing somewhere a list of the form:
>
>     (lambda argument-list (progn expresion-list))
>
> Evaluating an expressions is relatively simple: either it's a symbol
> in which case we fetch the value associated with that symbol, or it's
> an atom (a literal value) in which case we just return it, or it's a
> list whose first element determines the processing to do.  There are
> some special forms that are interpreted specially by the eval
> function, but most of them are just plain functions for which eval
> just evaluates the arguments and pass them to the apply function to
> have it call the function.
>
>
> (defun my-eval (sexp)
>   (cond
>    ((symbolp sexp) (symbol-value sexp))
>    ((atom sexp)    sexp)
>    (t (case (car sexp)
>         ((quote)  (cadr sexp))
>         ((if)     (if (my-eval (cadr sexp))
>                     (my-eval (caddr sexp))
>                     (my-eval (cadddr sexp))))
>         ((setq)   (setf (symbol-value (cadr sexp)) (my-eval (caddr
sexp))))
>         ((rplaca) (rplaca (my-eval (cadr sexp)) (my-eval (caddr sexp))))
>         ((progn)
>          (my-eval (cadr sexp))
>          (if (cddr sexp) (my-eval (cons 'progn (cddr sexp)))))
>         (otherwise
>          (my-apply (symbol-function (car sexp))
>                 (mapcar (function my-eval) (cdr sexp))))))))
>
>
> Apply my process specially primitive functions (and compiled
> functions, but that's another subject), but it will normally just bind
> the arguments, recover the body of the function and invoke eval to
> further the processing.
>
>
> (defun my-apply (fun &rest effective-arg-list)
>   (let* ((lambda-exp      (function-lambda-expression fun))
>          (formal-arg-list (cadr lambda-exp))
>          (sexp            (caddr lambda-exp)))
>     (if (eq 'lambda (car lambda-exp))
>         ;; let's skip the argument binding
>         (my-eval sexp)
>         ;; a primive function
>         (funcall (function apply) fun effective-arg-list))))
>
>
> So, what happens when you define a function:
>
> [364]> (my-defun a-fun () (setq x '(1 2 3)) (print x) (rplaca x 0) (print
x))
> A-FUN
>
> You just store some data in what's called the function slot of the
> symbol naming the function:
>
> [365]> (setq l (function-lambda-expression (symbol-function 'a-fun)))
> (LAMBDA NIL (PROGN (SETQ X '(1 2 3)) (PRINT X) (RPLACA X 0) (PRINT X)))
> [366]> (second (third (second (third l))))
> (1 2 3)
>
> If you follow from then you'll see that what is stored in the value
> slot of the symbol X is actually that same exact list, and what is
> modified with rplaca is the car of the first cons cell of that same
> exact list.  Remember, this is a list that is in the lambda expression
> of the function.  That means that you are modifying the function itself.
>
>
> I'm not sure we can call it the _source_ code, but it's definitely the
> code of the function, which consists of data in the form of lists.
>
> -- 
> __Pascal_Bourguignon__                     http://www.informatimago.com/
> There is no worse tyranny than to force a man to pay for what he doesn't
> want merely because you think it would be good for him.--Robert Heinlein
> http://www.theadvocates.org/
From: Kenny Tilton
Subject: Re: unexpected behaviour
Date: 
Message-ID: <sPL0c.122$tP6.108601@twister.nyc.rr.com>
····@fvdw.com wrote:
> Hi,
> 
> I'm fairly new to lisp. I've come across the following behaviour, which
> surprised me:
> 
> (defun unexpected ()
>     (let ((x))
>         (setf x '(1 2 3))
>         (princ x)              ; prints (1 2 3) on first use of function,
> but (0 2 3) after that
>         (setf (car x) 0)))
> 
> (defun expected ()
>     (let ((x))
>         (setf x (list 1 2 3))
>         (princ x)              ; always prints (1 2 3)
>         (setf (car x) 0)))
> 
> I'd be very grateful for an explanation of why the function unexpected
> prints (1 2 3) the first time it's used but (0 2 3) after that.
> I can see roughly what is happening but I don't understand in detail what is
> going on.

The first case is a little like modifying a string literal in "C", if 
you understand the consequences of that. The C compiler stashes the 
literal value somewhere in a table in the object code. So modifying it 
once /apparently/ dynamically modifies it forever. But if you allocate 
memory in the C app (as when you coded "(list ...)" in the second 
example) and then modify that storage, only explicit dereferencing of 
the same dynamic pointer sees the modified storage.

Unfortunately, introductory lisp texts (and the hyperspec, I have 
observed) just love to use '(a b c) in the first few chapters, even in 
code that destructively modifies the list, so just about every newbie 
trips over this early on.

ie, You have been sandbagged. :)

kenny

> 
> Thanks in advance for any help,
> Frederick
> 
> 

-- 
http://tilton-technology.com

Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film

Your Project Here! http://alu.cliki.net/Industry%20Application
From: Frode Vatvedt Fjeld
Subject: Re: unexpected behaviour
Date: 
Message-ID: <2h8yikjtcs.fsf@vserver.cs.uit.no>
<····@fvdw.com> writes:

> (defun unexpected ()
>     (let ((x))
>         (setf x '(1 2 3))
>         (princ x)              ; prints (1 2 3) on first use of function,
> but (0 2 3) after that
>         (setf (car x) 0)))

If there was a function called print-function-definition that printed
a function's body form, you would see this:

  (defun unexpected ()
     ...)
  => UNEXPECTED

  (print-function-definition 'unexpected)
  => (LET ((X))
       (SETF X '(1 2 3))
       (PRINC X)
       (SETF (CAR X) 0))

  (unexpected)
(1 2 3)
  => 0

  (print-function-definition 'unexpected)
  => (LET ((X))
       (SETF X '(0 2 3))
       (PRINC X)
       (SETF (CAR X) 0))
 

You have written self-modifying code. It would be desirable for the
lisp system to warn or even disallow this, but this is not always easy
to enforce by the lisp system, and not mandated by the Common Lisp
standard.

If you substitute (function-lambda-expression #'unexpected) for
(print-function-definition 'unexpected), this might actually work
approximately as described above, depending on your lisp
implementation.

-- 
Frode Vatvedt Fjeld
From: [Invalid-From-Line]
Subject: Re: unexpected behaviour
Date: 
Message-ID: <c201ml$4uf$1@news.ox.ac.uk>
Thank you! What you say below makes sense.
Could you explain why unexpected behaves differently from expected (which
seems fine)? Thanks.

"Frode Vatvedt Fjeld" <······@cs.uit.no> wrote in message
···················@vserver.cs.uit.no...
> <····@fvdw.com> writes:
>
> > (defun unexpected ()
> >     (let ((x))
> >         (setf x '(1 2 3))
> >         (princ x)              ; prints (1 2 3) on first use of
function,
> > but (0 2 3) after that
> >         (setf (car x) 0)))
>
> If there was a function called print-function-definition that printed
> a function's body form, you would see this:
>
>   (defun unexpected ()
>      ...)
>   => UNEXPECTED
>
>   (print-function-definition 'unexpected)
>   => (LET ((X))
>        (SETF X '(1 2 3))
>        (PRINC X)
>        (SETF (CAR X) 0))
>
>   (unexpected)
> (1 2 3)
>   => 0
>
>   (print-function-definition 'unexpected)
>   => (LET ((X))
>        (SETF X '(0 2 3))
>        (PRINC X)
>        (SETF (CAR X) 0))
>
>
> You have written self-modifying code. It would be desirable for the
> lisp system to warn or even disallow this, but this is not always easy
> to enforce by the lisp system, and not mandated by the Common Lisp
> standard.
>
> If you substitute (function-lambda-expression #'unexpected) for
> (print-function-definition 'unexpected), this might actually work
> approximately as described above, depending on your lisp
> implementation.
>
> -- 
> Frode Vatvedt Fjeld
From: Marco Antoniotti
Subject: Re: unexpected behaviour
Date: 
Message-ID: <3FM0c.66$IJ5.50781@typhoon.nyu.edu>
····@fvdw.com wrote:
> Thank you! What you say below makes sense.
> Could you explain why unexpected behaves differently from expected (which
> seems fine)? Thanks.
> 

Because

	'(1 2 3)

can be seen by the Common Lisp processor (interpreter and/or compiler) 
as a constant expression.

Instead,

	(list 1 2 3)

is not a constant, but a call to the function LIST.

In the first case the CL processor is free to open code the constant, 
hence by modifying it you end up modifying the code of the function 
itself (since the constant list is part of the function cons 
representation).

You just need to be aware of this behavior and be careful about it.  The 
nice thing is that you can use it (as Frode pointed out) as a very nice 
tool to write selfmodifying code, should you wish to do so.

Cheers

Marco

PS. Now go ahead and try the same in Python. :)



> "Frode Vatvedt Fjeld" <······@cs.uit.no> wrote in message
> ···················@vserver.cs.uit.no...
> 
>><····@fvdw.com> writes:
>>
>>
>>>(defun unexpected ()
>>>    (let ((x))
>>>        (setf x '(1 2 3))
>>>        (princ x)              ; prints (1 2 3) on first use of
> 
> function,
> 
>>>but (0 2 3) after that
>>>        (setf (car x) 0)))
>>
>>If there was a function called print-function-definition that printed
>>a function's body form, you would see this:
>>
>>  (defun unexpected ()
>>     ...)
>>  => UNEXPECTED
>>
>>  (print-function-definition 'unexpected)
>>  => (LET ((X))
>>       (SETF X '(1 2 3))
>>       (PRINC X)
>>       (SETF (CAR X) 0))
>>
>>  (unexpected)
>>(1 2 3)
>>  => 0
>>
>>  (print-function-definition 'unexpected)
>>  => (LET ((X))
>>       (SETF X '(0 2 3))
>>       (PRINC X)
>>       (SETF (CAR X) 0))
>>
>>
>>You have written self-modifying code. It would be desirable for the
>>lisp system to warn or even disallow this, but this is not always easy
>>to enforce by the lisp system, and not mandated by the Common Lisp
>>standard.
>>
>>If you substitute (function-lambda-expression #'unexpected) for
>>(print-function-definition 'unexpected), this might actually work
>>approximately as described above, depending on your lisp
>>implementation.
>>
>>-- 
>>Frode Vatvedt Fjeld
> 
> 
> 
From: Marco Antoniotti
Subject: Re: unexpected behaviour
Date: 
Message-ID: <zOM0c.67$IJ5.50793@typhoon.nyu.edu>
BTW.  I should have used the term "literal expression" instead of 
"constant expression".

Cheers

marco



Marco Antoniotti wrote:

> 
> 
> ····@fvdw.com wrote:
> 
>> Thank you! What you say below makes sense.
>> Could you explain why unexpected behaves differently from expected (which
>> seems fine)? Thanks.
>>
> 
> Because
> 
>     '(1 2 3)
> 
> can be seen by the Common Lisp processor (interpreter and/or compiler) 
> as a constant expression.
> 
> Instead,
> 
>     (list 1 2 3)
> 
> is not a constant, but a call to the function LIST.
> 
> In the first case the CL processor is free to open code the constant, 
> hence by modifying it you end up modifying the code of the function 
> itself (since the constant list is part of the function cons 
> representation).
> 
> You just need to be aware of this behavior and be careful about it.  The 
> nice thing is that you can use it (as Frode pointed out) as a very nice 
> tool to write selfmodifying code, should you wish to do so.
> 
> Cheers
> 
> Marco
> 
> PS. Now go ahead and try the same in Python. :)
> 
> 
> 
>> "Frode Vatvedt Fjeld" <······@cs.uit.no> wrote in message
>> ···················@vserver.cs.uit.no...
>>
>>> <····@fvdw.com> writes:
>>>
>>>
>>>> (defun unexpected ()
>>>>    (let ((x))
>>>>        (setf x '(1 2 3))
>>>>        (princ x)              ; prints (1 2 3) on first use of
>>
>>
>> function,
>>
>>>> but (0 2 3) after that
>>>>        (setf (car x) 0)))
>>>
>>>
>>> If there was a function called print-function-definition that printed
>>> a function's body form, you would see this:
>>>
>>>  (defun unexpected ()
>>>     ...)
>>>  => UNEXPECTED
>>>
>>>  (print-function-definition 'unexpected)
>>>  => (LET ((X))
>>>       (SETF X '(1 2 3))
>>>       (PRINC X)
>>>       (SETF (CAR X) 0))
>>>
>>>  (unexpected)
>>> (1 2 3)
>>>  => 0
>>>
>>>  (print-function-definition 'unexpected)
>>>  => (LET ((X))
>>>       (SETF X '(0 2 3))
>>>       (PRINC X)
>>>       (SETF (CAR X) 0))
>>>
>>>
>>> You have written self-modifying code. It would be desirable for the
>>> lisp system to warn or even disallow this, but this is not always easy
>>> to enforce by the lisp system, and not mandated by the Common Lisp
>>> standard.
>>>
>>> If you substitute (function-lambda-expression #'unexpected) for
>>> (print-function-definition 'unexpected), this might actually work
>>> approximately as described above, depending on your lisp
>>> implementation.
>>>
>>> -- 
>>> Frode Vatvedt Fjeld
>>
>>
>>
>>
> 
From: Frode Vatvedt Fjeld
Subject: Re: unexpected behaviour
Date: 
Message-ID: <2h4qt8js6e.fsf@vserver.cs.uit.no>
<····@fvdw.com> writes:

> Could you explain why unexpected behaves differently from expected
> (which seems fine)? Thanks.

You need to understand the difference between '(1 2 3) and (list 1 2
3). Any introductory text on lisp will teach you this.

-- 
Frode Vatvedt Fjeld