普通的lisp中的#'

Max*_*Max 14 common-lisp quote

在Practical Common Lisp一书的第3章中,有一个类似SQL的选择和函数的例子.这是它的简化版本:

(defun where (x) 
   #'(lambda (item)
     (> item x)))
Run Code Online (Sandbox Code Playgroud)

它像这样使用:

(remove-if-not (where 2) (list 1 2 3 4))
Run Code Online (Sandbox Code Playgroud)

在本书的前面部分解释说,#'序列用于表示它后跟一个函数名,而不是一个需要评估的变量.我不明白为什么这里需要它.我尝试在where没有它的情况下实现该功能,它也可以工作:

(defun where (x) 
   (lambda (item)
     (> item x)))
Run Code Online (Sandbox Code Playgroud)

我试着谷歌搜索它,并且,正如你可以想象的那样,通过这样一系列的角色,它不是一个非常有成效的搜索.我不知道这件事的名字.在上面的代码中是否有任何特殊原因需要它?

小智 12

这是Hyperspec中的精确页面,它处理标准宏字符"sharp"后跟"single quote".

为简单起见,此阅读器宏扩展为将以下形式包含在(function <form>)s-expression中.这有效地告诉解析器该表单是可调用的.

lambda是一个宏,它生成代码,它已经包含(function <form>),但历史上和一致性,通常也使用从带有尖锐+引号的阅读器宏获得的替代形式.

这里是在常见的lisp(另一个StackOverflow问题)中编写lambda表达式,它深入介绍了特殊情况(lambda <form>)

  • 具体来说,#'(lambda()nil)不是宏调用,而是函数文字和(lambda()nil)调用扩展为#'(lambda()nil)的宏扩展器. (4认同)

Rai*_*wig 6

注意:*print-pretty*适用NIL于这些示例.

(defun where (x) 
  #'(lambda (item)
      (> item x)))
Run Code Online (Sandbox Code Playgroud)

在上面的函数中,where您正在创建一个匿名函数,并将它作为闭包返回(函数加变量绑定X).由于您将其作为值返回,因此您必须编写(FUNCTION (LAMBDA ...)).#'(lambda ...)是一个更短的符号,但结果相同 - 使用阅读器宏#':

CL-USER 74 > (read-from-string "#'(lambda (foo) (1+ foo))")
(FUNCTION (LAMBDA (FOO) (1+ FOO)))
Run Code Online (Sandbox Code Playgroud)

你也可以写:

(defun where (x) 
  (lambda (item)
    (> item x)))
Run Code Online (Sandbox Code Playgroud)

在Common Lisp的定义中,已经添加了它以便能够编写上面的代码.它也与(function (lambda ...))表格相同.在Common Lisp中LAMBDA是宏,它扩展到它:

CL-USER 75 > '(lambda (foo) (1+ foo))
(LAMBDA (FOO) (1+ FOO))

CL-USER 76 > (macroexpand '(lambda (foo) (1+ foo)))
(FUNCTION (LAMBDA (FOO) (1+ FOO)))
T
Run Code Online (Sandbox Code Playgroud)

因此,LAMBDA是一个宏,当评估者将其视为时(lambda ...),它将表单扩展为一个(function (lambda ...))表单,然后进行评估.

FUNCTION是一个特殊的形式,当评估者看到它时,它返回一个函数对象 - 在(function (lambda (foo) (1+ foo)))它返回匿名函数作为对象的情况下:

CL-USER 77 > (function (lambda (foo) (1+ foo)))
#<anonymous interpreted function 406000761C>
Run Code Online (Sandbox Code Playgroud)

所以你看到这(function (lambda ...))是获取函数对象的真正的s表达式符号,并且#'(lambda ...)(通过读取器宏)或(lambda ...)(通过宏)都是Lisp源代码中较短的符号.程序员使用长格式是不常见的.大多数(99.999%)使用源代码中较短的符号之一.

顺便说一句:如果评估者看到function包含这样一个函数的名称(function sin),那么它会查找函数绑定并返回相应的函数对象:

CL-USER 78 > (function sin)
#<Function SIN 4110083C6C>
Run Code Online (Sandbox Code Playgroud)