未使用的词汇变量

Mat*_*att 2 lisp common-lisp

刚开始学习Lisp。我不知道为什么我会收到这些错误,甚至是什么意思。我只是尝试使用Gregory-Leibniz系列编码pi的近似值,这是代码。

(defun gl (n)
           (defparameter x 0)                        ;init variable to hold our runnning sum
           (loop for y from 0 to n                   ;number of iterations, starting from 0 to desired n
              (if (= y 0)                                      ;if n is 0 then we just want 4
                 (defparameter w 4))
              (if (> y 0)                                      ;else, 4*(-1^y)/((2 * y)+1)
                 (defparameter w (* 4 (/ (exp -1 y) (+ (* 2 y) 1)))))
              (+ x w))                                         ;add to our running sum
           (write x))                                        ;once loop is over, print x.
Run Code Online (Sandbox Code Playgroud)

我尝试使用setq,defvar,let等代替defparameter,但是我仍然收到“未声明的自由变量X”。

即使我将其用于循环,也会出现错误“未使用的词法变量N”,这也是很奇怪的。

我该如何解决这个问题,为什么会发生呢?谢谢!

cor*_*ump 5

这是Emacs自动缩进后的代码:

(defun gl (n)
  (defparameter x 0)
  (loop for y from 0 to n
       (if (= y 0)
           (defparameter w 4))
       (if (> y 0)
           (defparameter w (* 4 (/ (exp -1 y) (+ (* 2 y) 1)))))
       (+ x w))
  (write x))
Run Code Online (Sandbox Code Playgroud)

使用SBCL编译以下代码会产生一个错误和两个警告。

一则警告说这x是不确定的。您不应defparameter从函数内部进行调用,因为defvardefparameter用于声明动态变量并在全局范围内设置其值。最好使用let绑定,或者,因为您已经在使用循环,所以最好使用with子句。要修改绑定时,请使用setf

错误来自的宏扩展LOOP,格式不正确。对于SBCL,这意味着在其余的函数编译中,该代码被视为死代码。这就解释了为什么n不使用的原因,这就是第二个警告。

尚待完成各种修复:

  • 使用功能EXPT,而不是EXP
  • 调用(+ x w)仅计算一个值,而不修改x,结果是无用的。
  • if像其他语言中的三元运算符一样,最好使用表达式,在这种情况下,可以简化代码
  • 可以使用函数来添加一个1+(这是函数的名称,而不是用于添加常量的特殊语法)
  • write很少需要该操作,尤其是在计算数学公式时;只需返回该值,REPL就会自动将其打印出来。

使您的代码正常工作的小更正:

(defun gl (n)
  (let ((x 0))
    (loop
       for y from 0 to n
       for w = (if (= y 0)
                   4
                   (* 4 (/ (expt -1 y) (+ (* 2 y) 1))))
       do (setf x (+ x w)))
    (write x)))
Run Code Online (Sandbox Code Playgroud)

我个人会摆脱xw,并使用SUM循环子句。

(defun gl (n)
  (loop
     for y from 0 to n
     sum (if (zerop y)
             4
             (* 4 (/ (expt -1 y)
                     (1+ (* 2 y)))))))
Run Code Online (Sandbox Code Playgroud)

  • @Matt主要取决于您对它的熟悉程度,您可能会很容易了解CL,CL在某些方面比C ++和Python都更简单(例如,更少的极端情况)。 (2认同)