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

167 lines
16 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: Special Operator FLET, LABELS, MACROLET</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="f_fmakun.htm">
<LINK REL=UP HREF="c_data_a.htm">
<LINK REL=NEXT HREF="f_funcal.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="f_fmakun.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="f_funcal.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<A NAME="flet"><A NAME="labels"><A NAME="macrolet"><I>Special Operator</I> <B>FLET, LABELS, MACROLET</B></A></A></A> <P>
<P>
<P><B>Syntax:</B><P>
<P>
<B>flet</B> <I>((<I>function-name</I> <I>lambda-list</I> [[<I>local-declaration</I><B>*</B> | <I>local-documentation</I>]] <I>local-form</I><B>*</B>)<B>*</B>) <I>declaration</I><B>*</B> <I>form</I><B>*</B></I><P> =&gt; <I><I>result</I><B>*</B></I><P>
<P>
<B>labels</B> <I>((<I>function-name</I> <I>lambda-list</I> [[<I>local-declaration</I><B>*</B> | <I>local-documentation</I>]] <I>local-form</I><B>*</B>)<B>*</B>) <I>declaration</I><B>*</B> <I>form</I><B>*</B></I><P> =&gt; <I><I>result</I><B>*</B></I><P>
<P>
<B>macrolet</B> <I>((<I>name</I> <I>lambda-list</I> [[<I>local-declaration</I><B>*</B> | <I>local-documentation</I>]] <I>local-form</I><B>*</B>)<B>*</B>) <I>declaration</I><B>*</B> <I>form</I><B>*</B></I><P> =&gt; <I><I>result</I><B>*</B></I><P>
<P>
<P><B>Arguments and Values:</B><P>
<P>
<I>function-name</I>---a <A REL=DEFINITION HREF="26_glo_f.htm#function_name"><I>function name</I></A>. <P>
<I>name</I>---a <A REL=DEFINITION HREF="26_glo_s.htm#symbol"><I>symbol</I></A>. <P>
<I>lambda-list</I>---a <A REL=DEFINITION HREF="26_glo_l.htm#lambda_list"><I>lambda list</I></A>; for <A REL=DEFINITION HREF="#flet"><B>flet</B></A> and <A REL=DEFINITION HREF="#labels"><B>labels</B></A>, it is an <A REL=DEFINITION HREF="26_glo_o.htm#ordinary_lambda_list"><I>ordinary lambda list</I></A>; for <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A>, it is a <A REL=DEFINITION HREF="26_glo_m.htm#macro_lambda_list"><I>macro lambda list</I></A>. <P>
<I>local-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>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>local-documentation</I>---a <A REL=DEFINITION HREF="26_glo_s.htm#string"><I>string</I></A>; not evaluated. <P>
<I>local-forms</I>, <I>forms</I>---an <A REL=DEFINITION HREF="26_glo_i.htm#implicit_progn"><I>implicit progn</I></A>. <P>
<I>results</I>---the <A REL=DEFINITION HREF="26_glo_v.htm#value"><I>values</I></A> of the <I>forms</I>. <P>
<P><B>Description:</B><P>
<P>
<A REL=DEFINITION HREF="#flet"><B>flet</B></A>, <A REL=DEFINITION HREF="#labels"><B>labels</B></A>, and <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> define local <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A> and <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macros</I></A>, and execute <I>forms</I> using the local definitions. <I>Forms</I> are executed in order of occurrence. <P>
The body forms (but not the <A REL=DEFINITION HREF="26_glo_l.htm#lambda_list"><I>lambda list</I></A>) of each <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>function</I></A> created by <A REL=DEFINITION HREF="#flet"><B>flet</B></A> and <A REL=DEFINITION HREF="#labels"><B>labels</B></A> and each <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macro</I></A> created by <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> are enclosed in an <A REL=DEFINITION HREF="26_glo_i.htm#implicit_block"><I>implicit block</I></A> whose name is the <A REL=DEFINITION HREF="26_glo_f.htm#function_block_name"><I>function block name</I></A> of the <I>function-name</I> or <I>name</I>, as appropriate. <P>
The scope of the <I>declarations</I> between the list of local function/macro definitions and the body <I>forms</I> in <A REL=DEFINITION HREF="#flet"><B>flet</B></A> and <A REL=DEFINITION HREF="#labels"><B>labels</B></A> does not include the bodies of the locally defined <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A>, except that for <A REL=DEFINITION HREF="#labels"><B>labels</B></A>, any <A REL=DEFINITION HREF="d_inline.htm#inline"><B>inline</B></A>, <A REL=DEFINITION HREF="d_inline.htm#notinline"><B>notinline</B></A>, or <A REL=DEFINITION HREF="d_ftype.htm#ftype"><B>ftype</B></A> declarations that refer to the locally defined functions do apply to the local function bodies. That is, their <A REL=DEFINITION HREF="26_glo_s.htm#scope"><I>scope</I></A> is the same as the function name that they affect. The scope of these <I>declarations</I> does not include the bodies of the macro expander functions defined by <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A>. <P>
<P><DL><DT><B>flet</B> <P><DD>
<A REL=DEFINITION HREF="#flet"><B>flet</B></A> defines locally named <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A> and executes a series of <I>forms</I> with these definition <A REL=DEFINITION HREF="26_glo_b.htm#binding"><I>bindings</I></A>. Any number of such local <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A> can be defined. <P>
The <A REL=DEFINITION HREF="26_glo_s.htm#scope"><I>scope</I></A> of the name <A REL=DEFINITION HREF="26_glo_b.htm#binding"><I>binding</I></A> encompasses only the body. Within the body of <A REL=DEFINITION HREF="#flet"><B>flet</B></A>, <I>function-names</I> matching those defined by <A REL=DEFINITION HREF="#flet"><B>flet</B></A> refer to the locally defined <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A> rather than to the global function definitions of the same name. Also, within the scope of <A REL=DEFINITION HREF="#flet"><B>flet</B></A>, global <A REL=DEFINITION HREF="26_glo_s.htm#setf_expander"><I>setf expander</I></A> definitions of the <I>function-name</I> defined by <A REL=DEFINITION HREF="#flet"><B>flet</B></A> do not apply. Note that this applies to <TT>(defsetf </TT><I>f</I><TT> ...)</TT>, not <TT>(defmethod (setf </TT><I>f</I><TT>) ...)</TT>. <P>
The names of <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A> defined by <A REL=DEFINITION HREF="#flet"><B>flet</B></A> are in the <A REL=DEFINITION HREF="26_glo_l.htm#lexical_environment"><I>lexical environment</I></A>; they retain their local definitions only within the body of <A REL=DEFINITION HREF="#flet"><B>flet</B></A>. The function definition bindings are visible only in the body of <A REL=DEFINITION HREF="#flet"><B>flet</B></A>, not the definitions themselves. Within the function definitions, local function names that match those being defined refer to <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A> or <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macros</I></A> defined outside the <A REL=DEFINITION HREF="#flet"><B>flet</B></A>. <A REL=DEFINITION HREF="#flet"><B>flet</B></A> can locally <A REL=DEFINITION HREF="26_glo_s.htm#shadow"><I>shadow</I></A> a global function name, and the new definition can refer to the global definition. <P>
Any <I>local-documentation</I> is attached to the corresponding local <I>function</I> (if one is actually created) as a <A REL=DEFINITION HREF="26_glo_d.htm#documentation_string"><I>documentation string</I></A>. <P>
<DT><B>labels</B> <P><DD>
<A REL=DEFINITION HREF="#labels"><B>labels</B></A> is equivalent to <A REL=DEFINITION HREF="#flet"><B>flet</B></A> except that the scope of the defined function names for <A REL=DEFINITION HREF="#labels"><B>labels</B></A> encompasses the function definitions themselves as well as the body. <P>
<DT><B>macrolet</B> <P><DD>
<A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> establishes local <A REL=DEFINITION HREF="26_glo_m.htm#macro"><I>macro</I></A> definitions, using the same format used by <A REL=DEFINITION HREF="m_defmac.htm#defmacro"><B>defmacro</B></A>. <P>
Within the body of <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A>, global <A REL=DEFINITION HREF="26_glo_s.htm#setf_expander"><I>setf expander</I></A> definitions of the <I>names</I> defined by the <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> do not apply; rather, <A REL=DEFINITION HREF="m_setf_.htm#setf"><B>setf</B></A> expands the <A REL=DEFINITION HREF="26_glo_m.htm#macro_form"><I>macro form</I></A> and recursively process the resulting <A REL=DEFINITION HREF="26_glo_f.htm#form"><I>form</I></A>. <P>
The macro-expansion functions defined by <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> are defined in the <A REL=DEFINITION HREF="26_glo_l.htm#lexical_environment"><I>lexical environment</I></A> in which the <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> form appears. Declarations and <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> and <A REL=DEFINITION HREF="s_symbol.htm#symbol-macrolet"><B>symbol-macrolet</B></A> definitions affect the local macro definitions in a <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A>, but the consequences are undefined if the local macro definitions reference any local <A REL=DEFINITION HREF="26_glo_v.htm#variable"><I>variable</I></A> or <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>function</I></A> <A REL=DEFINITION HREF="26_glo_b.htm#binding"><I>bindings</I></A> that are visible in that <A REL=DEFINITION HREF="26_glo_l.htm#lexical_environment"><I>lexical environment</I></A>. <P>
Any <I>local-documentation</I> is attached to the corresponding local <I>macro function</I> as a <A REL=DEFINITION HREF="26_glo_d.htm#documentation_string"><I>documentation string</I></A>. <P>
<P></DL><P>
<P><B>Examples:</B><P>
<P>
<PRE>
(defun foo (x flag)
(macrolet ((fudge (z)
;The parameters x and flag are not accessible
; at this point; a reference to flag would be to
; the global variable of that name.
` (if flag (* ,z ,z) ,z)))
;The parameters x and flag are accessible here.
(+ x
(fudge x)
(fudge (+ x 1)))))
==
(defun foo (x flag)
(+ x
(if flag (* x x) x)
(if flag (* (+ x 1) (+ x 1)) (+ x 1))))
</PRE>
</TT> after macro expansion. The occurrences of <TT>x</TT> and <TT>flag</TT> legitimately refer to the parameters of the function <TT>foo</TT> because those parameters are visible at the site of the macro call which produced the expansion. <P>
<P>
<PRE>
(flet ((flet1 (n) (+ n n)))
(flet ((flet1 (n) (+ 2 (flet1 n))))
(flet1 2))) =&gt; 6
(defun dummy-function () 'top-level) =&gt; DUMMY-FUNCTION
(funcall #'dummy-function) =&gt; TOP-LEVEL
(flet ((dummy-function () 'shadow))
(funcall #'dummy-function)) =&gt; SHADOW
(eq (funcall #'dummy-function) (funcall 'dummy-function))
=&gt; <A REL=DEFINITION HREF="26_glo_t.htm#true">true</A>
(flet ((dummy-function () 'shadow))
(eq (funcall #'dummy-function)
(funcall 'dummy-function)))
=&gt; <A REL=DEFINITION HREF="26_glo_f.htm#false">false</A>
(defun recursive-times (k n)
(labels ((temp (n)
(if (zerop n) 0 (+ k (temp (1- n))))))
(temp n))) =&gt; RECURSIVE-TIMES
(recursive-times 2 3) =&gt; 6
(defmacro mlets (x &amp;environment env)
(let ((form `(babbit ,x)))
(macroexpand form env))) =&gt; MLETS
(macrolet ((babbit (z) `(+ ,z ,z))) (mlets 5)) =&gt; 10
</PRE>
</TT> <P>
<PRE>
(flet ((safesqrt (x) (sqrt (abs x))))
;; The safesqrt function is used in two places.
(safesqrt (apply #'+ (map 'list #'safesqrt '(1 2 3 4 5 6)))))
=&gt; 3.291173
</PRE>
</TT> <P>
<PRE>
(defun integer-power (n k)
(declare (integer n))
(declare (type (integer 0 *) k))
(labels ((expt0 (x k a)
(declare (integer x a) (type (integer 0 *) k))
(cond ((zerop k) a)
((evenp k) (expt1 (* x x) (floor k 2) a))
(t (expt0 (* x x) (floor k 2) (* x a)))))
(expt1 (x k a)
(declare (integer x a) (type (integer 0 *) k))
(cond ((evenp k) (expt1 (* x x) (floor k 2) a))
(t (expt0 (* x x) (floor k 2) (* x a))))))
(expt0 n k 1))) =&gt; INTEGER-POWER
</PRE>
</TT> <P>
<PRE>
(defun example (y l)
(flet ((attach (x)
(setq l (append l (list x)))))
(declare (inline attach))
(dolist (x y)
(unless (null (cdr x))
(attach x)))
l))
(example '((a apple apricot) (b banana) (c cherry) (d) (e))
'((1) (2) (3) (4 2) (5) (6 3 2)))
=&gt; ((1) (2) (3) (4 2) (5) (6 3 2) (A APPLE APRICOT) (B BANANA) (C CHERRY))
</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="s_declar.htm#declare"><B>declare</B></A>, <A REL=DEFINITION HREF="m_defmac.htm#defmacro"><B>defmacro</B></A>, <A REL=DEFINITION HREF="m_defun.htm#defun"><B>defun</B></A>, <A REL=DEFINITION HREF="f_docume.htm#documentation"><B>documentation</B></A>, <A REL=DEFINITION HREF="s_let_l.htm#let"><B>let</B></A>, <A REL=CHILD HREF="03_a.htm">Section 3.1 (Evaluation)</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>
It is not possible to define recursive <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A> with <A REL=DEFINITION HREF="#flet"><B>flet</B></A>. <A REL=DEFINITION HREF="#labels"><B>labels</B></A> can be used to define mutually recursive <A REL=DEFINITION HREF="26_glo_f.htm#function"><I>functions</I></A>. <P>
If a <A REL=DEFINITION HREF="#macrolet"><B>macrolet</B></A> <A REL=DEFINITION HREF="26_glo_f.htm#form"><I>form</I></A> is a <A REL=DEFINITION HREF="26_glo_t.htm#top_level_form"><I>top level form</I></A>, the body <I>forms</I> are also processed as <A REL=DEFINITION HREF="26_glo_t.htm#top_level_form"><I>top level forms</I></A>. See <A REL=CHILD HREF="03_bc.htm">Section 3.2.3 (File Compilation)</A>. <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/iss214.htm">LISP-SYMBOL-REDEFINITION:MAR89-X3J13</A><LI> <A REL=CHILD HREF="../Issues/iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL:ALLOW</A><LI> <A REL=CHILD HREF="../Issues/iss185.htm">GET-SETF-METHOD-ENVIRONMENT:ADD-ARG</A><LI> <A REL=CHILD HREF="../Issues/iss308.htm">SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS</A><LI> <A REL=CHILD HREF="../Issues/iss092.htm">DECLARATION-SCOPE:NO-HOISTING</A><LI> <A REL=CHILD HREF="../Issues/iss159.htm">FLET-DECLARATIONS</A><LI> <A REL=CHILD HREF="../Issues/iss105.htm">DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS</A><LI> <A REL=CHILD HREF="../Issues/iss161.htm">FLET-IMPLICIT-BLOCK:YES</A><LI> <A REL=CHILD HREF="../Issues/iss174.htm">FUNCTION-NAME:LARGE</A><LI> <A REL=CHILD HREF="../Issues/iss160.htm">FLET-DECLARATIONS: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>