为什么我不能使用从Common lisp列表中提取的函数符号(#')?

时间:2012-05-09 18:09:34

标签: function functional-programming lisp common-lisp

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

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

2 个答案:

答案 0 :(得分:4)

#'是读者宏。 #'+(function +)的缩写。 '是一个扩展到(quote …)的读者宏。后者返回其论点未评估。因此,'(#'+ +)会产生((function +) +)#'+将在读取时变为(function +)first只是列表(function +),它不是函数。现在,(function +)打印为#'+,这是您在调试器中看到的内容。

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

CL-USER> (funcall (first (list #'+ '+)) 1)
1

答案 1 :(得分:4)

您的输入是:

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

我们评估时'(#'+ +)是什么?前面的引用阻止了表单的评估,因此结果就是读者读取的数据:

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

  1. (function +)
  2. +
  3. 通常写为((function +)+)。

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

    现在,您可以在此列表中拨打FIRST。结果是第一项:(function +)。这是两个项目的列表:

    1. function
    2. +
    3. 现在使用此列表调用FUNCALL,值为1。

      FUNCALL期望函数或符号作为输入。您将列表(function +)作为第一个参数。 FUNCALL不知道如何处理它。

      我们如何修复它?您可能想要使用评估(function +)的结果的函数。

      因此您需要重写原始列表。而不是''(#'+ +))'使用例如:

      (list #'+ '+)
      

      `(,#'+ +)    ; note the backquote in front