递归Lisp函数的函数警告无效

递归Lisp函数的函数警告无效,lisp,emacs23,Lisp,Emacs23,我正在看Lisp,到目前为止我一直在关注。但是,当我尝试评估这个函数时 (defun tailfact (n &optional (intermediate 1)) (if (= n 1) (return-from tailfact intermediate)) (tailfact (1 - n) (* n intermediate))) (tailfact 5) 我得到一个无效函数警告(我在Emacs中运行这个)。不知道该怎么做,也不知道如何修复。您不小心在1-中写

我正在看Lisp,到目前为止我一直在关注。但是,当我尝试评估这个函数时

(defun tailfact (n &optional (intermediate 1))
  (if (= n 1)
    (return-from tailfact intermediate))
  (tailfact (1 - n) (* n intermediate)))

(tailfact 5)

我得到一个
无效函数
警告(我在Emacs中运行这个)。不知道该怎么做,也不知道如何修复。

您不小心在
1-
中写入了一个空格(这是一个从给定数字中减去1的函数)。请删除该空格(即使用
(1-n)
而不是
(1-n)
),然后重试

此外,Emacs Lisp没有从返回的
。只需说
intermediate
而不是
(从tailfact intermediate返回)
。但是,您必须在
if
表达式中移动
tailfact
调用,如else子句

哦,在我的测试中,我发现了Common Lisp和Emacs Lisp之间的另一个不同点:后者不支持可选参数的默认值,并且它总是使用
nil
。因此,这里有一种将代码移植到elisp的方法:

(defun tailfact (n &optional intermediate)
  (let ((intermediate (or intermediate 1)))
    (if (= n 1)
        intermediate
      (tailfact (1- n) (* n intermediate)))))

然而,让我首先同意雷纳的评论。如果您正在学习通用Lisp资源,那么您确实应该使用通用Lisp实现。我听说这是一种很棒的Emacs模式,用于集成主要的CL实现,包括SBCL(可能是最常用的CL实现之一)。

Hmmmmm,这也不起作用。它给出了相同的错误。它与我在上面发布的完全相同,具有您建议的修复。我明白了。我只是在谷歌上搜索,发现elisp没有从
返回的
,所以我对我的答案进行了适当的编辑。所以,只需将行
(从tailfact intermediate返回)
更改为
(intermediate)
?不。
intermediate
没有任何选项。您还需要在
if
表达式中提升整个
tailfact
表达式。教程使用的是Common Lisp。所以我建议使用CommonLisp。CommonLisp和EmacsLisp有很多细微和主要的区别。在学习过程中找出哪些有效,哪些无效并不十分有用。