注意:对于这些示例,*print-pretty* 是 NIL。
(defun where (x)
#'(lambda (item)
(> item x)))
在上面的函数where 中,您正在创建一个匿名函数,并将它作为闭包返回(函数加上X 的变量绑定)。由于您将其作为值返回,因此您必须编写 (FUNCTION (LAMBDA ...))。 #'(lambda ...) 是一个较短的符号,但结果相同 - 使用阅读器宏 #':
CL-USER 74 > (read-from-string "#'(lambda (foo) (1+ foo))")
(FUNCTION (LAMBDA (FOO) (1+ FOO)))
你也可以写:
(defun where (x)
(lambda (item)
(> item x)))
在定义 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
所以,LAMBDA 是一个宏,当评估者看到它就像在 (lambda ...) 中一样时,它会将表单扩展为 (function (lambda ...)) 表单,然后对其进行评估。
FUNCTION 是一种特殊形式,当求值者看到它时,它会返回一个函数对象——在(function (lambda (foo) (1+ foo))) 的情况下,它会将匿名函数作为一个对象返回:
CL-USER 77 > (function (lambda (foo) (1+ foo)))
#<anonymous interpreted function 406000761C>
所以你看到(function (lambda ...)) 是获取函数对象的真正 s 表达式表示法,#'(lambda ...)(通过读取器宏)或(lambda ...)(通过宏)在 Lisp 源代码中都是较短的表示法。程序员使用长格式是不寻常的。大多数 (99.999%) 在源代码中使用较短的符号之一。
顺便说一句:如果求值器看到 function 包含像 (function sin) 这样的函数名称,那么它会查找函数绑定并返回相应的函数对象:
CL-USER 78 > (function sin)
#<Function SIN 4110083C6C>