From: Rene
Subject: SETF : Ambiguous?
Date: 
Message-ID: <8078c580.0111220403.5878d88f@posting.google.com>
Consider the following code

(let ((result nil) (tail nil))
    (let ((temp (list 1)))
        (setf result (setf tail temp)))
    (let ((temp (list 2)))
        (setf (cdr tail) (setf tail temp)))
     (values result tail))

The result of this seems to depend on the evaluation of order of place and
newvalue in (setf place newvalue).

However I didn't see where the order of place and new value was defined in
the Hyperspec for SETF.

In CormanLisp this results in

(1)

(2 ... )

and in Lispworks

(1 2)

(2)

Rene.

From: Erik Naggum
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <3215431275217808@naggum.net>
* ··············@hotmail.com (Rene)
| However I didn't see where the order of place and new value was defined in
| the Hyperspec for SETF.

  There is nothing special about the evaluation order for setf.  The
  standard Common Lisp evaluation order is strictly left to right.  Any
  deviation from this is a serious bug.

(let ((x (list 1 2 3)))
  (setf (cdr (progn (format t "First base!~&")
                    x))
        (progn (format t "Second base!~&")
               (list 3 5)))
  x)

  In a conforming Common Lisp implementation, this _must_ print First base!
  and Second base! in that order and return (1 3 5).

///
-- 
  Norway is now run by a priest from the fundamentalist Christian People's
  Party, the fifth largest party representing one eighth of the electorate.
-- 
  Carrying a Swiss Army pocket knife in Oslo, Norway, is a criminal offense.
From: Rene de Visser
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <9tja3e$h1p$1@news1.wdf.sap-ag.de>
Noting that SETF is a macro,

Is it then the case then that all the standard macros in common lisp that
end up evaluating their arguements
make sure that these evaluations occur in a left to right direction w.r.t to
the original macro parameters?

Do people pay much attention to this when writing their own macros?
(I certainly haven't given any thought to this in the past when writing my
own macros.)

Rene.

"Erik Naggum" <····@naggum.net> wrote in message
·····················@naggum.net...
> * ··············@hotmail.com (Rene)
> | However I didn't see where the order of place and new value was defined
in
> | the Hyperspec for SETF.
>
>   There is nothing special about the evaluation order for setf.  The
>   standard Common Lisp evaluation order is strictly left to right.  Any
>   deviation from this is a serious bug.
>
> (let ((x (list 1 2 3)))
>   (setf (cdr (progn (format t "First base!~&")
>                     x))
>         (progn (format t "Second base!~&")
>                (list 3 5)))
>   x)
>
>   In a conforming Common Lisp implementation, this _must_ print First
base!
>   and Second base! in that order and return (1 3 5).
>
> ///
> --
>   Norway is now run by a priest from the fundamentalist Christian People's
>   Party, the fifth largest party representing one eighth of the
electorate.
> --
>   Carrying a Swiss Army pocket knife in Oslo, Norway, is a criminal
offense.
From: Erik Naggum
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <3215443310284855@naggum.net>
* Rene de Visser
| Is it then the case then that all the standard macros in common lisp that
| end up evaluating their arguements make sure that these evaluations occur
| in a left to right direction w.r.t to the original macro parameters?

  Yes.

| Do people pay much attention to this when writing their own macros?

  If they are smart and know the language, they do.

| (I certainly haven't given any thought to this in the past when writing
| my own macros.)

  Well, then you have written _really_ bad macros.

///
-- 
  Norway is now run by a priest from the fundamentalist Christian People's
  Party, the fifth largest party representing one eighth of the electorate.
-- 
  Carrying a Swiss Army pocket knife in Oslo, Norway, is a criminal offense.
From: Kent M Pitman
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <sfwoflumwjr.fsf@shell01.TheWorld.com>
Erik Naggum <····@naggum.net> writes:

> * Rene de Visser
> | Is it then the case then that all the standard macros in common lisp that
> | end up evaluating their arguements make sure that these evaluations occur
> | in a left to right direction w.r.t to the original macro parameters?
> 
>   Yes.
> 
> | Do people pay much attention to this when writing their own macros?
> 
>   If they are smart and know the language, they do.
> 
> | (I certainly haven't given any thought to this in the past when writing
> | my own macros.)
> 
>   Well, then you have written _really_ bad macros.

Actually, the more generous way to say this is that you have macros that
only you can use.

You can, of course, write macros that violate this convention and then make
sure your code is careful to call the macro in a way that doesn't trip
up any problem.

But you should never offer these to other people without a HUGE disclaimer.

Btw, the same is true for double-evaluation.  Macros should never do
double-evaluation of arguments without that being a well-publicized
effect.  (Things like LOOP or DO or DOTIMES for example, may doubly
evlauate their arguments since that's the whole function of iteration.
But the details are carefully documented.  For that matter, LOOP and
associates [I hesitate to call LOOP and DO friends :-] might be
considered to violate left to right evaluation, since it backs up
sometimes, but again, it doesn't happen casually.)
From: Thomas F. Burdick
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <xcvoflq8wig.fsf@apocalypse.OCF.Berkeley.EDU>
"Rene de Visser" <··············@hotmail.de> writes:

> Noting that SETF is a macro,
> 
> Is it then the case then that all the standard macros in common lisp that
> end up evaluating their arguements
> make sure that these evaluations occur in a left to right direction w.r.t to
> the original macro parameters?
> 
> Do people pay much attention to this when writing their own macros?
> (I certainly haven't given any thought to this in the past when writing my
> own macros.)

If I were you, I'd go through your commonly-used macros and fix this.
If you want to be consistent with Common Lisp, left-to-right order
should be used everywhere, except where the differing order of
evaluation is a part of the point of the macro.  Even then, though, as
much should be done left-to-right as possible, because that will fit
with the instincts you acquire from CL.

You can probably get away with arbitrary orders of evaluation,
particularly if you hadn't thought about it, for a long time.  Sort of
like how if you go and declare a bunch of commonly-used variables to
be special, you'll likely get by without being bitten for a long time.
But just like how working in a lisp image where X is special can
create some *really* confusing bugs when it finally catches up with
you, so will this.  I screwed up left-to-right evaluation in a
commonly-used macro of mine through careless editing, and when I
finally got bitten by the bug, MAN did it take me too long to figure
out the problem.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Pierre R. Mai
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <87y9kyetst.fsf@orion.bln.pmsf.de>
··············@hotmail.com (Rene) writes:

> Consider the following code
> 
> (let ((result nil) (tail nil))
>     (let ((temp (list 1)))
>         (setf result (setf tail temp)))
>     (let ((temp (list 2)))
>         (setf (cdr tail) (setf tail temp)))
>      (values result tail))
> 
> The result of this seems to depend on the evaluation of order of place and
> newvalue in (setf place newvalue).
> 
> However I didn't see where the order of place and new value was defined in
> the Hyperspec for SETF.

On a quick glance I didn't find exact wording that exactly prohibits
what Corman Lisp does, though several appeals to left-to-right order
of evaluation, and section 5.1.2.9 seem to suggest that the intent was
clearly that left-to-right order of evaluation of subforms would
extend to the new-value forms of setf as well:

<quote>
5.1.2.9 Other Compound Forms as Places

For any other compound form for which the operator is a symbol f, the
setf form expands into a call to the function named (setf f). The
first argument in the newly constructed function form is newvalue and
the remaining arguments are the remaining elements of place. This
expansion occurs regardless of whether f or (setf f) is defined as a
function locally, globally, or not at all. For example,

(setf (f arg1 arg2 ...) new-value)

expands into a form with the same effect and value as

(let ((#:temp-1 arg1)          ;force correct order of evaluation
       (#:temp-2 arg2)
       ...
       (#:temp-0 new-value))
   (funcall (function (setf f)) #:temp-0 #:temp-1 #:temp-2...))

A function named (setf f) must return its first argument as its only
value in order to preserve the semantics of setf.
</quote>

Yes, I know that this could be considered to be an example, which
isn't binding, and furthermore the section doesn't deal with setf of
cdr, which is handled elsewhere, so again technically this isn't
binding at all.

But it clearly suggests, and I'd guess user expectations to agree with
this, that the new-value form is evaluated after all sub-forms of
place have been evaluated from left-to-right.  So unless an
implementor can make the case that this is a real burden on his
implementation, I think following that hint would be a good thing.
All implementations I tested seem to follow that interpretation,
producing (1 2) and (2), as I'd have expected.

I'd be glad if someone could locate some more exact wording in the
standard.

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Kent M Pitman
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <sfwlmgymw9o.fsf@shell01.TheWorld.com>
"Pierre R. Mai" <····@acm.org> writes:

> ··············@hotmail.com (Rene) writes:
> 
> > Consider the following code
> > 
> > (let ((result nil) (tail nil))
> >     (let ((temp (list 1)))
> >         (setf result (setf tail temp)))
> >     (let ((temp (list 2)))
> >         (setf (cdr tail) (setf tail temp)))
> >      (values result tail))
> > 
> > The result of this seems to depend on the evaluation of order of place and
> > newvalue in (setf place newvalue).
> > 
> > However I didn't see where the order of place and new value was defined in
> > the Hyperspec for SETF.

It's defined language-wide.

You should be looking for an exception in SETF, and none is given.

In CLTL, left-to-right order of evaluation failed to be mentioned
globally and people complained.  It was mentioned in only three
places: SETF, DEFSETF, and the discussion of arithmetic contagion, all
of which were mentioned to "preserve the ordinary left-to-right order
of evaluation".  Implementors fortunately inferred from that correctly
that there must be a left-to-right order globally.  But for ANSI CL, we
moved those references to a central place.

The presence of heavy-duty mechanisms for those five setf-expansion values
should be proof enough of the intent in any case.  It's extremely important
that this be correctly supported, to the point that we exposed to users
the same mechanism we expect the system to be using just to make sure it's
done consistently in all system and user code.
 
> On a quick glance I didn't find exact wording that exactly prohibits
> what Corman Lisp does, though several appeals to left-to-right order
> of evaluation, and section 5.1.2.9 seem to suggest that the intent was
> clearly that left-to-right order of evaluation of subforms would
> extend to the new-value forms of setf as well:
>
> <quote>
> 5.1.2.9 Other Compound Forms as Places
> 
> For any other compound form for which the operator is a symbol f, the
> setf form expands into a call to the function named (setf f). The
> first argument in the newly constructed function form is newvalue and
> the remaining arguments are the remaining elements of place. This
> expansion occurs regardless of whether f or (setf f) is defined as a
> function locally, globally, or not at all. For example,
> 
> (setf (f arg1 arg2 ...) new-value)
> 
> expands into a form with the same effect and value as
> 
> (let ((#:temp-1 arg1)          ;force correct order of evaluation
>        (#:temp-2 arg2)
>        ...
>        (#:temp-0 new-value))
>    (funcall (function (setf f)) #:temp-0 #:temp-1 #:temp-2...))
> 
> A function named (setf f) must return its first argument as its only
> value in order to preserve the semantics of setf.
> </quote>
> 
> Yes, I know that this could be considered to be an example, which
> isn't binding, and furthermore the section doesn't deal with setf of
> cdr, which is handled elsewhere, so again technically this isn't
> binding at all.
> 
> But it clearly suggests, and I'd guess user expectations to agree with
> this, that the new-value form is evaluated after all sub-forms of
> place have been evaluated from left-to-right.  So unless an
> implementor can make the case that this is a real burden on his
> implementation, I think following that hint would be a good thing.
> All implementations I tested seem to follow that interpretation,
> producing (1 2) and (2), as I'd have expected.
> 
> I'd be glad if someone could locate some more exact wording in the
> standard.

I'll look later perhaps.  Gotta go eat some turkey.
From: Ian Wild
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <3BFE2D9D.767FD988@cfmu.eurocontrol.int>
"Pierre R. Mai" wrote:
> 

> I'd be glad if someone could locate some more exact wording in the
> standard.

Quoth HyperSpec/Body/sec_5-1-1-1.html (rule 2):

"For the macros that manipulate places ...the subforms of the macro
call are evaluated exactly once in left-to-right order..."
From: Pierre R. Mai
Subject: Re: SETF : Ambiguous?
Date: 
Message-ID: <87herl8ycg.fsf@orion.bln.pmsf.de>
Ian Wild <···@cfmu.eurocontrol.int> writes:

> "Pierre R. Mai" wrote:
> > 
> 
> > I'd be glad if someone could locate some more exact wording in the
> > standard.
> 
> Quoth HyperSpec/Body/sec_5-1-1-1.html (rule 2):
> 
> "For the macros that manipulate places ...the subforms of the macro
> call are evaluated exactly once in left-to-right order..."

Right, that's the rule I had been missing.  Thanks!

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein