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))
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
"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.
"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
"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.
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
"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.
"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