《通链参考手册》


Special Operator FLET, LABELS, MACROLET

●语法设定:

flet ((function-name lambda-list [[local-declaration* | local-documentation]] local-form*)*) declaration* form*

=> result*

labels ((function-name lambda-list [[local-declaration* | local-documentation]] local-form*)*) declaration* form*

=> result*

macrolet ((name lambda-list [[local-declaration* | local-documentation]] local-form*)*) declaration* form*

=> result*

●参数和值:

function-name---a function name.

name---a symbol.

lambda-list---a lambda list; for flet and labels, it is an ordinary lambda list; for macrolet, it is a macro lambda list.

local-declaration---a declare expression; not evaluated.

declaration---a declare expression; not evaluated.

local-documentation---a string; not evaluated.

local-forms, forms---an implicit progn.

results---the values of the forms.

●详情:

flet, labels, and macrolet define local functions and macros, and execute forms using the local definitions. Forms are executed in order of occurrence.

The body forms (but not the lambda list) of each function created by flet and labels and each macro created by macrolet are enclosed in an implicit block whose name is the function block name of the function-name or name, as appropriate.

The scope of the declarations between the list of local function/macro definitions and the body forms in flet and labels does not include the bodies of the locally defined functions, except that for labels, any inline, notinline, or ftype declarations that refer to the locally defined functions do apply to the local function bodies. That is, their scope is the same as the function name that they affect. The scope of these declarations does not include the bodies of the macro expander functions defined by macrolet.

●例子:

 (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))))
after macro expansion. The occurrences of x and flag legitimately refer to the parameters of the function foo because those parameters are visible at the site of the macro call which produced the expansion.

 (flet ((flet1 (n) (+ n n)))
    (flet ((flet1 (n) (+ 2 (flet1 n))))
      (flet1 2))) =>  6

 (defun dummy-function () 'top-level) =>  DUMMY-FUNCTION 
 (funcall #'dummy-function) =>  TOP-LEVEL 
 (flet ((dummy-function () 'shadow)) 
      (funcall #'dummy-function)) =>  SHADOW 
 (eq (funcall #'dummy-function) (funcall 'dummy-function))
=>  true 
 (flet ((dummy-function () 'shadow))
   (eq (funcall #'dummy-function)
       (funcall 'dummy-function)))
=>  false 

 (defun recursive-times (k n)
   (labels ((temp (n) 
              (if (zerop n) 0 (+ k (temp (1- n))))))
     (temp n))) =>  RECURSIVE-TIMES
 (recursive-times 2 3) =>  6

 (defmacro mlets (x &environment env) 
    (let ((form `(babbit ,x)))
      (macroexpand form env))) =>  MLETS
 (macrolet ((babbit (z) `(+ ,z ,z))) (mlets 5)) =>  10

 (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)))))
=>  3.291173

 (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))) =>  INTEGER-POWER

 (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)))
=>  ((1) (2) (3) (4 2) (5) (6 3 2) (A APPLE APRICOT) (B BANANA) (C CHERRY))

●受制于: 无。

●例外情况: 无。

●更多信息:

declare, defmacro, defun, documentation, let, Section 3.1 (Evaluation), Section 3.4.11 (Syntactic Interaction of Documentation Strings and Declarations)

●说明:

It is not possible to define recursive functions with flet. labels can be used to define mutually recursive functions.

If a macrolet form is a top level form, the body forms are also processed as top level forms. See Section 3.2.3 (File Compilation).


X3J13设计清单非标准部分,可查下面章节:


◇首页 § ◎章节目录 § □内容索引 § ○符号索引 § △术语表 § ※设计草案