3

第一个不起作用。但是第二个有效,这让我很困惑..有人可以解释一下吗?

CL-USER> (funcall (first '(#'+ +)) 1)
; Evaluation aborted on #<TYPE-ERROR expected-type:
;  (OR FUNCTION SYMBOL) datum: #'+>.
CL-USER> (funcall #'+ 1)
1
4

2 回答 2

5

您的输入是:

 (funcall (first '(#'+ +)) 1)

'(#'+ +)我们评估它的时候是什么?前面的引用阻止了对表单的评估,所以结果就是读者读到的数据:

这是一个包含两个项目的列表:

  1. (function +)
  2. +

通常写为 ((function +) +)。

请注意,原始输入中的引用明确表示您不想评估列表或其内容。

现在你FIRST在这个名单上打电话。结果是第一项:(function +). 这是两个项目的列表:

  1. function
  2. +

现在你用这个列表和值 1 调用 FUNCALL。

FUNCALL 需要一个函数或一个符号作为输入。你给它列表(function +)作为第一个参数。FUNCALL 不知道如何处理它。

我们怎样才能修复它?您可能想使用作为评估结果的函数(function +)

所以你需要重写你的原始列表。代替 `'(#'++))' 使用例如:

(list #'+ '+)

或者

`(,#'+ +)    ; note the backquote in front
于 2012-05-09T20:01:15.643 回答
5

#'是一个阅读器宏。#'+是 的缩写(function +)'是扩展为 的阅读器宏(quote …)。后者返回未评估的参数。因此,'(#'+ +)产量((function +) +)#'+(function +)在读取时转换)。这first只是列表(function +),它不是函数。现在,(function +)打印为#'+,这是您在调试器中看到的。

使用非文字列表将起作用:

CL-USER> (funcall (first (list #'+ '+)) 1)
1
于 2012-05-09T18:45:00.410 回答