我为什么要和lambda一起使用#'?它通常是这样写的,所以我猜它是好的形式。但这些界限似乎与我相同:
> (mapcar #'(lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
> (mapcar (lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
任何人都想提醒初学者注意差异吗?
答案 0 :(得分:14)
各种Lisp方言不同。以下使用Common Lisp:
首先#'是(function ...)的简短表示法。所以以下只是文本上的不同,但Common Lisp将它们视为相同:
#'(lambda (x) (* x 2))
和
(function (lambda (x) (* x 2)))
#'是一个readmacro,当Lisp系统读取Lisp代码时进行转换。
如果Lisp评估
(function (lambda (x) (* x 2)))
Lisp系统创建一个函数对象,FUNCTION将其作为值返回。
因此,无论何时需要函数作为值,都需要像这样编写它。当您想要将函数作为参数传递给另一个函数,当您想要从函数返回它或者想要将它存储在变量中时,需要一个函数作为值。例子:
(map #'(lambda (x) (* x 2)) '(1 2 3))
(defun (y) #'(lambda (x) (* x y)))
(defparameter *twice-fn* #'(lambda (x) (* x 2)))
现在,(lambda(x)(* x 2))是什么?
取决于具体情况,这是两个不同的事情。
Lambda表达
可以使用lambda表达式代替函数名称:
(function foo) and (function (lambda (x) (* x 2)))
和
(foo 17) and ((lambda (x) (* x 2)) 17)
以上两个是合法的Common Lisp语法。有一个lambda表达式可以直接使用。
请注意,Common Lisp中的以下两种形式为非法:
(#'(lambda (x) (* x 2)) 17) ; illegal in Common Lisp
(function #'(lambda (x) (* x 2))) ; illegal in Common Lisp
<强>宏强>
在Common Lisp标准化过程中,添加了一个宏LAMBDA(它不是Common Lisp的第一个描述,CLtL1的一部分)。它可以编写略短的代码。例如:
(lambda (x) (* x 2))
在上述情况下,LAMBDA是一个宏。在宏扩展期间,它将扩展为:
(function (lambda (x) (* x 2)))
请记住,在上面的FUNCTION表单中,内部lambda是lambda表达式的一部分,表示函数并且不会被展开。
所以,现在上面的三个例子可以写成:
(map (lambda (x) (* x 2)) '(1 2 3))
(defun (y) (lambda (x) (* x y)))
(defparameter *twice-fn* (lambda (x) (* x 2)))
它略短,看起来有点混乱,看起来与Scheme代码略微相似。对于用于读写Scheme代码的程序员来说,这看起来好一点。
<强>摘要强>
a)(function(lambda(x)(* x 2)))是编写将函数作为值返回的代码的“真实”方式。
b)#'(lambda(x)(* x 2))是上面较短的符号
c)(lambda(x)(* x 2))甚至更短,但使用宏扩展来创建a)的形式。
答案 1 :(得分:11)
#'
是function
的简写,它返回一个指向函数的指针(而不是应用它)。 lambda
返回一个函数,通常需要一个指向该函数的指针。由于这是如此常见,因此还有一个宏(在可变空间中)为您执行此操作,也称为lambda
。两行代码都是相同的。
哪个更好归结为Lisp-1/Lisp-2 debate:在Common Lisp中你可以做到,这要归功于宏。一如既往,保持一致。