1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Body/m_defset.htm
2024-04-01 10:24:07 +02:00

133 lines
13 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Macro DEFSETF</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="m_defi_2.htm">
<LINK REL=UP HREF="c_data_a.htm">
<LINK REL=NEXT HREF="m_defi_3.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="m_defi_2.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="c_data_a.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="m_defi_3.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<A NAME="defsetf"><I>Macro</I> <B>DEFSETF</B></A> <P>
<P>
<P><B>Syntax:</B><P>
<P>
The ``short form'': <P>
<B>defsetf</B> <I>access-fn update-fn [documentation]</I><P> =&gt; <I>access-fn</I><P>
<P>
The ``long form'': <P>
<B>defsetf</B> <I>access-fn lambda-list (<I>store-variable</I><B>*</B>) [[<I>declaration</I><B>*</B> | <I>documentation</I>]] <I>form</I><B>*</B></I><P> =&gt; <I>access-fn</I><P>
<P>
<P><B>Arguments and Values:</B><P>
<P>
<I>access-fn</I>---a <A REL=DEFINITION HREF="26_glo_s.htm#symbol"><I>symbol</I></A> which names a <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>function</I></A> or a <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macro</I></A>. <P>
<I>update-fn</I>---a <A REL=DEFINITION HREF="26_glo_s.htm#symbol"><I>symbol</I></A> naming a <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>function</I></A> or <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macro</I></A>. <P>
<I>lambda-list</I>---a <A REL=DEFINITION HREF="26_glo_d.htm#defsetf_lambda_list"><I>defsetf lambda list</I></A>. <P>
<I>store-variable</I>---a <A REL=DEFINITION HREF="26_glo_s.htm#symbol"><I>symbol</I></A> (a <A REL=DEFINITION HREF="26_glo_v.htm#variable"><I>variable</I></A> <A REL=DEFINITION HREF="26_glo_n.htm#name"><I>name</I></A>). <P>
<I>declaration</I>---a <A REL=DEFINITION HREF="s_declar.htm#declare"><B>declare</B></A> <A REL=DEFINITION HREF="26_glo_e.htm#expression"><I>expression</I></A>; not evaluated. <P>
<I>documentation</I>---a <A REL=DEFINITION HREF="26_glo_s.htm#string"><I>string</I></A>; not evaluated. <P>
<I>form</I>---a <A REL=DEFINITION HREF="26_glo_f.htm#form"><I>form</I></A>. <P>
<P><B>Description:</B><P>
<P>
<A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> defines how to <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A> a <A REL=DEFINITION HREF="26_glo_p.htm#place"><I>place</I></A> of the form <TT>(</TT><I>access-fn</I><TT> ...)</TT> for relatively simple cases. (See <A REL=DEFINITION HREF="m_defi_3.htm#define-setf-expander"><B>define-setf-expander</B></A> for more general access to this facility.) It must be the case that the <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>function</I></A> or <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macro</I></A> named by <I>access-fn</I> evaluates all of its arguments. <P>
<A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> may take one of two forms, called the ``short form'' and the ``long form,'' which are distinguished by the <A REL=DEFINITION HREF="26_glo_t.htm#type"><I>type</I></A> of the second <A REL=DEFINITION HREF="26_glo_a.htm#argument"><I>argument</I></A>. <P>
When the short form is used, <I>update-fn</I> must name a <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>function</I></A> (or <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macro</I></A>) that takes one more argument than <I>access-fn</I> takes. When <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A> is given a <A REL=DEFINITION HREF="26_glo_p.htm#place"><I>place</I></A> that is a call on <I>access-fn</I>, it expands into a call on <I>update-fn</I> that is given all the arguments to <I>access-fn</I> and also, as its last argument, the new value (which must be returned by <I>update-fn</I> as its value). <P>
The long form <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> resembles <A REL=DEFINITION HREF="m_defmac.htm#defmacro"><B>defmacro</B></A>. The <I>lambda-list</I> describes the arguments of <I>access-fn</I>. The <I>store-variables</I> describe the value or values to be stored into the <A REL=DEFINITION HREF="26_glo_p.htm#place"><I>place</I></A>. The <I>body</I> must compute the expansion of a <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A> of a call on <I>access-fn</I>. The expansion function is defined in the same <A REL=DEFINITION HREF="26_glo_l.htm#lexical_environment"><I>lexical environment</I></A> in which the <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> <A REL=DEFINITION HREF="26_glo_f.htm#form"><I>form</I></A> appears. <P>
During the evaluation of the <I>forms</I>, the variables in the <I>lambda-list</I> and the <I>store-variables</I> are bound to names of temporary variables, generated as if by <A REL=DEFINITION HREF="f_gensym.htm#gensym"><B>gensym</B></A> or <A REL=DEFINITION HREF="f_gentem.htm#gentemp"><B>gentemp</B></A>, that will be bound by the expansion of <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A> to the values of those <A REL=DEFINITION HREF="26_glo_s.htm#subform"><I>subforms</I></A>. This binding permits the <I>forms</I> to be written without regard for order-of-evaluation issues. <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> arranges for the temporary variables to be optimized out of the final result in cases where that is possible. <P>
The body code in <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> is implicitly enclosed in a <A REL=DEFINITION HREF="26_glo_b.htm#block"><I>block</I></A> whose name is <I>access-fn</I> <P>
<A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> ensures that <A REL=DEFINITION HREF="26_glo_s.htm#subform"><I>subforms</I></A> of the <A REL=DEFINITION HREF="26_glo_p.htm#place"><I>place</I></A> are evaluated exactly once. <P>
<I>Documentation</I> is attached to <I>access-fn</I> as a <A REL=DEFINITION HREF="26_glo_d.htm#documentation_string"><I>documentation string</I></A> of kind <A REL=DEFINITION HREF="a_setf.htm#setf"><B>setf</B></A>. <P>
If a <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> <A REL=DEFINITION HREF="26_glo_f.htm#form"><I>form</I></A> appears as a <A REL=DEFINITION HREF="26_glo_t.htm#top_level_form"><I>top level form</I></A>, the <A REL=DEFINITION HREF="26_glo_c.htm#compiler"><I>compiler</I></A> must make the <A REL=DEFINITION HREF="26_glo_s.htm#setf_expander"><I>setf expander</I></A> available so that it may be used to expand calls to <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A> later on in the <A REL=DEFINITION HREF="26_glo_f.htm#file"><I>file</I></A>. Users must ensure that the <I>forms</I>, if any, can be evaluated at compile time if the <I>access-fn</I> is used in a <A REL=DEFINITION HREF="26_glo_p.htm#place"><I>place</I></A> later in the same <A REL=DEFINITION HREF="26_glo_f.htm#file"><I>file</I></A>. The <A REL=DEFINITION HREF="26_glo_c.htm#compiler"><I>compiler</I></A> must make these <A REL=DEFINITION HREF="26_glo_s.htm#setf_expander"><I>setf expanders</I></A> available to compile-time calls to <A REL=DEFINITION HREF="f_get_se.htm#get-setf-expansion"><B>get-setf-expansion</B></A> when its <I>environment</I> argument is a value received as the <A REL=DEFINITION HREF="26_glo_e.htm#environment_parameter"><I>environment parameter</I></A> of a <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macro</I></A>. <P>
<P><B>Examples:</B><P>
The effect of <P>
<PRE>
(defsetf symbol-value set)
</PRE>
</TT> is built into the Common Lisp system. This causes the form <TT>(setf (symbol-value foo) fu)</TT> to expand into <TT>(set foo fu)</TT>. <P>
Note that <P>
<PRE>
(defsetf car rplaca)
</PRE>
</TT> would be incorrect because <A REL=DEFINITION HREF="f_rplaca.htm#rplaca"><B>rplaca</B></A> does not return its last argument. <P>
<PRE>
(defun middleguy (x) (nth (truncate (1- (list-length x)) 2) x)) =&gt; MIDDLEGUY
(defun set-middleguy (x v)
(unless (null x)
(rplaca (nthcdr (truncate (1- (list-length x)) 2) x) v))
v) =&gt; SET-MIDDLEGUY
(defsetf middleguy set-middleguy) =&gt; MIDDLEGUY
(setq a (list 'a 'b 'c 'd)
b (list 'x)
c (list 1 2 3 (list 4 5 6) 7 8 9)) =&gt; (1 2 3 (4 5 6) 7 8 9)
(setf (middleguy a) 3) =&gt; 3
(setf (middleguy b) 7) =&gt; 7
(setf (middleguy (middleguy c)) 'middleguy-symbol) =&gt; MIDDLEGUY-SYMBOL
a =&gt; (A 3 C D)
b =&gt; (7)
c =&gt; (1 2 3 (4 MIDDLEGUY-SYMBOL 6) 7 8 9)
</PRE>
</TT> <P>
An example of the use of the long form of <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A>: <P>
<PRE>
(defsetf subseq (sequence start &amp;optional end) (new-sequence)
`(progn (replace ,sequence ,new-sequence
:start1 ,start :end1 ,end)
,new-sequence)) =&gt; SUBSEQ
</PRE>
</TT> <P>
<PRE>
(defvar *xy* (make-array '(10 10)))
(defun xy (&amp;key ((x x) 0) ((y y) 0)) (aref *xy* x y)) =&gt; XY
(defun set-xy (new-value &amp;key ((x x) 0) ((y y) 0))
(setf (aref *xy* x y) new-value)) =&gt; SET-XY
(defsetf xy (&amp;key ((x x) 0) ((y y) 0)) (store)
`(set-xy ,store 'x ,x 'y ,y)) =&gt; XY
(get-setf-expansion '(xy a b))
=&gt; (#:t0 #:t1),
(a b),
(#:store),
((lambda (&amp;key ((x #:x)) ((y #:y)))
(set-xy #:store 'x #:x 'y #:y))
#:t0 #:t1),
(xy #:t0 #:t1)
(xy 'x 1) =&gt; NIL
(setf (xy 'x 1) 1) =&gt; 1
(xy 'x 1) =&gt; 1
(let ((a 'x) (b 'y))
(setf (xy a 1 b 2) 3)
(setf (xy b 5 a 9) 14))
=&gt; 14
(xy 'y 0 'x 1) =&gt; 1
(xy 'x 1 'y 2) =&gt; 3
</PRE>
</TT> <P>
<P><B>Affected By:</B> None.
<P>
<P><B>Exceptional Situations:</B> None.
<P>
<P><B>See Also:</B><P>
<P>
<A REL=DEFINITION HREF="f_docume.htm#documentation"><B>documentation</B></A>, <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A>, <A REL=DEFINITION HREF="m_defi_3.htm#define-setf-expander"><B>define-setf-expander</B></A>, <A REL=DEFINITION HREF="f_get_se.htm#get-setf-expansion"><B>get-setf-expansion</B></A>, <A REL=CHILD HREF="05_a.htm">Section 5.1 (Generalized Reference)</A>, <A REL=CHILD HREF="03_dk.htm">Section 3.4.11 (Syntactic Interaction of Documentation Strings and Declarations)</A> <P>
<P><B>Notes:</B><P>
<P>
<I>forms</I> must include provision for returning the correct value (the value or values of <I>store-variable</I>). This is handled by <I>forms</I> rather than by <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> because in many cases this value can be returned at no extra cost, by calling a function that simultaneously stores into the <A REL=DEFINITION HREF="26_glo_p.htm#place"><I>place</I></A> and returns the correct value. <P>
A <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A> of a call on <I>access-fn</I> also evaluates all of <I>access-fn</I>'s arguments; it cannot treat any of them specially. This means that <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> cannot be used to describe how to store into a <A REL=DEFINITION HREF="26_glo_g.htm#generalized_reference"><I>generalized reference</I></A> to a byte, such as <TT>(ldb field reference)</TT>. <A REL=DEFINITION HREF="m_defi_3.htm#define-setf-expander"><B>define-setf-expander</B></A> is used to handle situations that do not fit the restrictions imposed by <A REL=DEFINITION HREF="#defsetf"><B>defsetf</B></A> and gives the user additional control. <P>
<P>
<P><HR>The following <A REL=META HREF="../Front/X3J13Iss.htm">X3J13 cleanup issues</A>, <I>not part of the specification</I>, apply to this section:<P><UL><LI> <A REL=CHILD HREF="../Issues/iss308.htm">SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS</A><LI> <A REL=CHILD HREF="../Issues/iss059.htm">COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY</A><LI> <A REL=CHILD HREF="../Issues/iss161.htm">FLET-IMPLICIT-BLOCK:YES</A><LI> <A REL=CHILD HREF="../Issues/iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL:ALLOW</A><LI> <A REL=CHILD HREF="../Issues/iss309.htm">SETF-MULTIPLE-STORE-VARIABLES:ALLOW</A><LI> <A REL=CHILD HREF="../Issues/iss097.htm">DECLS-AND-DOC</A><P></UL><HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>