From: ramestica
Subject: elisp programming basic question
Date: 
Message-ID: <1155078688.905244.284840@p79g2000cwp.googlegroups.com>
I have just started doing some e/lisp programming and got into
something I cannot understand.

The function below will return 3, 5, 7 and so on, when executed again
and again. The statement (setq stack '(1 2 3 4)) seems to happen only
once, when I execute the function the first time. But after that the
stack variable is not set again to '(1 2 3 4).

My emacs version is 21.3.1

Any hints?

many thanks,
 Rodrigo

(defun test ()
  (setq stack '(1 2 3 4))
  (setcar stack (+ (car (cdr stack)) (car stack))))

From: Pascal Bourguignon
Subject: Re: elisp programming basic question
Date: 
Message-ID: <87fyg6ahts.fsf@thalassa.informatimago.com>
"ramestica" <·········@yahoo.com> writes:

> I have just started doing some e/lisp programming and got into
> something I cannot understand.
>
> The function below will return 3, 5, 7 and so on, when executed again
> and again. The statement (setq stack '(1 2 3 4)) seems to happen only
> once, when I execute the function the first time. But after that the
> stack variable is not set again to '(1 2 3 4).

This is because you are modifying the literal constant (1 2 3 4).

> My emacs version is 21.3.1
>
> Any hints?
>
> many thanks,
>  Rodrigo
>
> (defun test ()
>   (setq stack '(1 2 3 4))
>   (setcar stack (+ (car (cdr stack)) (car stack))))


(defun test ()
   (setq stack '(1 2 3 4))
   (insert (format "stack=%S\n" stack))
   (setcar stack (+ (car (cdr stack)) (car stack))))
C-x C-e

(test) C-u C-x C-e -->
stack=(1 2 3 4)
3

(test) C-u C-x C-e -->
stack=(3 2 3 4)
5



You don't say what you want to archieve, so it's hard to tell what the
correct solution would be.  Perhaps something like:

(require 'cl)
(lexical-let ((a 1) (b 2))
   (defun test ()
     (setf a (+ a b))))

(list (test) (test) (test)) --> (3 5 7) 



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

WARNING: This product attracts every other piece of matter in the
universe, including the products of other manufacturers, with a
force proportional to the product of the masses and inversely
proportional to the distance between them.
From: ramestica
Subject: Re: elisp programming basic question
Date: 
Message-ID: <1155089642.755748.223690@b28g2000cwb.googlegroups.com>
Hi Pascal,

what I'm trying to achieve with this simple test is to show what is
that I cannot understand. But I did not really explicitly stated in my
original posting. I expect this code to always return 3, however, it
does not work like that :-(

I cannot understand what's happening with (setq stack '(1 2 3 4)) after
the first time the function has been invoked.

Rodrigo

Pascal Bourguignon wrote:
> "ramestica" <·········@yahoo.com> writes:
>
> > I have just started doing some e/lisp programming and got into
> > something I cannot understand.
> >
> > The function below will return 3, 5, 7 and so on, when executed again
> > and again. The statement (setq stack '(1 2 3 4)) seems to happen only
> > once, when I execute the function the first time. But after that the
> > stack variable is not set again to '(1 2 3 4).
>
> This is because you are modifying the literal constant (1 2 3 4).
>
> > My emacs version is 21.3.1
> >
> > Any hints?
> >
> > many thanks,
> >  Rodrigo
> >
> > (defun test ()
> >   (setq stack '(1 2 3 4))
> >   (setcar stack (+ (car (cdr stack)) (car stack))))
>
>
> (defun test ()
>    (setq stack '(1 2 3 4))
>    (insert (format "stack=%S\n" stack))
>    (setcar stack (+ (car (cdr stack)) (car stack))))
> C-x C-e
>
> (test) C-u C-x C-e -->
> stack=(1 2 3 4)
> 3
>
> (test) C-u C-x C-e -->
> stack=(3 2 3 4)
> 5
>
>
>
> You don't say what you want to archieve, so it's hard to tell what the
> correct solution would be.  Perhaps something like:
>
> (require 'cl)
> (lexical-let ((a 1) (b 2))
>    (defun test ()
>      (setf a (+ a b))))
>
> (list (test) (test) (test)) --> (3 5 7)
>
>
>
> --
> __Pascal Bourguignon__                     http://www.informatimago.com/
>
> WARNING: This product attracts every other piece of matter in the
> universe, including the products of other manufacturers, with a
> force proportional to the product of the masses and inversely
> proportional to the distance between them.
From: wolfjb
Subject: Re: elisp programming basic question
Date: 
Message-ID: <1155092238.056856.191820@m79g2000cwm.googlegroups.com>
ramestica wrote:

[...snip...]
> > > The function below will return 3, 5, 7 and so on, when executed again
> > > and again. The statement (setq stack '(1 2 3 4)) seems to happen only
> > > once, when I execute the function the first time. But after that the
> > > stack variable is not set again to '(1 2 3 4).
> >
> > This is because you are modifying the literal constant (1 2 3 4).
> >
[...snip...]

I'm probably not expert enough to explain the difference but

'(1 2 3 4)

is not the same as

(list 1 2 3 4)

The 'literal constant' mentioned is a good hint where to start looking
though. Try changing your test function to this:

 (defun test ()
   (setq stack (list 1 2 3 4))
   (insert (format "stack=%S\n" stack))
   (setcar stack (+ (car (cdr stack)) (car stack))))

which always returns 3 for me.
From: Barry Margolin
Subject: Re: elisp programming basic question
Date: 
Message-ID: <barmar-A46F32.00391009082006@comcast.dca.giganews.com>
In article <························@b28g2000cwb.googlegroups.com>,
 "ramestica" <·········@yahoo.com> wrote:

> Hi Pascal,
> 
> what I'm trying to achieve with this simple test is to show what is
> that I cannot understand. But I did not really explicitly stated in my
> original posting. I expect this code to always return 3, however, it
> does not work like that :-(
> 
> I cannot understand what's happening with (setq stack '(1 2 3 4)) after
> the first time the function has been invoked.
> 

What's happening is that each time you invoke the function, the setcar 
actually modifies the list in the code of the function.  So that line 
has been turned into (setq stack '(3 2 3 4)).

Change the line to (setq stack (list 1 2 3 4)) and it will create a 
fresh list each time, rather than using the literal list in the source 
code.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal Bourguignon
Subject: Re: elisp programming basic question
Date: 
Message-ID: <873bc6a8cw.fsf@thalassa.informatimago.com>
"ramestica" <·········@yahoo.com> writes:
> what I'm trying to achieve with this simple test is to show what is
> that I cannot understand. But I did not really explicitly stated in my
> original posting. I expect this code to always return 3, however, it
> does not work like that :-(

If you expect some definite behavior then you should avoid modifying
literal objects (this invokes undefined behavior).



If you want to still increment the car of a list, use a list newly
consed everytime you call the function:

(defun test ()
  (let ((stack (list 1 2 3 4)))
     (incf (car stack) (cadr stack))))


If you just want to write a pure function, just avoid modifying the
places (no setf (no setcar), no incf, etc), then you can use literal
objects:

(defun test ()
  (let ((stack '(1 2 3 4)))
     (+ (car stack) (cadr stack)))) 


In both cases, avoid assigning to undeclared global variables. Better:

- use a lexical variable (LET),

- or if you need a global variable, declare it with defvar, or defparameter,
  before modifying it.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.
From: Sidney Markowitz
Subject: Re: elisp programming basic question
Date: 
Message-ID: <44d91c62$0$34527$742ec2ed@news.sonic.net>
ramestica wrote, On 9/8/06 11:11 AM:
> The statement (setq stack '(1 2 3 4)) seems to happen only
> once, when I execute the function the first time.
[...]
> (defun test ()
>   (setq stack '(1 2 3 4))
>   (setcar stack (+ (car (cdr stack)) (car stack))))


No, what is happening is storage is allocated for the list '(1 2 3 4) when the
function is byte-compiled, and each time the function is called the local
variable 'stack' is allocated again and is set to point to that storage. When
you call setcar, the number you compute is smashed into the first element
location of that list.

Thus, the next time you call test, stack is set to point to a list that has
had its first element changed.

The result is that every time you call test the first element of the list is
incremented by the second element of the list, which is the number 2.

-- 
    Sidney Markowitz
    http://www.sidney.com
From: ramestica
Subject: Re: elisp programming basic question
Date: 
Message-ID: <1155089059.304394.170320@n13g2000cwa.googlegroups.com>
Sidney, thanks for the reply

I'm still confused. I'm sure that there is  something to the 'storage'
that I'm not understanding well; but leaving that aside, are you saying
that the second time the function is invoked the statement (setq stack
'(1 2 3 4)) is practically doing nothing? That's difficult to
understand.

I just tried the same thing from a clisp shell (replaced setcar by a
pertinent code) and here it works in the way I was expecting, the
function always return 3.

thanks again,
 Rodrigo

Sidney Markowitz wrote:
> ramestica wrote, On 9/8/06 11:11 AM:
> > The statement (setq stack '(1 2 3 4)) seems to happen only
> > once, when I execute the function the first time.
> [...]
> > (defun test ()
> >   (setq stack '(1 2 3 4))
> >   (setcar stack (+ (car (cdr stack)) (car stack))))
>
>
> No, what is happening is storage is allocated for the list '(1 2 3 4) when the
> function is byte-compiled, and each time the function is called the local
> variable 'stack' is allocated again and is set to point to that storage. When
> you call setcar, the number you compute is smashed into the first element
> location of that list.
>
> Thus, the next time you call test, stack is set to point to a list that has
> had its first element changed.
>
> The result is that every time you call test the first element of the list is
> incremented by the second element of the list, which is the number 2.
> 
> -- 
>     Sidney Markowitz
>     http://www.sidney.com
From: Pascal Bourguignon
Subject: Re: elisp programming basic question
Date: 
Message-ID: <877j1ia8lx.fsf@thalassa.informatimago.com>
"ramestica" <·········@yahoo.com> writes:

> Sidney, thanks for the reply
>
> I'm still confused. I'm sure that there is  something to the 'storage'
> that I'm not understanding well; but leaving that aside, are you saying
> that the second time the function is invoked the statement (setq stack
> '(1 2 3 4)) is practically doing nothing? That's difficult to
> understand.


I'll explain in terms of Common Lisp, but emacs lisp behaves similarly.

#\' is a reader macro character.  When lisp reads the characters: "'(1 2 3 4)"
the reader macro function for #\' reads the following object, 
that is, it reads: "(1 2 3 4)".

   #\( is a reader macro character.  When lisp reads it, the reader macro
   function for #\( reads objects until it finds a #\) character, and
   builds a list with them.  Therefore it will call READ four times, and
   execute the equivalent of: (cons 1 (cons 2 (cons 3 (cons 4 nil))))
   to build the list corresponding to "(1 2 3 4)".  This newly consed list 
   is the returned by the #\( reader macro function.


Then the reader macro function for #\' builds the quote form, with the
equivalent of:  (cons (quote quote) (cons object nil)), object being
the object read above, that is, the (1 2 3 4) list built above.

Then, READ returns that form: (quote (1 2 3 4))

    You can try:

        (progn (princ "( ")
               (mapc 'print (read-from-string "'(1 2 3 4)"))
               (princ " )")
               (values))

Next, when EVAL  evaluates that form, it notices that QUOTE is a
special operator and do what this special operator must do, that is,
return the second element of that form as is, namely the very same
list (1 2 3 4) built above by the reader macro function for #\(.

In (setq stack '(1 2 3 4)), this is that list that is bound to the
variable stack.  Everytime you execute it.

The second expression in the body of test modifies that list, changing
the car of its first cons.


Here is the source cons tree built when lisp reads the (defun test ...) 
form:

+-----------------------------------------------------------------------+
|    (defun test ()                                                     |
|        (setq stack '(1 2 3 4))                                        |
|         (setcar stack (+ (car (cdr stack)) (car stack))))             |
|                                                                       |
|                                                                       |
| +---+---+   +-------+                                                 |
| |cdr|car|-->| DEFUN |                                                 |
| +---+---+   +-------+                                                 |
|   |                                                                   |
|   v                                                                   |
| +---+---+   +------+                                                  |
| | * | * |-->| TEST |                                                  |
| +---+---+   +------+                                                  |
|   |                                                                   |
|   v                                                                   |
| +---+---+                                                             |
| | * |NIL|                                                             |
| +---+---+                                                             |
|   |                                                                   |
|   v                                                                   |
| +---+---+   +---+---+   +------+                                      |
| | * | * |-->| * | * |-->| SETQ |                                      |
| +---+---+   +---+---+   +------+                                      |
|   |           |                                                       |
|   |           v                                                       |
|   |         +---+---+   +-------+                                     |
|   |         | * | * |-->| STACK |                                     |
|   |         +---+---+   +-------+                                     |
|   |           |                                                       |
|   |           v                                                       |
|   |         +---+---+   +---+---+   +-------+                         |
|   |         |NIL| * |-->| * | * |-->| QUOTE |                         |
|   |         +---+---+   +---+---+   +-------+                         |
|   |                       |                                           |
|   |                       |        [stack]                            |
|   |                       |           |                               |
|   |                       v           v                               |
|   |                     +---+---+   +---+---+   +---+                 |
|   |                     |NIL| * |-->| * | * |-->| 1 |                 |
|   |                     +---+---+   +---+---+   +---+                 |
|   |                                   |                               |
|   |                                   v                               |
|   |                                 +---+---+   +---+                 |
|   |                                 | * | * |-->| 2 |                 |
|   |                                 +---+---+   +---+                 |
|   |                                   |                               |
|   |                                   v                               |
|   |                                 +---+---+   +---+                 |
|   |                                 | * | * |-->| 3 |                 |
|   |                                 +---+---+   +---+                 |
|   |                                   |                               |
|   |                                   v                               |
|   |                                 +---+---+   +---+                 |
|   |                                 |NIL| * |-->| 4 |                 |
|   |                                 +---+---+   +---+                 |
|   v                                                                   |
| +---+---+   +---+---+   +--------+                                    |
| |NIL| * |-->| * | * |-->| SETCAR |                                    |
| +---+---+   +---+---+   +--------+                                    |
|               |                                                       |
|               v                                                       |
|             +---+---+   +-------+                                     |
|             | * | * |-->| STACK |                                     |
|             +---+---+   +-------+                                     |
|               |                                                       |
|               v                                                       |
|             +---+---+   +---+---+   +---+                             |
|             |NIL| * |-->| * | * |-->| + |                             |
|             +---+---+   +---+---+   +---+                             |
|                           |                                           |
|                           v                                           |
|                         +---+---+   +---+---+   +-----+               |
|                         | * | * |-->| * | * |-->| CAR |               |
|                         +---+---+   +---+---+   +-----+               |
|                           |           |                               |
|                           |           v                               |
|                           |         +---+---+   +---+---+   +-----+   |
|                           |         |NIL| * |-->| * | * |-->| CDR |   |
|                           |         +---+---+   +---+---+   +-----+   |
|                           |                       |                   |
|                           |                       v                   |
|                           |                     +---+---+   +-------+ |
|                           |                     |NIL| * |-->| STACK | |
|                           |                     +---+---+   +-------+ |
|                           v                                           |
|                         +---+---+   +---+---+   +-----+               |
|                         |NIL| * |-->| * | * |-->| CAR |               |
|                         +---+---+   +---+---+   +-----+               |
|                                       |                               |
|                                       v                               |
|                                     +---+---+   +-------+             |
|                                     |NIL| * |-->| STACK |             |
|                                     +---+---+   +-------+             |
+-----------------------------------------------------------------------+


After (setq stack '(1 2 3 4)), the variable stack points to the cons
cell indicated by [stack]--> in the above diagram.

After (setcar stack (+ ...))  the only thing that's changed, is the
car of the cons cell pointed to by stack:

+-------------------+
|                   |
| [stack]           |
|   |               |
|   v               |
| +---+---+   +---+ |
| |cdr|car|-->| 3 | |
| +---+---+   +---+ |
|   |               |
|   v               |
| +---+---+   +---+ |
| | * | * |-->| 2 | |
| +---+---+   +---+ |
|   |               |
|   v               |
| +---+---+   +---+ |
| | * | * |-->| 3 | |
| +---+---+   +---+ |
|   |               |
|   v               |
| +---+---+   +---+ |
| |NIL| * |-->| 4 | |
| +---+---+   +---+ |
+-------------------+


When you execute test again, stack is assigned again the same cons
cell, but it still has the new value in its car slot.

After (setcar stack (+ ...))  the only thing that's changed, is the
car of the cons cell pointed to by stack:

+-------------------+
|                   |
| [stack]           |
|   |               |
|   v               |
| +---+---+   +---+ |
| |cdr|car|-->| 5 | |
| +---+---+   +---+ |
|   |               |
|   v               |
| +---+---+   +---+ |
| | * | * |-->| 2 | |
| +---+---+   +---+ |
|   |               |
|   v               |
| +---+---+   +---+ |
| | * | * |-->| 3 | |
| +---+---+   +---+ |
|   |               |
|   v               |
| +---+---+   +---+ |
| |NIL| * |-->| 4 | |
| +---+---+   +---+ |
+-------------------+


etc...


> I just tried the same thing from a clisp shell (replaced setcar by a
> pertinent code) and here it works in the way I was expecting, the
> function always return 3.

I doubt it.  Contrarily to emacs, clisp will even display how the
source of the program is modified:


[17]> (defun test ()
        (setq stack '(1 2 3 4))
        (setf (car stack) (+ (car (cdr stack)) (car stack))))
TEST
[18]> (function-lambda-expression (function test))
(LAMBDA NIL (DECLARE (SYSTEM::IN-DEFUN TEST))
 (BLOCK TEST (SETQ STACK '(1 2 3 4))
  (SETF (CAR STACK) (+ (CAR (CDR STACK)) (CAR STACK))))) ;
#(NIL NIL NIL NIL ((DECLARATION XLIB::CLX-VALUES VALUES OPTIMIZE DECLARATION))) ;
TEST
[19]> (test)
3
[20]> (function-lambda-expression (function test))
(LAMBDA NIL (DECLARE (SYSTEM::IN-DEFUN TEST))
 (BLOCK TEST (SETQ STACK '(3 2 3 4))
  (SETF (CAR STACK) (+ (CAR (CDR STACK)) (CAR STACK))))) ;
#(NIL NIL NIL NIL ((DECLARATION XLIB::CLX-VALUES VALUES OPTIMIZE DECLARATION))) ;
TEST
[21]> (test)
5
[22]> (function-lambda-expression (function test))
(LAMBDA NIL (DECLARE (SYSTEM::IN-DEFUN TEST))
 (BLOCK TEST (SETQ STACK '(5 2 3 4))
  (SETF (CAR STACK) (+ (CAR (CDR STACK)) (CAR STACK))))) ;
#(NIL NIL NIL NIL ((DECLARATION XLIB::CLX-VALUES VALUES OPTIMIZE DECLARATION))) ;
TEST
[23]> 



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

"What is this talk of "release"?  Klingons do not make software
"releases".  Our software "escapes" leaving a bloody trail of
designers and quality assurance people in its wake."
From: Sidney Markowitz
Subject: Re: elisp programming basic question
Date: 
Message-ID: <44d956bc$0$34534$742ec2ed@news.sonic.net>
ramestica wrote, On 9/8/06 2:04 PM:
> are you saying that the second time
> the function is invoked the statement (setq stack
> '(1 2 3 4)) is practically doing nothing? That's difficult to
> understand.

wolfjb has the right idea in his post.

I'll try to explain it in more detail. I apologize in advance if I go over
parts that you already know, but I want to make sure I cover whatever part is
confusing you.

You give the source code of the function 'test' to the elisp byte-compiler,
and it converts that into a data structure that contains the byte code version
of that function. In that byte code are instructions about what the function
is supposed to do and a data object, which is a list that contains '(1 2 3 4).

Every time you call the function (test), the byte-code interpreter starts
doing what the byte codes say to do.

The first thing it does is allocate some memory space for the local variable
that is named 'stack'. The next thing it does is the (setq stack ... )
function which says to take a pointer to the data object, which has been
compiled to contain the list '(1 2 3 4), and place that pointer in the newly
allocated 'stack' variable.

Those steps are done every time you invoke (test). The important point here is
that because you said '(1 2 3 4) instead of (list 1 2 3 4), a new list object
is not created every time you invoke (test). The list object is created only
once, when you compile the test function.

Then, when you do the setcar, you replace the 1 in '(1 2 3 4) with a 3, so the
object now contains '(3 2 3 4).

When (test) finishes, it releases the memory allocated for the variable
'stack'. But that memory only contained a pointer to the list object. The list
object itself is still sitting there in the byte code of (test) and it still
contains '(3 2 3 4). The second time you invoke (test), a new 'stack' variable
is allocated and the setq stores a pointer to the list object in it. Now stack
points to a list object that contains '(3 2 3 4), and the next step turns that
into '(5 2 3 4).

If you use (list 1 2 3 4) instead of '(1 2 3 4), the list object is created
anew each time (test) is called, so changing the first element in one call has
no effect that can be seen in the next call.

-- 
    Sidney Markowitz
    http://www.sidney.com
From: ramestica
Subject: Re: elisp programming basic question
Date: 
Message-ID: <1155245473.944232.8890@h48g2000cwc.googlegroups.com>
I really appreaciate all these replies, this is a lot of information
for someone just starting.

If I'm not wrong then the (setq stack '(1 2 3 4)) expression in the
original test function is acting like what is call in other languages a
static variable definition .  I mean, in c I would expect that a
function like this:

int test (void) {static int i = 1; return ++i;}

it should, indeed, return an increasing integer everytime the function
is called again, starting from 2. Which is similar to the outcome of
the test elisp function.

Pascal, the way I coded the test function in clisp was like this

(defun test ()
  (setq stack '(1 2 3 4))
  (setq stack (cons (+ (car (cdr stack)) (car stack)) (cdr stack)))
  (car stack))

And this one always returns 3, your version (based on setf) does work
indeed as my original one. I have read The Roots of Lisp and the first
pages of On Lisp, therefore, my lisp 'vocabulary' is very short, that's
why I did not try setf.

The net result is that my 'static' interpretation of (setq stack '(1 2
3 4)) is not really okay. Why is that 'test' as shown above does not
increase the car of stack? It seems that the second setq is creating a
temporal storage for stack.

All in all, many thanks for the help. 
 Rodrigo
From: Pascal Bourguignon
Subject: Re: elisp programming basic question
Date: 
Message-ID: <877j1gmf1i.fsf@thalassa.informatimago.com>
"ramestica" <·········@yahoo.com> writes:

> I really appreaciate all these replies, this is a lot of information
> for someone just starting.
>
> If I'm not wrong then the (setq stack '(1 2 3 4)) expression in the
> original test function is acting like what is call in other languages a
> static variable definition .  I mean, in c I would expect that a
> function like this:
>
> int test (void) {static int i = 1; return ++i;}
>
> it should, indeed, return an increasing integer everytime the function
> is called again, starting from 2. Which is similar to the outcome of
> the test elisp function.
>
> Pascal, the way I coded the test function in clisp was like this
>
> (defun test ()
>   (setq stack '(1 2 3 4))
>   (setq stack (cons (+ (car (cdr stack)) (car stack)) (cdr stack)))
>   (car stack))

SETF on normal variables is the same as SETQ:

[7]> (macroexpand '(setf stack '(1 2 3 4)))
(SETQ STACK '(1 2 3 4)) ;
T


> And this one always returns 3, your version (based on setf) does work
> indeed as my original one. I have read The Roots of Lisp and the first
> pages of On Lisp, therefore, my lisp 'vocabulary' is very short, that's
> why I did not try setf.
>
> The net result is that my 'static' interpretation of (setq stack '(1 2
> 3 4)) is not really okay. 

A better analogy for

    (defun test ()
      (setq stack '(1 2 3 4))
      (setcar stack (+ (car (cdr stack)) (car stack))))

in C would be:

    #include <stdio.h>

    char test(void){
       char* stack="1234";
       stack[0]=stack[1]+stack[0];
       return(stack[0]);}

    int main(void){
        printf("test()=%d\n",test());
        printf("test()=%d\n",test());
        printf("test()=%d\n",test());
        return(0);}



[···@thalassa tmp]$ gcc -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wredundant-decls -Winline -Wcomments -Wtrigraphs -Wimport -Wundef -Wendif-labels -g -o a a.c 
a.c: In function `test':
a.c:4: warning: initialization discards qualifiers from pointer target type
[···@thalassa tmp]$ ./a
Segmentation fault


The segmentation fault occurs because you're trying to modify the
literal value "1234".


However, you can ask gcc to make it writable:

[···@thalassa tmp]$ gcc  -fwritable-strings -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wredundant-decls -Winline -Wcomments -Wtrigraphs -Wimport -Wundef -Wendif-labels -g -o a a.c
[···@thalassa tmp]$ ./a
test()=99
test()=-107
test()=-57


Common Lisp implementations are allowed to behave as they want (and
are even allowed to provide such a flag, even if few do).  



> Why is that 'test' as shown above does not
> increase the car of stack? 

Because you are not modifying any of the places used in the expressions
assigned to stack!

   (setq stack (cons (+ (car (cdr stack)) (car stack)) (cdr stack)))

The functions, CONS, +, CAR, and CDR are pure function, without any
side effect.


> It seems that the second setq is creating a
> temporal storage for stack.

That's what CONS does: it CONStructs a new pair.


> All in all, many thanks for the help. 
>  Rodrigo


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

The world will now reboot.  don't bother saving your artefacts.
From: ramestica
Subject: Re: elisp programming basic question
Date: 
Message-ID: <1155248329.828389.279990@h48g2000cwc.googlegroups.com>
Pascal Bourguignon wrote:
> Because you are not modifying any of the places used in the expressions
> assigned to stack!
>
>    (setq stack (cons (+ (car (cdr stack)) (car stack)) (cdr stack)))
>
> The functions, CONS, +, CAR, and CDR are pure function, without any
> side effect.

I can understand that cons has no side effects, but at the same time I
understand that setq above it should have a side effect, or? I mean,
setq should modify the place where stack is pointing to. A place I'm
assuming is the same one as the fisrt setq, (setq stack '(1 2 3 4)).
However, it seems that the first setq points to somewhere and the
second one points to an other place.

In the expression shown above, why is that you said that I'm not
modifying a place assigned to stack?

Rodrigo
From: Pascal Bourguignon
Subject: Re: elisp programming basic question
Date: 
Message-ID: <87vep0kz25.fsf@thalassa.informatimago.com>
"ramestica" <·········@yahoo.com> writes:

> Pascal Bourguignon wrote:
>> Because you are not modifying any of the places used in the expressions
>> assigned to stack!
>>
>>    (setq stack (cons (+ (car (cdr stack)) (car stack)) (cdr stack)))
>>
>> The functions, CONS, +, CAR, and CDR are pure function, without any
>> side effect.
>
> I can understand that cons has no side effects, but at the same time I
> understand that setq above it should have a side effect, or? I mean,
> setq should modify the place where stack is pointing to. A place I'm
> assuming is the same one as the fisrt setq, (setq stack '(1 2 3 4)).
> However, it seems that the first setq points to somewhere and the
> second one points to an other place.
>
> In the expression shown above, why is that you said that I'm not
> modifying a place assigned to stack?

I've not said that.


   Because you are not modifying any of the places used in the expressions
   assigned to stack!

   (setq stack (cons (+ (car (cdr stack)) (car stack)) (cdr stack)))


What more can I say?


Does this modify stack or anything else?

                             (cdr stack)



Does this modify stack or anything else?

                       (car (cdr stack))



Does this modify stack or anything else? 

                                         (car stack)


Does this modify stack or anything else? 
 
                    (+ (car (cdr stack)) (car stack))


Does this modify stack or anything else? 

                                                      (cdr stack)


Does this modify stack or anything else? 

              (cons (+ (car (cdr stack)) (car stack)) (cdr stack))


If you answered NO to every question above, then  what else can you
answer to the question whether you're modifying any of the places used
in the expression 

              (cons (+ (car (cdr stack)) (car stack)) (cdr stack))

?


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d? s++:++ a+ C+++ UL++++ P--- L+++ E+++ W++ N+++ o-- K- w--- 
O- M++ V PS PE++ Y++ PGP t+ 5+ X++ R !tv b+++ DI++++ D++ 
G e+++ h+ r-- z? 
------END GEEK CODE BLOCK------
From: Sidney Markowitz
Subject: Re: elisp programming basic question
Date: 
Message-ID: <44dbc393$0$34491$742ec2ed@news.sonic.net>
ramestica wrote, On 11/8/06 10:18 AM:
> setq should modify the place where stack is pointing to. A place I'm
> assuming is the same one as the fisrt setq, (setq stack '(1 2 3 4)).
> However, it seems that the first setq points to somewhere and the
> second one points to an other place.

This might help clarify it for you:

In C terms, a symbol in Lisp is similar to a pointer variable. When you
evaluate (setq stack ...) you are assigning a pointer, not a value.

(setq stack '(1 2 3 4))

stores a pointer to a data structure that is created at read time (you can
think of that as compile time), which contains the list (1 2 3 4)

(setq stack (cons (car ... etc. ...)))

creates a new data structure in the call to cons and stores a pointer to that
brand new data structure in the value slot of the symbol 'stack'. That data
structure is something like a static variable in C, but 'stack' is more like
local variable.

(setf (car stack) ... )

is a special form that stores a value after doing some dereferencing. It is
similar to using in C

  *stack = ...

Consider the difference in C between

 static int constlist[] = {1, 2, 3, 4};
 int * stack = constlist;
 stack = function_that_returns_an_int_array_pointer(stack);

and

 static int constlist[] = {1, 2, 3, 4};
 int * stack = constlist;
 *stack = 3;

-- 
    Sidney Markowitz
    http://www.sidney.com
From: Brian Downing
Subject: Re: elisp programming basic question
Date: 
Message-ID: <XrCdnSF8q6j3X0bZnZ2dnUVZ_oCdnZ2d@insightbb.com>
In article <··············@thalassa.informatimago.com>,
Pascal Bourguignon  <···@informatimago.com> wrote:
> Common Lisp implementations are allowed to behave as they want (and
> are even allowed to provide such a flag, even if few do).  

Some even produce warnings about this:

SBCL> (defun test ()
	(let ((stack '(1 2 3 4)))
	  (setf (car stack) (+ (car (cdr stack)) (car stack)))))
; in: LAMBDA NIL
;     (SETF (COMMON-LISP:CAR SBCL::STACK)
;           (+ (COMMON-LISP:CAR (CDR SBCL::STACK)) (COMMON-LISP:CAR SBCL::STACK)))
; ==>
;   (SB-KERNEL:%RPLACA SBCL::STACK
;                      (+ (COMMON-LISP:CAR (CDR SBCL::STACK))
;                         (COMMON-LISP:CAR SBCL::STACK)))
; 
; caught WARNING:
;   Destructive function SB-KERNEL:%RPLACA called on constant data.
;   See also:
;     The ANSI Standard, Special Operator QUOTE
;     The ANSI Standard, Section 3.2.2.3
; 
; compilation unit finished
;   caught 1 WARNING condition

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net>