From: Andrew Baine
Subject: first arg to setf an if form: possible?
Date: 
Message-ID: <1142658109.071659.241670@j33g2000cwa.googlegroups.com>
I was searching this group to look at queue implementations
and I became confused about setf

Can setf be used to set one place if some predicate is true,
some other place else?

See below for a trivial example (and failure)

CL-USER> (let ((x 0)
	       (y 0))
	   (if (zerop 1)
	       (setf x 10)
	       (setf y 10))
	   (list x y))
(0 10)
CL-USER> (let ((x 0)
	       (y 0))
	   (setf (if (zerop 1) 'x 'y) 10)
	   (list x y))

; in: LAMBDA NIL
;     (SETF (IF (ZEROP 1) 'X 'Y) 10)
; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL
; ==>
;   (SB-C::%FUNCALL #'(SETF IF) #:G0 #:G3 #:G2 #:G1)
;
; caught WARNING:
;   The function (SETF IF) is undefined, and its name is reserved by
ANSI CL so
;   that even if it were defined later, the code doing so would not be
portable.
;
; caught STYLE-WARNING:
;   This function is undefined:
;     (SETF IF)
;
; compilation unit finished
;   caught 1 WARNING condition
;   caught 1 STYLE-WARNING condition


With respect to the enqueue operation, if the head of a queue is null,
you set the head to point to a new node.  Else you set the cdr of the
tail to the new node.

(defmethod enqueue (obj (queue queue))
   (with-slots (head tail) queue
     (let ((new-tail (cons obj nil)))
       (if (null head)
           (setf head new-tail)
           (setf (cdr tail) new-tail))
       (setf tail new-tail)
     obj))

From: David Sletten
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <T0NSf.3655$w86.916@tornado.socal.rr.com>
Andrew Baine wrote:

> I was searching this group to look at queue implementations
> and I became confused about setf
> 
> Can setf be used to set one place if some predicate is true,
> some other place else?
> 
> See below for a trivial example (and failure)
> 
> CL-USER> (let ((x 0)
> 	       (y 0))
> 	   (if (zerop 1)
> 	       (setf x 10)
> 	       (setf y 10))
> 	   (list x y))
> (0 10)
> CL-USER> (let ((x 0)
> 	       (y 0))
> 	   (setf (if (zerop 1) 'x 'y) 10)
> 	   (list x y))
> 
> ; in: LAMBDA NIL
> ;     (SETF (IF (ZEROP 1) 'X 'Y) 10)
> ; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL
> ; ==>
> ;   (SB-C::%FUNCALL #'(SETF IF) #:G0 #:G3 #:G2 #:G1)
> ;
> ; caught WARNING:
> ;   The function (SETF IF) is undefined, and its name is reserved by
> ANSI CL so
> ;   that even if it were defined later, the code doing so would not be
> portable.
> ;
> ; caught STYLE-WARNING:
> ;   This function is undefined:
> ;     (SETF IF)
> ;
> ; compilation unit finished
> ;   caught 1 WARNING condition
> ;   caught 1 STYLE-WARNING condition
> 
> 
> With respect to the enqueue operation, if the head of a queue is null,
> you set the head to point to a new node.  Else you set the cdr of the
> tail to the new node.
> 
> (defmethod enqueue (obj (queue queue))
>    (with-slots (head tail) queue
>      (let ((new-tail (cons obj nil)))
>        (if (null head)
>            (setf head new-tail)
>            (setf (cdr tail) new-tail))
>        (setf tail new-tail)
>      obj))
> 

Taking a look at kinds of places:
http://www.lispworks.com/documentation/HyperSpec/Body/05_ab.htm
it looks as though section 5.1.2.9 is the only potentially relevant section:
http://www.lispworks.com/documentation/HyperSpec/Body/05_abi.htm
However, it discusses expansion into a call to the function (setf if), 
which as you saw above doesn't exist.

Here's a good article about queues in Lisp:
http://www.norvig.com/TR91-04.pdf

Aloha,
David Sletten
From: Pascal Bourguignon
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <8764mcaqrk.fsf@thalassa.informatimago.com>
"Andrew Baine" <·······@gmail.com> writes:

> I was searching this group to look at queue implementations
> and I became confused about setf
>
> Can setf be used to set one place if some predicate is true,
> some other place else?
>
> See below for a trivial example (and failure)
>
> CL-USER> (let ((x 0)
> 	       (y 0))
> 	   (if (zerop 1)
> 	       (setf x 10)
> 	       (setf y 10))
> 	   (list x y))
> (0 10)

(setf if) is not standard.  
But clisp implements one, and you could implement yours.  Here is clisp's one:


(define-setf-expander IF (&whole whole-form
                          condition t-form f-form &environment env)
  (let ((conditionvar (gensym)))
    (multiple-value-bind (T-temps T-subforms T-stores T-setterform T-getterform)
        (get-setf-expansion t-form env)
      (multiple-value-bind (F-temps F-subforms F-stores F-setterform F-getterform)
          (get-setf-expansion f-form env)
        (unless (eql (length T-stores) (length F-stores))
          (error-of-type 'source-program-error
            :form whole-form
            :detail whole-form
            (TEXT "SETF place ~S expects different numbers of values in the true and false branches (~D vs. ~D values).")
            (list 'IF condition t-form f-form) (length T-stores) (length F-stores)))
        (values
          `(,conditionvar
            ,@T-temps
            ,@F-temps
           )
          `(,condition
            ,@(mapcar #'(lambda (x) `(IF ,conditionvar ,x)) T-subforms)
            ,@(mapcar #'(lambda (x) `(IF (NOT ,conditionvar) ,x)) F-subforms)
           )
          T-stores
          `(IF ,conditionvar ,T-setterform 
                  ,(sublis-in-form (mapcar #'cons F-stores T-stores) F-setterform))
          `(IF ,conditionvar ,T-getterform ,F-getterform))))))




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

HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.
From: Andrew Baine
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <1142890730.601809.190460@u72g2000cwu.googlegroups.com>
Thank you both.

Andrew
From: Geoffrey Summerhayes
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <1rKTf.4443$ji6.225231@news20.bellglobal.com>
"Pascal Bourguignon" <······@informatimago.com> wrote in message ···················@thalassa.informatimago.com...
>
> (setf if) is not standard.
> But clisp implements one, and you could implement yours.  Here is clisp's one:
>
>
> (define-setf-expander IF (&whole whole-form
>                          condition t-form f-form &environment env)

This came up a long time ago, the general consensus
was in favor of shadowing IF in a seperate package
and modifying it rather than playing with the CL package.

--
Geoff
From: Pascal Bourguignon
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <87slpc2wse.fsf@thalassa.informatimago.com>
"Geoffrey Summerhayes" <·······@NhOoStPmAaMil.com> writes:

> "Pascal Bourguignon" <······@informatimago.com> wrote in message ···················@thalassa.informatimago.com...
>>
>> (setf if) is not standard.
>> But clisp implements one, and you could implement yours.  Here is clisp's one:
>>
>>
>> (define-setf-expander IF (&whole whole-form
>>                          condition t-form f-form &environment env)
>
> This came up a long time ago, the general consensus
> was in favor of shadowing IF in a seperate package
> and modifying it rather than playing with the CL package.

Yes, but in this thread, we're not discussing packages, but setf expanders.

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

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
From: Geoffrey Summerhayes
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <1142959514.821111.174500@e56g2000cwe.googlegroups.com>
Pascal Bourguignon wrote:
> "Geoffrey Summerhayes" <·······@NhOoStPmAaMil.com> writes:
>
> > "Pascal Bourguignon" <······@informatimago.com> wrote in message ···················@thalassa.informatimago.com...
> >>
> >> (setf if) is not standard.
> >> But clisp implements one, and you could implement yours.  Here is clisp's one:
> >>
> >>
> >> (define-setf-expander IF (&whole whole-form
> >>                          condition t-form f-form &environment env)
> >
> > This came up a long time ago, the general consensus
> > was in favor of shadowing IF in a seperate package
> > and modifying it rather than playing with the CL package.
>
> Yes, but in this thread, we're not discussing packages, but setf expanders.
>

Regardless, writing a DEFINE-SETF-EXPANDER on CL:IF makes
a program non-conforming, undefined behaviour, yada yada, scary
stuff. See section 11.1.2.1.2 HS

--
Geoff
From: Pascal Bourguignon
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <877j6n3ebf.fsf@thalassa.informatimago.com>
"Geoffrey Summerhayes" <·······@hotmail.com> writes:
> Pascal Bourguignon wrote:
>> "Geoffrey Summerhayes" <·······@NhOoStPmAaMil.com> writes:
>>
>> > "Pascal Bourguignon" <······@informatimago.com> wrote in message ···················@thalassa.informatimago.com...
>> >>
>> >> (setf if) is not standard.
>> >> But clisp implements one, and you could implement yours.  Here is clisp's one:
>> >>
>> >>
>> >> (define-setf-expander IF (&whole whole-form
>> >>                          condition t-form f-form &environment env)
>> >
>> > This came up a long time ago, the general consensus
>> > was in favor of shadowing IF in a seperate package
>> > and modifying it rather than playing with the CL package.
>>
>> Yes, but in this thread, we're not discussing packages, but setf expanders.
>>
>
> Regardless, writing a DEFINE-SETF-EXPANDER on CL:IF makes
> a program non-conforming, undefined behaviour, yada yada, scary
> stuff. See section 11.1.2.1.2 HS

Why are you assuming the IF in the above form is CL:IF ?

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

PLEASE NOTE: Some quantum physics theories suggest that when the
consumer is not directly observing this product, it may cease to
exist or will exist only in a vague and undetermined state.
From: Geoffrey Summerhayes
Subject: Re: first arg to setf an if form: possible?
Date: 
Message-ID: <pIXTf.4810$ji6.273286@news20.bellglobal.com>
"Pascal Bourguignon" <······@informatimago.com> wrote in message 
···················@thalassa.informatimago.com...
> "Geoffrey Summerhayes" <·······@hotmail.com> writes:
>>
>> Regardless, writing a DEFINE-SETF-EXPANDER on CL:IF makes
>> a program non-conforming, undefined behaviour, yada yada, scary
>> stuff. See section 11.1.2.1.2 HS
>
> Why are you assuming the IF in the above form is CL:IF ?

Because if the OP didn't know to use DEFINE-SETF-EXPANDER
he's unlikely to realize, even with the warning, that
conformity requires shadowing.

Gawd, I sound like a SLW. :(

--
Geoff