我正在尝试使用标签来使用本地函数来允许我的函数递归。 这是代码:
(defun my-replace (e1 e2 L)
"Perform a deep replace e1 with e2 in L."
(labels ((my-replace-rec (e1 e2 L)
"Used for recursion"
(cond ((endp L) nil)
((equal (car L) e1) (cons e2 (cdr L)))
((listp (car L)) (my-replace-rec e1 e2 (car L)))
(t (my-replace-rec e1 e2 (cdr L)))))))
(my-replace-rec e1 e2 L))
当我有slime评估函数并尝试运行它时:
; Note: Deleting unused function
; (LABELS MY-REPLACE-REC)
; ;
; Warning: This function is undefined:
; MY-REPLACE-REC
我试图尽可能多地填写错误消息,但我正在使用Emacs(我还是很新的)并尝试粘贴一个小缓冲区。
为什么会这样?它被定义和使用,但似乎它在被使用之前一直被删除(据说是因为它没有被使用)。
答案 0 :(得分:9)
你的身份已经消失了。这是您正确设计的代码:
(defun my-replace (e1 e2 L)
"Perform a deep replace e1 with e2 in L."
(labels ((my-replace-rec (e1 e2 L)
"Used for recursion"
(cond ((endp L) nil)
((equal (car L) e1) (cons e2 (cdr L)))
((listp (car L)) (my-replace-rec e1 e2 (car L)))
(t (my-replace-rec e1 e2 (cdr L))))))
;; empty labels body here..
)
;; my-replace-rec is a global function expected to be defun-ed later
(my-replace-rec e1 e2 L))
labels
就像let
一样工作。您需要在labels
的主体中使用创建的对象,而不是在函数被销毁之后使用。
使用let:
(let ((a 10))
; a exists here
)
; a doesn't esist anymore
使用labels
(labels ((name (arg) arg))
; the fcuntion exists here
)
;the function doesn't esist anymore
在您的代码中,您创建my-replace-rec
,然后在标签正文中 nothing ,并在my-replace-rec
被销毁后调用它。 Common Lisp对此没有任何警告,因为它希望您稍后将全局定义它。它不会与您不使用的范围进行比较。
通过移动结束括号,以便在my-replace-rec
emacs中完成对labels
的调用,将正确识别代码:
(defun my-replace (e1 e2 L)
"Perform a deep replace e1 with e2 in L."
(labels ((my-replace-rec (e1 e2 L)
"Used for recursion"
(cond ((endp L) nil)
((equal (car L) e1) (cons e2 (cdr L)))
((listp (car L)) (my-replace-rec e1 e2 (car L)))
(t (my-replace-rec e1 e2 (cdr L))))))
(my-replace-rec e1 e2 L)))
现在,当您查看代码时,它看起来与此相同,因为您已将其标识为在标签中使用my-replace-rec
,而编辑器和您的实现知道它不是。