[英]Recursive function in Emacs Lisp has void-variable error upon evaluating itself
我试图定义一个递归函数balanced
,需要一个字符串,返回true只有在字符串中的括号是平衡的。
我写的elisp代码是基于我为Odersky为Coursera课程编写的一些Scala代码,它是一个音译。
;; check if expr (list of chars of some expression) is balanced
(defun balanced (expr)
(defvar lparen (string-to-char "("))
(defvar rparen (string-to-char ")"))
(defun is-open (c) (eq lparen c))
(defun is-close (c) (eq rparen c))
(defun is-empty (ls) (eq ls nil))
(defun is-matching (l r) (and (is-open l) (is-close r)))
(defun is-balanced (list stack)
(cond ((is-empty list) (is-empty stack))
((is-open (car list))
(is-balanced (cdr list) ;; 'push' open-paren onto stack
(cons (car list) stack)))
((is-close (car list))
(if (is-empty stack) nil
(and
(is-balanced (cdr list) (cdr stack))
(is-matching (car stack) (car list)))))
(is-balanced (cdr list) (cdr stack))))
is-balanced
我在lisp-interaction-mode中,所以我使用Ctrl-J来评估上面的defun
语句。
然后,当我试图评估这个:
(balanced "(balanced nil nil)")
我得到一个void-variable错误:
Debugger entered--Lisp error: (void-variable is-balanced)
balanced("(balanced nil nil)")
(progn (balanced "(balanced nil nil)"))
eval((progn (balanced "(balanced nil nil)")) t)
eval-last-sexp-1(t)
eval-last-sexp(t)
eval-print-last-sexp()
call-interactively(eval-print-last-sexp nil nil)
recursive-edit()
debug(error (void-variable is-balanced))
balanced("(balanced nil nil)")
(progn (balanced "(balanced nil nil)"))
eval((progn (balanced "(balanced nil nil)")) t)
eval-last-sexp-1(t)
eval-last-sexp(t)
eval-print-last-sexp()
call-interactively(eval-print-last-sexp nil nil)
recursive-edit()
这个功能似乎没有认识到自己,我做错了什么?
当你执行你的功能(balanced ...)
,它的作用是:
is-balanced
。 第3步发生在(defun is-balanced (list stack) ... ))))
。
(defun balanced (expr)
...
(defun is-balanced (list stack)
...
(is-balanced (cdr list) (cdr stack))))
is-balanced ;; <= here!
但是你还没有定义这样的变量。 您已经定义了一个相同名称的函数 ,但是您无法访问函数对象,就好像它们是Emacs Lisp中的变量一样。 另见这里 。 由于没有名为is-balanced
变量, is-balanced
会收到错误消息。
(也就是说,对你的其余代码有很多批评。对于初学者来说,要注意通过defun
s defun
s,你每次调用时都会重新定义你的is-*
函数(balanced ...)
。这肯定不是你想要的。同样,你可能想要将defvar移动到函数体之外,因为它们定义全局变量。或者你的意思是使用(let ...)
代替?如果你真的想要全球价值,然后(defconst...)
可能更合适。)
问题是cond
表达式的最后一个元素没有包含在(t
... )
:
不正确:
(is-balanced (cdr list) (cdr stack))
正确
(t (is-balanced (cdr list) (cdr stack)))
这需要的原因是最后一个表达式应该是else
情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.