From: surendra
Subject: setf problem
Date: 
Message-ID: <cmi43j$b7e$1@news.asu.edu>
Hi,
   I am playing with some LISP code and I am facing some peculiar 
problem with the use of push and setf function.

(defun NEW-PROP-LEVEL (plan-graph)
   (first (plan-graph-proposition-levels plan-graph)))

(defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
    (setf (new-prop-level plan-graph) new-value))

(defun push-new-prop (prop plan-graph)
       (push prop (new-prop-level plan-graph)))

In the above code, the "plan-graph" is a structure and it has a field 
named "proposition-levels".

I want to insert a new proposition into the proposition levels field, 
which is initialized as

(proposition-levels (list nil))

The problem which I am facing in this code is that I am first of all 
forced to use the method, secondly it is going into an infinite loop.

I am able to make this code work only by changing the method to this:

(defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
   (setf (first (plan-graph-proposition-levels plan-graph)) new-value))

Can anyone explain to me the reason for this behavior, and if possible 
direct me to books/link where I can find more information on 
understanding it.

Thanks in advance,
Surendra Singhi

From: surendra
Subject: Re: setf problem
Date: 
Message-ID: <cmi4sf$b8u$1@news.asu.edu>
surendra wrote:

> Hi,
>   I am playing with some LISP code and I am facing some peculiar problem 
> with the use of push and setf function.
> 
> (defun NEW-PROP-LEVEL (plan-graph)
>   (first (plan-graph-proposition-levels plan-graph)))
> 
> (defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
>    (setf (new-prop-level plan-graph) new-value))
> 
> (defun push-new-prop (prop plan-graph)
>       (push prop (new-prop-level plan-graph)))
> 
> In the above code, the "plan-graph" is a structure and it has a field 
> named "proposition-levels".
> 
> I want to insert a new proposition into the proposition levels field, 
> which is initialized as
> 
> (proposition-levels (list nil))
> 
> The problem which I am facing in this code is that I am first of all 
> forced to use the method, secondly it is going into an infinite loop.
> 
> I am able to make this code work only by changing the method to this:
> 
> (defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
>   (setf (first (plan-graph-proposition-levels plan-graph)) new-value))
> 
> Can anyone explain to me the reason for this behavior, and if possible 
> direct me to books/link where I can find more information on 
> understanding it.
> 

In fact I am facing this problem at multiple places, whenever I want to 
modify the value of some field stored in a structure using setf, I am 
getting this error in clisp.
How should I work around it? What is the neat solution to it?

Thanks in advance,
Surendra Singhi
From: Brian Downing
Subject: Re: setf problem
Date: 
Message-ID: <VK0jd.575895$8_6.318726@attbi_s04>
In article <············@news.asu.edu>,
surendra  <·········@netscape.net> wrote:
> (defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
>     (setf (new-prop-level plan-graph) new-value))
> 
> The problem which I am facing in this code is that I am first of all 
> forced to use the method, secondly it is going into an infinite loop.

Well, you're writing this setf method so that you can write something
like:

(setf (new-prop-level plan-graph) new-value)

...right?  And in the definition of the setf function, you are calling:

(setf (new-prop-level plan-graph) new-value)

See the problem?

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: surendra
Subject: Re: setf problem
Date: 
Message-ID: <cmibki$cid$1@news.asu.edu>
Brian Downing wrote:

> In article <············@news.asu.edu>,
> surendra  <·········@netscape.net> wrote:
> 
>>(defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
>>    (setf (new-prop-level plan-graph) new-value))
>>
>>The problem which I am facing in this code is that I am first of all 
>>forced to use the method, secondly it is going into an infinite loop.
> 
> 
> Well, you're writing this setf method so that you can write something
> like:
> 
> (setf (new-prop-level plan-graph) new-value)
> 
> ...right?  And in the definition of the setf function, you are calling:
> 
> (setf (new-prop-level plan-graph) new-value)
> 
> See the problem?
> 
> -bcd

I see that but why does (setf (new-prop-level plan-graph) new-value) 
translates to (SETF NEW-PROP-LEVEL). I didn't understand that part.
Shouldn't (new-prop-level plan-graph) be first evaluated and whatever 
address that evaluates to be modified?

Surendra
From: Marco Baringer
Subject: Re: setf problem
Date: 
Message-ID: <m23bznm8m7.fsf@bese.it>
surendra <·········@netscape.net> writes:

> I see that but why does (setf (new-prop-level plan-graph) new-value) 
> translates to (SETF NEW-PROP-LEVEL). I didn't understand that part.
> Shouldn't (new-prop-level plan-graph) be first evaluated and whatever 
> address that evaluates to be modified?

no, setf is a macro not a function and the first argument to setf is a
place, not a value. see
http://www.lisp.org/HyperSpec/Body/mac_setfcm_psetf.html and
http://www.lisp.org/HyperSpec/Body/sec_5-1-2.html for details.

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen
From: Pascal Bourguignon
Subject: Re: setf problem
Date: 
Message-ID: <87vfcjozwa.fsf@naiad.informatimago.com>
surendra <·········@netscape.net> writes:

> Brian Downing wrote:
> 
> > In article <············@news.asu.edu>,
> > surendra  <·········@netscape.net> wrote:
> >
> >>(defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
> >>    (setf (new-prop-level plan-graph) new-value))
> >>
> >> The problem which I am facing in this code is that I am first of
> >> all forced to use the method, secondly it is going into an infinite
> >> loop.
> > Well, you're writing this setf method so that you can write something
> > like:
> > (setf (new-prop-level plan-graph) new-value)
> > ...right?  And in the definition of the setf function, you are
> > calling:
> > (setf (new-prop-level plan-graph) new-value)
> > See the problem?
> > -bcd
> 
> I see that but why does (setf (new-prop-level plan-graph) new-value)
> translates to (SETF NEW-PROP-LEVEL). I didn't understand that part.
> Shouldn't (new-prop-level plan-graph) be first evaluated and whatever
> address that evaluates to be modified?

But this function:

(defun NEW-PROP-LEVEL (plan-graph)
   (first (plan-graph-proposition-levels plan-graph)))

returns a value, not an address!


So, when you write:

    (setf (new-prop-level plan-graph) new-value)

setf cannot just evaluate (new-prop-level plan-graph), because the
only thing it would get would be a value, and it could not do anything
with it.  Instead, it analyses '(new-prop-level plan-graph), see that
there exists some (setf new-prop-level) function and call it to do the
job.


(defun push-new-prop (prop plan-graph)
       (push prop (new-prop-level plan-graph)))

Note that push is macro, not a function.  There's a reason for that!
You cannot modify the pro-level of plan-graph from some value
new-prop-level returns.  You need to write a primitive writer method
somewhere.




-- 
__Pascal Bourguignon__
From: surendra
Subject: Re: setf problem
Date: 
Message-ID: <cmimdb$lnh$1@news.asu.edu>
Pascal Bourguignon wrote:

> surendra <·········@netscape.net> writes:
> 
> 
>>Brian Downing wrote:
>>
>>
>>>In article <············@news.asu.edu>,
>>>surendra  <·········@netscape.net> wrote:
>>>
>>>
>>>>(defmethod (SETF NEW-PROP-LEVEL) (new-value (plan-graph plan-graph))
>>>>   (setf (new-prop-level plan-graph) new-value))
>>>>
>>>>The problem which I am facing in this code is that I am first of
>>>>all forced to use the method, secondly it is going into an infinite
>>>>loop.
>>>
>>>Well, you're writing this setf method so that you can write something
>>>like:
>>>(setf (new-prop-level plan-graph) new-value)
>>>...right?  And in the definition of the setf function, you are
>>>calling:
>>>(setf (new-prop-level plan-graph) new-value)
>>>See the problem?
>>>-bcd
>>
>>I see that but why does (setf (new-prop-level plan-graph) new-value)
>>translates to (SETF NEW-PROP-LEVEL). I didn't understand that part.
>>Shouldn't (new-prop-level plan-graph) be first evaluated and whatever
>>address that evaluates to be modified?
> 
> 
> But this function:
> 
> (defun NEW-PROP-LEVEL (plan-graph)
>    (first (plan-graph-proposition-levels plan-graph)))
> 
> returns a value, not an address!
> 
> 
> So, when you write:
> 
>     (setf (new-prop-level plan-graph) new-value)
> 
> setf cannot just evaluate (new-prop-level plan-graph), because the
> only thing it would get would be a value, and it could not do anything
> with it.  Instead, it analyses '(new-prop-level plan-graph), see that
> there exists some (setf new-prop-level) function and call it to do the
> job.
> 
> 
> (defun push-new-prop (prop plan-graph)
>        (push prop (new-prop-level plan-graph)))
> 
> Note that push is macro, not a function.  There's a reason for that!
> You cannot modify the pro-level of plan-graph from some value
> new-prop-level returns.  You need to write a primitive writer method
> somewhere.
> 

Suppose there is a code like: (setf (first lst) 5)

So, does setf first expands it to   "(setf first) (lst 5)"
and then does it calls some internal function to do the writing?

-Surendra Singhi
From: Pascal Bourguignon
Subject: Re: setf problem
Date: 
Message-ID: <87r7n7owwu.fsf@naiad.informatimago.com>
surendra <·········@netscape.net> writes:
> Suppose there is a code like: (setf (first lst) 5)
> 
> So, does setf first expands it to   "(setf first) (lst 5)"
> and then does it calls some internal function to do the writing?

Yes.

Why don't you ask your implementation?

CL-USER> (macroexpand-1 '(setf (first x) 5))
(SYSTEM::%RPLACA X 5)
T
CL-USER> (macroexpand-1 '(setf  (first (aref (caddr x) 42)) 5))
(SYSTEM::%RPLACA (AREF (CADDR X) 42) 5)
T

-- 
__Pascal Bourguignon__
From: Harald Hanche-Olsen
Subject: Re: setf problem
Date: 
Message-ID: <pcois8jqb9j.fsf@shuttle.math.ntnu.no>
+ surendra <·········@netscape.net>:

| Suppose there is a code like: (setf (first lst) 5)
| 
| So, does setf first expands it to   "(setf first) (lst 5)"
| and then does it calls some internal function to do the writing?

(As an aside, there is nothing wrong in Common Lisp about using "list"
as a variable name, since function and variable name spaces are
separate.)

No, it's more like this:  The lisp system has some information
associated with (setf first) that it uses to create the appropriate
function call.  On CMUCL, for example:

(macroexpand-1 '(setf (first list) 42))
=> (COMMON-LISP::%RPLACA LIST 42)
=> T

(The implementation is, of course, under no obligation to let the
expansion be in terms of standard functions.)

You too, can find out what is known about (setf first) as follows:

CL-USER> (get-setf-expansion '(first list))
(#:G1165)
(LIST)
(#:G1164)
(COMMON-LISP::%RPLACA #:G1165 #:G1164)
(FIRST #:G1165)

If you think this all looks awfully complicated, think about the fact
that, for example, (incf (aref array (incf n)) 42) must NOT expand
into the simpleminded

(setf (aref array (incf n))
  (+ (aref array (incf n)) 42))

because that would increment n twice.  Here is how CMUCL expands it:

(LET* ((#:G1175 ARRAY)
       (#:G1174 (INCF N))
       (#:G1173 (+ (AREF #:G1175 #:G1174) 42)))
  (COMMON-LISP::%ASET #:G1175 #:G1174 #:G1173))

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: surendra
Subject: Re: setf problem
Date: 
Message-ID: <cmip1r$meg$1@news.asu.edu>
Harald Hanche-Olsen wrote:

> + surendra <·········@netscape.net>:
> 
> | Suppose there is a code like: (setf (first lst) 5)
> | 
> | So, does setf first expands it to   "(setf first) (lst 5)"
> | and then does it calls some internal function to do the writing?
> 
> (As an aside, there is nothing wrong in Common Lisp about using "list"
> as a variable name, since function and variable name spaces are
> separate.)
> 

I know, it won't make a difference to the interpreter but doesn't it 
makes it harder for someone else looking at the code(for readability 
sake) to make out whether i am using list as function name or variable name?

Surendra
From: Jeff
Subject: Re: setf problem
Date: 
Message-ID: <qW5jd.471683$mD.241463@attbi_s02>
surendra wrote:

> 
> 
> Harald Hanche-Olsen wrote:
> 
> > + surendra <·········@netscape.net>:
> > 
> > >  Suppose there is a code like: (setf (first lst) 5)
> > >  
> > >  So, does setf first expands it to   "(setf first) (lst 5)"
> > >  and then does it calls some internal function to do the writing?
> > 
> > (As an aside, there is nothing wrong in Common Lisp about using
> > "list" as a variable name, since function and variable name spaces
> > are separate.)
> > 
> 
> I know, it won't make a difference to the interpreter but doesn't it
> makes it harder for someone else looking at the code(for readability
> sake) to make out whether i am using list as function name or
> variable name?

I used to think this, too, when first starting to use Lisp. In fact, it
isn't true. Is list the first item in the list or not? If not, it is
prefixed with #' or not? This is second nature when looking at Lisp
code. The only time you might need to worry about it is if you plan on
doing any EVAL calls:

 (eval (cdr '(1 list 2 3)))

Jeff M.

-- 
`(:mail-to ,(concatenate 'string (symbol-name 'massung) 
                                 (string (code-char 64)) 
                                 (string-upcase "gmail.com")))
From: Harald Hanche-Olsen
Subject: Re: setf problem
Date: 
Message-ID: <pcopt2rymsm.fsf@shuttle.math.ntnu.no>
+ "Jeff" <·······@gmail.com>:

| The only time you might need to worry about it is if you plan on
| doing any EVAL calls:
| 
|  (eval (cdr '(1 list 2 3)))

If I found myself wanting to do something like that, I'd worry about
my own sanity first.  8-)

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: setf problem
Date: 
Message-ID: <87y8hfosdl.fsf@qrnik.zagroda>
"Jeff" <·······@gmail.com> writes:

> I used to think this, too, when first starting to use Lisp. In fact, it
> isn't true. Is list the first item in the list or not? If not, it is
> prefixed with #' or not? This is second nature when looking at Lisp
> code.

The above is not enough:
(funcall 'list 1 2)

The symbol can be quoted in one place and funcalled in another,
so it's not statically detectable whether it will be used as a
function, even if we don't use eval.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Jeff
Subject: Re: setf problem
Date: 
Message-ID: <ga7jd.303770$wV.116598@attbi_s54>
Marcin 'Qrczak' Kowalczyk wrote:

> "Jeff" <·······@gmail.com> writes:
> 
> > I used to think this, too, when first starting to use Lisp. In
> > fact, it isn't true. Is list the first item in the list or not? If
> > not, it is prefixed with #' or not? This is second nature when
> > looking at Lisp code.
> 
> The above is not enough:
> (funcall 'list 1 2)

Okay, now that freaks me out. ;)

But good to know. Thanks!

-- 
(surf-to "http://www.retrobyte.org/")
(mail-to (concatenate 'string "massung" ·@" "gmail.com"))
From: Pascal Bourguignon
Subject: Re: setf problem
Date: 
Message-ID: <87lldeq15s.fsf@naiad.informatimago.com>
"Jeff" <·······@gmail.com> writes:

> Marcin 'Qrczak' Kowalczyk wrote:
> 
> > "Jeff" <·······@gmail.com> writes:
> > 
> > > I used to think this, too, when first starting to use Lisp. In
> > > fact, it isn't true. Is list the first item in the list or not? If
> > > not, it is prefixed with #' or not? This is second nature when
> > > looking at Lisp code.
> > 
> > The above is not enough:
> > (funcall 'list 1 2)
> 
> Okay, now that freaks me out. ;)
> 
> But good to know. Thanks!

Yes, do freak:        (funcall (function list) 1 2)
is not the same as:   (funcall (quote    list) 1 2)

CL-USER> (flet ((list (&rest args) (mapcar (function cons) args args)))
           (values (funcall (function list) 1 2)
                   (funcall (quote    list) 1 2)))

((1 . 1) (2 . 2))
(1 2)

-- 
__Pascal Bourguignon__
From: Svein Ove Aas
Subject: Re: setf problem
Date: 
Message-ID: <cmjgge$cvt$1@services.kq.no>
Pascal Bourguignon wrote:

> "Jeff" <·······@gmail.com> writes:
> 
>> Marcin 'Qrczak' Kowalczyk wrote:
>> 
>> > "Jeff" <·······@gmail.com> writes:
>> > 
>> > > I used to think this, too, when first starting to use Lisp. In
>> > > fact, it isn't true. Is list the first item in the list or not? If
>> > > not, it is prefixed with #' or not? This is second nature when
>> > > looking at Lisp code.
>> > 
>> > The above is not enough:
>> > (funcall 'list 1 2)
>> 
>> Okay, now that freaks me out. ;)
>> 
>> But good to know. Thanks!
> 
> Yes, do freak:        (funcall (function list) 1 2)
> is not the same as:   (funcall (quote    list) 1 2)
> 
> CL-USER> (flet ((list (&rest args) (mapcar (function cons) args args)))
>            (values (funcall (function list) 1 2)
>                    (funcall (quote    list) 1 2)))
> 
> ((1 . 1) (2 . 2))
> (1 2)
> 

No, it makes sense.
If you give funcall a function, it calls that function.
If you give it a symbol, it looks up the (global) function-value of that
symbol, and calls that.

(flet ((nsf ()))
  (funcall #'nsf)) => OK

(flet ((nsf ()))
  (funcall 'nsf)) => No such function.
From: Kalle Olavi Niemitalo
Subject: Re: setf problem
Date: 
Message-ID: <87r7n6rrir.fsf@Astalo.kon.iki.fi>
Pascal Bourguignon <····@mouse-potato.com> writes:

> Yes, do freak:        (funcall (function list) 1 2)
> is not the same as:   (funcall (quote    list) 1 2)

If that's COMMON-LISP:LIST, then 11.1.2.1.2 makes them the same.
From: Steven M. Haflich
Subject: Re: setf problem
Date: 
Message-ID: <JAAjd.6164$zx1.780@newssvr13.news.prodigy.com>
Kalle Olavi Niemitalo wrote:

> Pascal Bourguignon <····@mouse-potato.com> writes:
> 
> 
>>Yes, do freak:        (funcall (function list) 1 2)
>>is not the same as:   (funcall (quote    list) 1 2)
> 
> 
> If that's COMMON-LISP:LIST, then 11.1.2.1.2 makes them the same.

No, the cited passage makes the original example _undefined_ with
its flet of cl:list.  It's point would be correct if the symbol
were in some other package.
From: Pascal Bourguignon
Subject: Re: setf problem
Date: 
Message-ID: <877joxnezd.fsf@naiad.informatimago.com>
"Steven M. Haflich" <·················@alum.mit.edu> writes:

> Kalle Olavi Niemitalo wrote:
> 
> > Pascal Bourguignon <····@mouse-potato.com> writes:
> >
> >>Yes, do freak:        (funcall (function list) 1 2)
> >>is not the same as:   (funcall (quote    list) 1 2)
> > If that's COMMON-LISP:LIST, then 11.1.2.1.2 makes them the same.
> 
> No, the cited passage makes the original example _undefined_ with
> its flet of cl:list.  It's point would be correct if the symbol
> were in some other package.

Well, I've not fleted common-lisp:lisp.  
Just prefix my code with (in-package :common-lisp-user).

But the point of Kalle was that if you don't want to be victime of
such a name capture you can always write:

    (funcall (function common-lisp:list) 1 2) ; or
    (funcall (quote    common-lisp:list) 1 2)

and in these case you get always the same result.
Of course, (flet ((common-lisp:list (...)...)) ...) is forbidden.


-- 
__Pascal Bourguignon__