8

我是 lisp 的新手,正在编写一些简单的程序来熟悉它。我正在做的一件事是编写阶乘方法的递归和迭代版本。但是,我遇到了一个问题,似乎无法解决。

我在 Lisp 看到了一个类似的错误 : CHAR 既没有声明也没有绑定 ,但实际上没有找到解决方案,除了 OP 意识到他犯了一个“打字错误”。在 REPL 中,我可以使用 setf 函数,它工作正常。我也在使用带有 emacs 的 LispBox。我将不胜感激任何建议!

(defun it-fact(num)
  (setf result 1)
  (dotimes (i num)
    (setf result (* result (+ i 1)))
  )
)

IT-FACT 中的警告:RESULT 既没有声明也没有约束,它将被视为已声明为 SPECIAL。

4

3 回答 3

8

Lisp 风格有一些错误或不太好的地方:

(defun it-fact(num)                      ; style: use a space before (
  (setf result 1)                        ; bad: variable RESULT is not introduced
  (dotimes (i num)
    (setf result (* result (+ i 1)))     ; bad: extra addition in each iteration
  )                                      ; style: parentheses on a single line
)                                        ; bad: no useful return value

一个可能的版本:

(defun it-fact (num)
  (let ((result 1))                      ; local variable introduced with LET
    (loop for i from 1 upto num          ; I starts with 1, no extra addition
      do (setf result (* result i)))
    result))                             ; result gets returned from the LET
于 2009-09-06T12:17:43.973 回答
6

在 Lisp 中,局部变量必须用 LET 或其他创建局部变量的形式显式声明。这与 Python 或 JavaScript 不同,其中对变量的赋值会在当前词法范围内创建变量。

您的示例可以这样重写:

(defun it-fact(num)
  (let ((result 1))
    (dotimes (i num)
      (setf result (* result (+ i 1))))))

题外话:将右括号放在单独的行上是没有意义的。

于 2009-09-06T08:58:36.803 回答
5

在开始使用它之前,您需要绑定变量“result”——例如,使用“let”:

(defun it-fact(num)
  (let ((result 1))
    (dotimes (i num)
      (setf result (* result (+ i 1))))))

有关更多详细信息,您可能需要阅读...

于 2009-09-06T08:34:20.187 回答