From: Emilian
Subject: (setf (if c x y) val)
Date: 
Message-ID: <1131022931.660457.128760@g44g2000cwa.googlegroups.com>
I've read on some site that the code (setf (if c x y) val) is wrong.
Why is that ?

Now, testing it with clisp doesn't yeld any error. Depending on the
value of c (t or nil) x (or y) gets the new value.

In the hyperspec (http://www.lisp.org/HyperSpec/Body/speope_if.html) I
see that IF should return a value (as returned by the then/else form)
which may be "2. an object associated with a name in a binding".

So I don't see any problem here. Any hints would be nice. And if we got
here, how does this differ from (+ (if c x y) val) ?

[26]> (setf x 0)
0
[27]> (setf y 1)
1
[28]> (setf (if (< 1 (read)) x y) 3)
0
3
[29]> x
0
[30]> y
3
[31]> (setf (if (< 1 (read)) x y) 3)
19
3
[32]> x
3
[33]> y
3

Regards,
Emilian Bold

From: ··············@hotmail.com
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131027202.592799.230120@o13g2000cwo.googlegroups.com>
Emilian wrote:
> I've read on some site that the code (setf (if c x y) val) is wrong.
> Why is that ?
>
> Now, testing it with clisp doesn't yeld any error. Depending on the
> value of c (t or nil) x (or y) gets the new value.
>
> In the hyperspec (http://www.lisp.org/HyperSpec/Body/speope_if.html) I
> see that IF should return a value (as returned by the then/else form)
> which may be "2. an object associated with a name in a binding".

> So I don't see any problem here. Any hints would be nice. And if we got
> here, how does this differ from (+ (if c x y) val) ?

You should also read the hyperspec regarding setf, and the concept of
"place."

What do you expect (setf 2 3) to do? Change the value of 2? It doesn't
make sense, and if it did, all hell would break loose anyway.

(if c x y) returns a value, either the value of x or the value of y. It
does not return a variable reference that setf can put a value into.

Your instinct is sound, but setf is not an ordinary Lisp function.
From: Bill Atkins
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131027411.474797.71010@g49g2000cwa.googlegroups.com>
As R. Mattes pointed out, setf is a macro, which means it is expanded
_before_ your code is actually executed.  So setf is operating on the
list '(if c x y), but at expansion-time this expression has no meaning
beyond the symbols it contains.

For instance, the form (setf x 4) will be expanded to (setq x 4) and
the form (setf (car x) 4) will expand to (rplaca x 4).  These are
straightforward code transformations; setf looks at the symbols
comprising its place argument and expands into the proper form.  In the
case of if, you could certainly implement your own setf function to do
something like this:

 (setf (if x y z) 4)
   ;; macroexpands to (roughly)
   (if x
     (setf y 4)
     (setf z 4))

However, this setter isn't built into Common Lisp and I'm not
personally convinced that it's useful.

Bill
From: Sam Steingold
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <uzmolyely.fsf@gnu.org>
> * Emilian <············@tznvy.pbz> [2005-11-03 05:02:11 -0800]:
>
> I've read on some site that the code (setf (if c x y) val) is wrong.
> Why is that ?

because ANSI CL does not require IF to be a SETF place.

> Now, testing it with clisp doesn't yeld any error. Depending on the
> value of c (t or nil) x (or y) gets the new value.

this is a CLISP extension.
<http://clisp.cons.org/impnotes/flow-dict.html#setf>


-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.openvotingconsortium.org/> <http://www.camera.org>
<http://truepeace.org> <http://www.dhimmi.com/>
I just forgot my whole philosophy of life!!!
From: Emilian
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131029793.717154.198130@g44g2000cwa.googlegroups.com>
All is clear now. Thanks for the answers. Who would have thought ?

I'll try to also take a look at the CLISP implementation notes from now
on.

Emilian

Sam Steingold wrote:
> > * Emilian <············@tznvy.pbz> [2005-11-03 05:02:11 -0800]:
> >
> > I've read on some site that the code (setf (if c x y) val) is wrong.
> > Why is that ?
>
> because ANSI CL does not require IF to be a SETF place.
>
> > Now, testing it with clisp doesn't yeld any error. Depending on the
> > value of c (t or nil) x (or y) gets the new value.
>
> this is a CLISP extension.
> <http://clisp.cons.org/impnotes/flow-dict.html#setf>
>
>
> --
> Sam Steingold (http://www.podval.org/~sds) running w2k
> <http://www.openvotingconsortium.org/> <http://www.camera.org>
> <http://truepeace.org> <http://www.dhimmi.com/>
> I just forgot my whole philosophy of life!!!
From: ·········@cern.ch
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <yzo4q6t3iu4.fsf@cern.ch>
> (setf (if c x y) val)

As you seem to know how to look up the HyperSpec, why don't you go
read about SETF? (Hint: SETF is a macro not a function)

Ole
From: R. Mattes
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <pan.2005.11.03.15.21.01.350877@mh-freiburg.de>
On Thu, 03 Nov 2005 05:02:11 -0800, Emilian wrote:

> I've read on some site that the code (setf (if c x y) val) is wrong.
> Why is that ?
> 
> Now, testing it with clisp doesn't yeld any error. Depending on the
> value of c (t or nil) x (or y) gets the new value.
> 
> In the hyperspec (http://www.lisp.org/HyperSpec/Body/speope_if.html) I
> see that IF should return a value (as returned by the then/else form)
> which may be "2. an object associated with a name in a binding".
> 
> So I don't see any problem here. Any hints would be nice. And if we got
> here, how does this differ from (+ (if c x y) val) ?
> 
> [26]> (setf x 0)
> 0
> [27]> (setf y 1)
> 1
> [28]> (setf (if (< 1 (read)) x y) 3)
> 0
> 3
> [29]> x
> 0
> [30]> y
> 3
> [31]> (setf (if (< 1 (read)) x y) 3)
> 19
> 3
> [32]> x
> 3
> [33]> y
> 3

Clisp is an interpreter - most Common Lisps are compilers.
Your examples doesn't work on SBCL for example.
Try:

 (macroexpand '(setf (if (< 1 (read) x y) 3))

Hint: setf is a _macro_ that gets executed long before (if ...) gets
evaluated ...

 HTH Ralf Mattes
> Regards,
> Emilian Bold
From: Sam Steingold
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <u64r9ztb6.fsf@gnu.org>
> * R. Mattes <··@zu-servohet.qr> [2005-11-03 16:21:09 +0100]:
>
> On Thu, 03 Nov 2005 05:02:11 -0800, Emilian wrote:
>
>> I've read on some site that the code (setf (if c x y) val) is wrong.
>> Why is that ?
>> 
>> Now, testing it with clisp doesn't yeld any error. Depending on the
>> value of c (t or nil) x (or y) gets the new value.
>> 
>> In the hyperspec (http://www.lisp.org/HyperSpec/Body/speope_if.html) I
>> see that IF should return a value (as returned by the then/else form)
>> which may be "2. an object associated with a name in a binding".
>> 
>> So I don't see any problem here. Any hints would be nice. And if we got
>> here, how does this differ from (+ (if c x y) val) ?
>> 
>> [26]> (setf x 0)
>> 0
>> [27]> (setf y 1)
>> 1
>> [28]> (setf (if (< 1 (read)) x y) 3)
>> 0
>> 3
>> [29]> x
>> 0
>> [30]> y
>> 3
>> [31]> (setf (if (< 1 (read)) x y) 3)
>> 19
>> 3
>> [32]> x
>> 3
>> [33]> y
>> 3
>
> Clisp is an interpreter - most Common Lisps are compilers.

CLISP does include a compiler.


-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.palestinefacts.org/> <http://www.honestreporting.com>
<http://www.openvotingconsortium.org/> <http://ffii.org/>
The early bird may get the worm, but the second mouse gets the cheese.
From: R. Mattes
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <pan.2005.11.03.18.07.30.646428@mh-freiburg.de>
On Thu, 03 Nov 2005 09:42:37 -0500, Sam Steingold wrote:

>> * R. Mattes <··@zu-servohet.qr> [2005-11-03 16:21:09 +0100]:
>>
 [..]
>>
>> Clisp is an interpreter - most Common Lisps are compilers.
> 
> CLISP does include a compiler.

Yes, of course, sorry. I couldn't macroexpansion with CLisp
since my latest attempt to compile the Debian package didn't
succeed.

 Cheers, RalfD
From: Timofei Shatrov
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <436a11b1.1211205@news.readfreenews.net>
On Thu, 03 Nov 2005 16:21:09 +0100, "R. Mattes" <··@mh-freiburg.de>
tried to confuse everyone with this message:


>Clisp is an interpreter - most Common Lisps are compilers.
>Your examples doesn't work on SBCL for example.
>Try:
>
> (macroexpand '(setf (if (< 1 (read) x y) 3))
>
>Hint: setf is a _macro_ that gets executed long before (if ...) gets
>evaluated ...
>

But it doesn't have to be evaluated at the time of expansion.
Implementation can easily extend setf behaviour. It doesn't matter
whether compiled or interpreted code is running (CLISP can do both).

(defmacro setf-if ((_ a b c) d)
  `(if ,a (setf ,b ,d) (setf ,c ,d)))


-- 
|a\o/r|,-------------.,---------- Timofei Shatrov aka Grue ------------.
| m"a ||FC AMKAR PERM|| mail: grue at mail.ru  http://grue3.tripod.com |
|  k  ||  PWNZ J00   || Kingdom of Loathing: Grue3 lvl 18 Seal Clubber |
`-----'`-------------'`-------------------------------------------[4*72]
From: R. Mattes
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <pan.2005.11.03.15.52.42.119363@mh-freiburg.de>
On Thu, 03 Nov 2005 13:39:03 +0000, Timofei Shatrov wrote:

> On Thu, 03 Nov 2005 16:21:09 +0100, "R. Mattes" <··@mh-freiburg.de>
> tried to confuse everyone with this message:
> 
> 
>>Clisp is an interpreter - most Common Lisps are compilers.
>>Your examples doesn't work on SBCL for example.
>>Try:
>>
>> (macroexpand '(setf (if (< 1 (read) x y) 3))
>>
>>Hint: setf is a _macro_ that gets executed long before (if ...) gets
>>evaluated ...
>>
> 
> But it doesn't have to be evaluated at the time of expansion.

I don't understand this. For the semantic the OP wants it _has_ to
evaluate the first argument to setf. I never said that's not possible
to get the expected behavior. One "only" needs to define a setter for
'(if a b c)'.

> Implementation can easily extend setf behaviour. It doesn't matter
> whether compiled or interpreted code is running (CLISP can do both).
> 
> (defmacro setf-if ((_ a b c) d)
>   `(if ,a (setf ,b ,d) (setf ,c ,d)))

But that is _not_ extending setf, that's just creating a new special
syntax (with is perfectly fine of course).

 Cheers RalfD
From: Emilian
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131027648.121296.223580@g14g2000cwa.googlegroups.com>
(macroexpand '(setf (if t x y) 4))
(LET* ((#:G509 T) (#:G510 4)) (IF #:G509 (SETQ X #:G510) (SETQ Y
#:G510)))

Looks ok to me.

Let me get this straight: since SETF is a macro, you never expect it to
evaluate its first argument ?

Emilian

R. Mattes wrote:
> On Thu, 03 Nov 2005 13:39:03 +0000, Timofei Shatrov wrote:
>
> > On Thu, 03 Nov 2005 16:21:09 +0100, "R. Mattes" <··@mh-freiburg.de>
> > tried to confuse everyone with this message:
> >
> >
> >>Clisp is an interpreter - most Common Lisps are compilers.
> >>Your examples doesn't work on SBCL for example.
> >>Try:
> >>
> >> (macroexpand '(setf (if (< 1 (read) x y) 3))
> >>
> >>Hint: setf is a _macro_ that gets executed long before (if ...) gets
> >>evaluated ...
> >>
> >
> > But it doesn't have to be evaluated at the time of expansion.
>
> I don't understand this. For the semantic the OP wants it _has_ to
> evaluate the first argument to setf. I never said that's not possible
> to get the expected behavior. One "only" needs to define a setter for
> '(if a b c)'.
>
> > Implementation can easily extend setf behaviour. It doesn't matter
> > whether compiled or interpreted code is running (CLISP can do both).
> >
> > (defmacro setf-if ((_ a b c) d)
> >   `(if ,a (setf ,b ,d) (setf ,c ,d)))
>
> But that is _not_ extending setf, that's just creating a new special
> syntax (with is perfectly fine of course).
> 
>  Cheers RalfD
From: Bill Atkins
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131028016.151138.94140@g44g2000cwa.googlegroups.com>
That appears to be some kind of nonstandard clisp extension.  So the
answer to your question is: yes, you can use that syntax, but only in
CLISP or in a CL for which you've defined an if setter.

Macros don't technically evaluate any of their arguments.  They accept
s-expressions and then transform that code into some other
s-expression.  Evaluation doesn't happen until runtime.

In any case, placement of the argument doesn't affect what forms will
ultimately be evaluated; it's entirely up to the macro author.  In some
common forms like setf, push, incf, decf, etc. the first argument is
indeed never evaluated directly - it is transformed into some other
code that is evaluated at runtime.

Hope that made sense and didn't just make things more confusing. :)

Bill
From: Emilian
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131028569.156440.218110@z14g2000cwz.googlegroups.com>
Thanks for the reply. I do know how a macro works (or at least I think
so!).

My confusion was this: if IF returns a value then that _workable_ (setf
(if...)) in clisp shouldn't happen. If IF returns a setf-able place
then the example was ok in any common lisp implementation. But if IF
returns a "place" how come (+ (if..)) is right ?

I see now that SETF in clisp does some extra (nonstandard) actions for
an IF.

Thanks.

Bill Atkins wrote:
> That appears to be some kind of nonstandard clisp extension.  So the
> answer to your question is: yes, you can use that syntax, but only in
> CLISP or in a CL for which you've defined an if setter.
>
> Macros don't technically evaluate any of their arguments.  They accept
> s-expressions and then transform that code into some other
> s-expression.  Evaluation doesn't happen until runtime.
>
> In any case, placement of the argument doesn't affect what forms will
> ultimately be evaluated; it's entirely up to the macro author.  In some
> common forms like setf, push, incf, decf, etc. the first argument is
> indeed never evaluated directly - it is transformed into some other
> code that is evaluated at runtime.
>
> Hope that made sense and didn't just make things more confusing. :)
> 
> Bill
From: Peter Seibel
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <m28xw58y85.fsf@gigamonkeys.com>
"Emilian" <············@gmail.com> writes:

> Thanks for the reply. I do know how a macro works (or at least I think
> so!).
>
> My confusion was this: if IF returns a value then that _workable_ (setf
> (if...)) in clisp shouldn't happen. If IF returns a setf-able place
> then the example was ok in any common lisp implementation. But if IF
> returns a "place" how come (+ (if..)) is right ?

The thing is "setf-able places" are not first class objects. When we
say that (CAR X) is a setf-able place it doesn't mean that (CAR X)
returns a place; it just means the SETF macro knows what code it needs
to expand into in order to assign a new value to the "place" such that
after the assignment the same (CAR ...) form will return the new
value. For instance:

  (setf (car x) 10)

might expand into:

  (rplaca x 10)

In CLISP, SETF knows what to do with an IF form, namely expand something like this:

  (setf (if (zerop (random 10)) x y) 100)

into[1]:

  (if (zerop (random 10)) (setf x 100) (setf y 100))

but that is a CLISP extension. The official set of places defined in
the language standard is enumerated in section 5.1.2 of the CLHS.


-Peter

[1] The actual expansion is likely a bit more complex in order to deal
with the order of evaluation in the general case.

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: ·········@cern.ch
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <yzozmol1yi4.fsf@cern.ch>
Emilian> (macroexpand '(setf (if t x y) 4))
Emilian> (LET* ((#:G509 T) (#:G510 4)) (IF #:G509 (SETQ X #:G510) (SETQ Y
Emilian> #:G510)))

Emilian> Looks ok to me.

It is not, because it doesn't treat  (IF T X Y) as a "place"...

Emilian> Let me get this straight: since SETF is a macro, you never
Emilian> expect it to evaluate its first argument ?

Macros can do whatever they like to their arguments. SETF is supposed
to examine its first argument:

- if it is a symbol it expands to SETQ
- if it is a general "place" it expands to the appropriate SETF-expansion

* (macroexpand '(setf (if t x y) 4))
  (LET* ((#:G1458 T) (#:G1457 X) (#:G1456 Y))
    (MULTIPLE-VALUE-BIND (#:G1455) 4
      (FUNCALL #'(SETF IF) #:G1455 #:G1458 #:G1457 #:G1456)))

Ole
From: ··············@hotmail.com
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131026995.457569.14590@f14g2000cwb.googlegroups.com>
R. Mattes wrote:
> On Thu, 03 Nov 2005 13:39:03 +0000, Timofei Shatrov wrote:
>
> >
> > (defmacro setf-if ((_ a b c) d)
> >   `(if ,a (setf ,b ,d) (setf ,c ,d)))
>
> But that is _not_ extending setf, that's just creating a new special
> syntax (with is perfectly fine of course).


I question your "perfectly fine" comment.

Ordinarily, (if condition expr-1 expr-2) returns an ordinary
expression.

In the syntax

(setf (if flag x y) foo)

The value of the if, according to the usual definition, is NOT a place!
It returns ordinary Lisp values, corresponding either to the value of x
or the value of y. You can't set values to other values. You can only
set places to values.

Values are not places. This "extension" changes the semantics of if.

I applaud the original poster's Lispy instinct, but setf is a special
form, and one has to play by its rules.
From: R. Mattes
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <pan.2005.11.03.18.02.23.694192@mh-freiburg.de>
On Thu, 03 Nov 2005 07:02:52 -0800, ··············@hotmail.com wrote:

> 
> R. Mattes wrote:
>> On Thu, 03 Nov 2005 13:39:03 +0000, Timofei Shatrov wrote:
>>
>> >
>> > (defmacro setf-if ((_ a b c) d)
>> >   `(if ,a (setf ,b ,d) (setf ,c ,d)))
>>
>> But that is _not_ extending setf, that's just creating a new special
>> syntax (with is perfectly fine of course).
> 
> 
> I question your "perfectly fine" comment.
> 
> Ordinarily, (if condition expr-1 expr-2) returns an ordinary
> expression.

I'm sorry if my last comment wasn't clear. I think it's perfectly fine 
to create a new macro 'setf-if'. It's just not really relevant to the OP's
question.



> In the syntax
> 
> (setf (if flag x y) foo)
> 
> The value of the if, according to the usual definition, is NOT a place!
> It returns ordinary Lisp values, corresponding either to the value of x
> or the value of y. You can't set values to other values. You can only
> set places to values.

Regarding the '(setf (if a b c) val)' syntax: it actually doesn't matter
at all what (if a b c) evaluates to ("returns") since the first syntactic
expression to setf isn't evaluated (not at compile time and most likely
not at runtime).  And evaluation can't return places (or are places all a
sudden first class lisp objects?).

The first argument to setf is inspected by the macro transformer - a place
is just something your Lisp implementation "knows" how to transform into
code that updates the value of a binding. As we have seen CLisp "knows"
how to do that for an sexpr of the form '(if a b c)' but that isn't
guaranteed by the standard.
 

> Values are not places. This "extension" changes the semantics of if.

Disputable, I'd say. 
  
> I applaud the original poster's Lispy instinct, but setf is a special
> form, and one has to play by its rules.

Yes, but the rule _allows_ setf to be augmented for more syntactic forms.
 

 Cheers, RalfD
From: Pisin Bootvong
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131073410.676568.58090@f14g2000cwb.googlegroups.com>
I agree, This is the key:

"a place is just something your Lisp implementation "knows" how to
transform into code that updates the value of a binding."

Place has no meaning at run time, it is only there at evaluation time.

Think about GETHASH, how is it possible that gethash is a function that
return a value and you can still do

 (setf (gethash hash 'key) 10)

Or SLOT-VALUE, CAR, CDR or your object's accessor function.

All of them are function that return value; you can try type it in REPL
and it will return value, not place.
Yet SETF work with it.

SETF just know how to handle these function expression and turn it to
the correct function.

So in source code:

(setf (gethash hash 'key) 10)

is actually transformed to this ACTUAL source code.

(sethash hash 'key 10)

I don't think (SETF (if x y z) 10) is invalid, but it surely is
confusing for me.
From: Pisin Bootvong
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <1131087944.884799.198510@f14g2000cwb.googlegroups.com>
> Place has no meaning at run time, it is only there at evaluation time.
> 

Compile time, I meant :(
From: Barry Margolin
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <barmar-A6462C.19122603112005@comcast.dca.giganews.com>
In article <······························@mh-freiburg.de>,
 "R. Mattes" <··@mh-freiburg.de> wrote:

> On Thu, 03 Nov 2005 13:39:03 +0000, Timofei Shatrov wrote:
> 
> > On Thu, 03 Nov 2005 16:21:09 +0100, "R. Mattes" <··@mh-freiburg.de>
> > tried to confuse everyone with this message:
> > 
> > 
> >>Clisp is an interpreter - most Common Lisps are compilers.
> >>Your examples doesn't work on SBCL for example.
> >>Try:
> >>
> >> (macroexpand '(setf (if (< 1 (read) x y) 3))
> >>
> >>Hint: setf is a _macro_ that gets executed long before (if ...) gets
> >>evaluated ...
> >>
> > 
> > But it doesn't have to be evaluated at the time of expansion.
> 
> I don't understand this. For the semantic the OP wants it _has_ to
> evaluate the first argument to setf.

No it doesn't.  It just has to expand into code that performs the same 
conditional.  This can easily be done with DEFSETF:

(defsetf if (cond place1 place2) (value)
  `(if ,cond
       (setf ,place1 ,value)
       (setf ,place2 ,value)))

Note, however, that this is not actually portable because Section 
11.1.2.1.2 of the ANSI spec prohibits programs from defining SETF 
expanders on symbols in the COMMON-LISP package.  But you can do the 
same thing with your own symbol, e.g.

(defsetf my-if ...)

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Kalle Olavi Niemitalo
Subject: Re: (setf (if c x y) val)
Date: 
Message-ID: <87pspg7trb.fsf@Astalo.kon.iki.fi>
Barry Margolin <······@alum.mit.edu> writes:

> It just has to expand into code that performs the same 
> conditional.  This can easily be done with DEFSETF:
>
> (defsetf if (cond place1 place2) (value)
>   `(if ,cond
>        (setf ,place1 ,value)
>        (setf ,place2 ,value)))

DEFSETF won't do; you need DEFINE-SETF-EXPANDER.  In SBCL 0.9.3.51:

(defmacro my-if (&rest args) `(if ,@args))
(defsetf my-if ...)

(macroexpand '(setf (my-if a b c) x))
=> (LET* ((#:G3905 A) (#:G3906 B) (#:G3907 C))
     (MULTIPLE-VALUE-BIND (#:G3908) X
       (IF #:G3905 (SETF #:G3906 #:G3908) (SETF #:G3907 #:G3908))))

(macroexpand '(push x (my-if a b c)))
=> (LET* ((#:G3913 X)
          (#:G3909 A)
          (#:G3910 B)
          (#:G3911 C)
          (#:G3912 (CONS #:G3913 (MY-IF #:G3909 #:G3910 #:G3911))))
     (IF #:G3909 (SETF #:G3910 #:G3912) (SETF #:G3911 #:G3912)))

The expansion evaluates the arguments unconditionally and stores
the result to to the wrong variables.

Prompt.franz.com running Allegro CL 6.2 behaved similarly.
(I believe SBCL and Allegro CL are entirely correct in doing this.)