如何在lisp中使用标签需要帮助

时间:2012-11-06 13:46:17

标签: list lisp

据我所知,标签的使用是将局部函数定义为与flat相同但范围较大的函数。那是对的吗。我将举一个例子:

(defun nested-average (tree)
  ;labels are the same as flet but with higher scope, define local functions
  (labels ((%nested-average
                ;arguments for the function
                (branch sum visited)                
                (cond
                 ((consp branch)
                      (multiple-value-call
                      ;calls the previous function with reference to the label
                       #'%nested-average (rest branch)
                       (%nested-average (first branch) sum visited)))

                   ;is branch a number
                 ((numberp branch)
                    (values (+ sum branch) (1+ visited)))
                  ;otherwise
                 (t 
                 (values sum visited))
                 )
            )
           )
            (multiple-value-call #'/ (%nested-average tree 0 0))
    )
)
    ;(nested-average ' (10 ((30 1) 20) (8 (5 (50 7)) 9) 40))

1 个答案:

答案 0 :(得分:2)

来自Hyperspec:标签等同于flet,除了标签定义的函数名称的范围包含函数定义本身以及正文。

这实际上意味着标签允许您编写递归函数。例如:

(defun fact (n)
  (labels ((rec (x)
             (if (< x 1) 
                 1
                 (* x (rec (- x 1))))))
    (rec n)))

此函数工作正常,但用flet编写的相同函数将导致错误,因为符号rec不会在函数定义中绑定。如果出于同样的原因使用flet编写,则您提供的示例函数会导致错误。