common lisp:申请需要特殊对待吗?

common lisp: apply needs special treatment?

如果我试试这个

(apply (first '(numberp)) '(17))

万事如意,回归T。但是这个

(apply numberp '(17))

获得The variable NUMBERP is unbound.

但是这个

(apply #'numberp '(17))

有效。我显然在这里遗漏了一些非常基本的东西。 . . .

您在这里缺少的是 Common Lisp reading and evaluation 的工作原理。

当您输入 CL 文本时,例如

(apply (first '(numberp)) '(17))

reader(你可以自己invoke!)将其解析为以下列表:

(apply (first (quote (numberp))) (quote (17)))

(注意 ' 只是 quote 的语法糖),然后像这样计算:

  1. 取列表第一个元素的函数绑定,apply
  2. 评估第二个列表元素:
    1. first
    2. 的函数绑定
    3. 评估第二个列表元素:
      • 既然是引号,就照原样,得到长度为1的列表,元素为numberp
    4. first应用于该列表,得到numberp
  3. 评估第三个列表元素:
    • 既然被引用了,就是quote下面的东西,即长度为1的列表,元素为17
  4. 将第一个函数 (apply) 应用于参数,即将 numberp 的(函数绑定)应用于一个元素的列表 - 17.

你的第二种形式与第一种形式的不同之处在于你有符号 numberp,它被评估为一个变量,因此你得到了你的错误。

在您的第三种形式中,您使用 #'numberp,reader 转换为 (function numberp),returns 一个 函数 值可以应用到列表中。

简而言之,这是 Common Lisp 的结果 Lisp-2

您可能还会发现 When to use 'quote in Lisp 有启发性。

(apply numberp '(17)) 所做的是查找 变量 numberp 的值。这与apply无关。函数位置中的不带引号的符号,即列表中的第一个元素,在函数命名空间中查找,后续元素在变量命名空间中查找。

如果您尝试 (+ x 1),您会得到同样的错误。或者 (symbol-function symbol-function) 就此而言。

要使 (apply numberp '(17)) 正常工作,您需要将变量 numberp 绑定到一个函数。例如:

(let ((numberp 'numberp))
  (apply numberp '(17)))