From: Q
Subject: move confusion with PUSH
Date: 
Message-ID: <1177002144.512908.39370@n76g2000hsh.googlegroups.com>
Why does this work?

CL-USER 264 > (list 2 3 4)
(2 3 4)

CL-USER 265 > (push 1 *)
(1 2 3 4)

When this does not work?

CL-USER 262 > (push '1 (list 2 3 4))

Error: Couldn't find a setf expansion for (LIST 2 3 4).
  1 (abort) Return to level 0.
  2 Return to top loop level 0.

From: Edi Weitz
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <uwt08s2mr.fsf@agharta.de>
On 19 Apr 2007 10:02:24 -0700, Q <······@gmail.com> wrote:

> Why does this work?
>
> CL-USER 264 > (list 2 3 4)
> (2 3 4)
>
> CL-USER 265 > (push 1 *)
> (1 2 3 4)
>
> When this does not work?
>
> CL-USER 262 > (push '1 (list 2 3 4))
>
> Error: Couldn't find a setf expansion for (LIST 2 3 4).
>   1 (abort) Return to level 0.
>   2 Return to top loop level 0.

If you look at the HyperSpec entry for PUSH, you'll see that the
second argument has to be a "place" - and (LIST ...) isn't one.  See

  http://www.lispworks.com/documentation/HyperSpec/Body/05_a.htm

Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Costanza
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <58pmnsF2i47rsU1@mid.individual.net>
Q wrote:
> Why does this work?
> 
> CL-USER 264 > (list 2 3 4)
> (2 3 4)
> 
> CL-USER 265 > (push 1 *)
> (1 2 3 4)
> 
> When this does not work?
> 
> CL-USER 262 > (push '1 (list 2 3 4))
> 
> Error: Couldn't find a setf expansion for (LIST 2 3 4).
>   1 (abort) Return to level 0.
>   2 Return to top loop level 0.

If you take a look at the HyperSpec entry for push, you can see that it 
expects a "place" as a second parameter. The fact that the error message 
tells you that it doesn't find a proper expansion for setf means that 
push is implemented in terms of setf. The entry for setf also tells you 
that it expects a "place" as its first parameter.

Push and setf are macros that assign new values to such "places." For 
example, variables are kinds of places, but also slots in structs or 
objects, entries in vectors, arrays and hashtables, and so on.

Plain objects, like lists, numbers, characters, strings, and so on, are 
not places, so you cannot use push or setf (or similar constructs) here.

You can find more information in Section 5.1 of the HyperSpec.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Q
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <1177003791.224022.118730@y5g2000hsa.googlegroups.com>
So then why is it a place in the second instance?  Why does that work?
From: Timofei Shatrov
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <4627a8e8.34735316@news.readfreenews.net>
On 19 Apr 2007 10:29:51 -0700, Q <······@gmail.com> tried to confuse everyone
with this message:

>So then why is it a place in the second instance?  Why does that work?
>

Because * is a variable, and therefore, a place.

-- 
|Don't believe this - you're not worthless              ,gr---------.ru
|It's us against millions and we can't take them all... |  ue     il   |
|But we can take them on!                               |     @ma      |
|                       (A Wilhelm Scream - The Rip)    |______________|
From: Pascal Costanza
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <58pon1F2h2svpU1@mid.individual.net>
Q wrote:
> So then why is it a place in the second instance?  Why does that work?

* is a variable.

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Alex Mizrahi
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <4627ab3c$0$90276$14726298@news.sunsite.dk>
(message (Hello 'Q)
(you :wrote  :on '(19 Apr 2007 10:29:51 -0700))
(

 Q> So then why is it a place in the second instance?
 Q>   Why does that work?

use CONS to build lists, until you understand how PUSH works.

(defparameter *udo* (list 2 3 4))
(cons 1 *udo*) => (1 2 3 4)
*udo* => (2 3 4)
;;you see, *udo* is not changed

(cons 1 (list 2 3 4)) => (1 2 3 4)

if you'll take a look how PUSH works:
(push 1 *udo*) is actuall same as
(setf *udo* (cons 1 *udo*))

you can do MACROEXPAND-1 to see what push is expanded to.

(push 1 *udo*) => (1 2 3 4)
*udo* => (1 2 3 4)

;;you see, push actually changes variable *udo*

now we'll check what you're trying to do:

(setf (list 2 3 4) (cons 1 (2 3 4)))

;;obviously it willl be an error

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"I am everything you want and I am everything you need") 
From: Edi Weitz
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <uk5w8s123.fsf@agharta.de>
On Thu, 19 Apr 2007 19:20:59 +0200, Pascal Costanza <··@p-cos.net> wrote:

> Plain objects, like lists, numbers, characters, strings, and so on,
> are not places, so you cannot use push or setf (or similar
> constructs) here.

That's not the reason.  The reason is that (LIST 2 3 4) is a function
form that can't be found in 5.1.2.2.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Costanza
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <58povgF2h2svpU2@mid.individual.net>
Edi Weitz wrote:
> On Thu, 19 Apr 2007 19:20:59 +0200, Pascal Costanza <··@p-cos.net> wrote:
> 
>> Plain objects, like lists, numbers, characters, strings, and so on,
>> are not places, so you cannot use push or setf (or similar
>> constructs) here.
> 
> That's not the reason.  The reason is that (LIST 2 3 4) is a function
> form that can't be found in 5.1.2.2.

Er, yes and no.

The mental model I learned for setf is "make sure that the next time you 
evaluate the left hand side form, it will evaluate to the value on the 
right hand side."

So in (setf (person-name *p*) "Edi"), setf "makes sure" that the next 
time (person-name *p*) is evaluated, the result will be "Edi".

I don't see how reasonable semantics could be defined for (setf (list 1 
2 3) ...), where (list 1 2 3) will evaluate to "something else" the next 
time it is evaluated.

Technically, you are of course right.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Edi Weitz
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <ufy6wrza5.fsf@agharta.de>
On Thu, 19 Apr 2007 19:59:12 +0200, Pascal Costanza <··@p-cos.net> wrote:

> I don't see how reasonable semantics could be defined for (setf
> (list 1 2 3) ...), where (list 1 2 3) will evaluate to "something
> else" the next time it is evaluated.

Right, that's why it's not in 5.1.2.2... :)

> Technically, you are of course right.

I was answering to your original posting because the fact that LIST
returns a "plain object" is irrelevant.  If *FOO* is the list (1 2 3
4), then (CDR *FOO*) will return the list (2 3 4), like (LIST 2 3 4)
does, but (CDR *FOO*) is nevertheless a "place."

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Dan Bensen
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <f09k0m$ah5$1@wildfire.prairienet.org>
Pascal Costanza wrote:
> The mental model I learned for setf is "make sure that the next time you 
> evaluate the left hand side form, it will evaluate to the value on the 
> right hand side."

The model I think of is that the LHS has to be accessible from a current 
binding.  That's the only way there can *be* a next evaluation.

> I don't see how reasonable semantics could be defined for (setf (list 1 
> 2 3) ...), where (list 1 2 3) will evaluate to "something else" the next 
> time it is evaluated.

Because it can't be evaluated again if you don't bind it.

-- 
Dan
www.prairienet.org/~dsb/
From: Rainer Joswig
Subject: Re: move confusion with PUSH
Date: 
Message-ID: <joswig-7D59AD.19373619042007@news-europe.giganews.com>
In article <·······················@n76g2000hsh.googlegroups.com>,
 Q <······@gmail.com> wrote:

> Why does this work?
> 
> CL-USER 264 > (list 2 3 4)
> (2 3 4)
> 
> CL-USER 265 > (push 1 *)
> (1 2 3 4)
> 
> When this does not work?
> 
> CL-USER 262 > (push '1 (list 2 3 4))
> 
> Error: Couldn't find a setf expansion for (LIST 2 3 4).
>   1 (abort) Return to level 0.
>   2 Return to top loop level 0.

Others have mentioned the concept of 'place'.

Also note the difference between CONS and PUSH.


(PUSH 1 place) is something like

(setf place (cons 1 place))

If place is just a variable, then it is
simply like:

(setq place (cons 1 place))

Now why SETQ?

(list 2 3 4) returns (2 3 4).


Set a variable to the list:

(setf foo (list 2 3 4)) 

Now if you do

(CONS 1 foo) and then look at foo, foo hasn't changed.

To change foo you need to cons 1 to the list and
then set foo to the new cons created.

So PUSH expects something that it can set the result
to. For example a variable.

So (push 1 foo) -> (setf foo (cons 1 foo)) makes sense.
But (push 1 (list 2 3 4)) -> (setf (list 2 3 4) (cons 1 (list 2 3 4)))
NOT!

---

Do you have a tutorial for Common Lisp, which explains these things?
There are some good introductory books available. Some
even for free in electronic form. Do you need some pointers?

Also there is a cool online Lisp tutor:
http://apsymac33.uni-trier.de:8080/Lisp-Course
It is running on top a web server written in Lisp (CL-HTTP).

-- 
http://lispm.dyndns.org