LISP:SYSTEM :: READ-EVAL-PRINT:变量我没有价值

时间:2018-03-28 19:56:18

标签: lisp common-lisp

我做了一个简单的测试函数,试图通过调用(测试j 10)为j赋值。 我得到SYSTEM :: READ-EVAL-PRINT:变量J没有值。

(DEFUN test (j i)
    (LET ((j i))
        (print j)
    )
)

2 个答案:

答案 0 :(得分:1)

我不确定您是否知道j中的letj中的变量test是两个完全不同的变量。因为真正的重构是将它们重命名以便清楚,所以删除了这些歧义的代码:

(defun test (pj pi)
  (let ((lj pi))
    (print lj)))

这是完全相同的代码,因为let中的 new 绑定有效地使得具有相同名称的旧变量在let的持续时间内不可访问。警告将大约为pj,因为它在函数中仍未使用,因此您应该考虑将其删除:

(defun test (pi)
  (let ((lj pi))
    (print lj)))

通常有一个未使用的参数是一个错误所以CL唠叨这样的事情。但是,有时您会使用更高阶函数来使用传递值的函数。例如。

(defun map-assoc (fn lst)
  (loop :for n :from 0
        :for (k . v) :in lst
        :collect (funcall fn k v n lst)))

现在想象你想要列出一个关键字。

(defun assoq-keys (lst)
  (map-assoc (lambda (k v n lst)
               (declare (ignore v n lst))
               k)
             lst))

(assoq-keys '((I . 1) (II . 2) (III . 3) (IV . 4) (V . 5)))
; ==> (I II III IV V)

declare语句将抑制传递的其他变量不会被使用的错误,但是您必须包含它们,因为它是map-assoc函数的合同。对于一个获取其值或者可能交换其他值的函数,您将使用其他变量,因此传递值是一个很好的推广。

答案 1 :(得分:0)

我认为你误解了论据是如何运作的。您当前的test函数有两个参数:ji。你好像只使用i,所以没有理由传递第二个。{1}}。考虑

(defun test (i)
  (let ((j i))
    (print j)))

然后将其称为(test 10)