我注意到这个名为rec
的函数在Common Lisp代码中多次出现,但我没有找到它实际上在做什么的引用。任何人都可以向我解释它是什么?例如,它出现在另一个问题的某些代码How to convert a flat list into a nested tree-like structure?:
(defun mimicry (source pattern)
(labels ((rec (pattern)
(mapcar (lambda (x)
(if (atom x)
(pop source)
(rec x)))
pattern)))
(rec pattern)))
答案 0 :(得分:9)
rec
不是代码中的全局函数,除非您自己定义它。它是使用labels
定义的本地辅助函数。
特殊运算符labels
执行与defun
类似的任务,但绑定是本地的。这就像您使用defparameter
制作全局变量而使用let
制作本地变量。
(labels ((banana (arg1) ; make function banana
(+ arg1 arg1)))
(banana 10)) ; use it
; banana doesn't exist anymore
与:
相同(defun banan (arg1) ; make function banana
(+ arg1 arg1))
(banana 10) ; use it
; banana still exists
不同之处在于香蕉不再存在于labels
的外部,而使用defun
时,您会使用辅助功能感染您的全球环境。由于labels
中的函数是本地函数,因此您可以使用rec
,loop
和aux
等常用名称作为名称,并且不会污染代码的其他部分。
有一个名为flet
的类似特殊运算符,其工作方式相同,但它在本地环境中不包含自己的函数,阻止您在其体内调用自己的函数。这些也很有用但你很少称它们为rec
,因为rec
暗示它是递归。
这不是CL限制,而是编码风格。我经常在Scheme编程中使用名称rec
和loop
(另一种Lisp方言),所以当我在CL中遇到它们时我知道它们是什么,但在CL中我从我的答案中看到了SO我在名为aux
的全局函数中使用test-aux
或test
。