Ant*_*ias 0 lisp function common-lisp
我正在尝试使用标签的本地函数来允许我的函数递归.这是代码:
(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))
Run Code Online (Sandbox Code Playgroud)
当我有slime评估函数并尝试运行它:
; Note: Deleting unused function
; (LABELS MY-REPLACE-REC)
; ;
; Warning: This function is undefined:
; MY-REPLACE-REC
Run Code Online (Sandbox Code Playgroud)
我试图尽可能多地填写错误消息,但我正在使用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))
Run Code Online (Sandbox Code Playgroud)
labels工作就像let.您需要labels在函数体内使用创建的对象,而不是在函数被销毁之后使用.
随着:
(let ((a 10))
; a exists here
)
; a doesn't exist anymore
Run Code Online (Sandbox Code Playgroud)
同 labels
(labels ((name (arg) arg))
; the function exists here
)
;the function doesn't esist anymore
Run Code Online (Sandbox Code Playgroud)
在你的代码中,你my-replace-rec在标签的主体中制作你什么也不做,在my-replace-rec被销毁之后你就称之为.Common Lisp对此没有任何警告,因为它希望您稍后将全局定义它.它不会与您不使用的范围进行比较.
通过移动结束括号,以便my-replace-rec在labelsemacs中完成调用将正确识别代码:
(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)))
Run Code Online (Sandbox Code Playgroud)
现在,当你查看你的代码时,它看起来与此相同,因为你已经将它看作my-replace-rec是在标签中使用它,而编辑器和你的实现知道它不是.