我正在尝试使用使用标签的局部函数来允许我的函数递归。 这是代码:
(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(我对它还是很陌生)并试图从一个小缓冲区中粘贴出来。
为什么会这样?它已被定义和使用,但似乎在使用之前一直被删除(据说是因为它未被使用)。
最佳答案
您的缩进已关闭。这是正确缩进的代码:
(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 ((a 10))
; a exists here
)
; a doesn't exist anymore
带有标签
(labels ((name (arg) arg))
; the function exists here
)
;the function doesn't esist anymore
在你的代码中你制作了 my-replace-rec
然后在标签的正文中你什么都不做并且在 my-replace-rec
被摧毁了,你称之为。 Common Lisp 对此没有任何警告,因为它希望您稍后在全局范围内定义它。它不会将它与您碰巧未使用的范围进行比较。
通过移动结束括号,以便在 labels
中完成对 my-replace-rec
的调用,emacs 将正确识别代码:
(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
,而编辑器和您的实现知道它不是't.
关于function - Lisp 标签函数在使用前被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46457082/