为什么要使用#'和lambda?

Joh*_*ski 13 lisp lambda quote

我为什么要和lambda一起使用#'?它通常是这样写的,所以我猜它是好的形式.但这些线条似乎与我相同:

> (mapcar #'(lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
> (mapcar (lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
Run Code Online (Sandbox Code Playgroud)

有人关心这个差异的开始吗?

Rai*_*wig 14

各种Lisp方言有所不同.以下使用Common Lisp:

First #'是(function ...)的简短符号.所以以下只是文本上的不同,但Common Lisp读取它们是相同的:

#'(lambda (x) (* x 2))
Run Code Online (Sandbox Code Playgroud)

(function (lambda (x) (* x 2)))
Run Code Online (Sandbox Code Playgroud)

#'是一个readmacro,当Lisp系统读取Lisp代码时进行转换.

如果Lisp评估

(function (lambda (x) (* x 2)))
Run Code Online (Sandbox Code Playgroud)

Lisp的系统创建一个功能对象和函数返回它作为其值.

因此,无论何时需要函数作为值,都需要像这样编写它.当您想要将函数作为参数传递给另一个函数,当您想要从函数返回它或者想要将它存储在变量中时,需要一个函数作为值.例子:

(map #'(lambda (x) (* x 2)) '(1 2 3))

(defun (y) #'(lambda (x) (* x y)))

(defparameter *twice-fn* #'(lambda (x) (* x 2)))
Run Code Online (Sandbox Code Playgroud)

现在,(lambda(x)(*x 2))是什么?

根据具体情况,这是两个不同的事情.

Lambda表达式

可以使用lambda表达式代替函数名称:

(function foo)   and    (function (lambda (x) (* x 2)))
Run Code Online (Sandbox Code Playgroud)

(foo 17)    and  ((lambda (x) (* x 2)) 17)
Run Code Online (Sandbox Code Playgroud)

以上两个是合法的Common Lisp语法.可以直接使用lambda表达式.

请注意,以下两种形式在Common Lisp中是非法的:

(#'(lambda (x) (* x 2)) 17)   ; illegal in Common Lisp

(function #'(lambda (x) (* x 2)))  ; illegal in Common Lisp
Run Code Online (Sandbox Code Playgroud)

在Common Lisp标准化过程中,添加了一个宏LAMBDA(它不是Common Lisp的第一个描述,CLtL1的一部分).它可以编写略短的代码.例:

(lambda (x) (* x 2))
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,LAMBDA是一个宏.在宏扩展期间,它将扩展为:

(function (lambda (x) (* x 2)))
Run Code Online (Sandbox Code Playgroud)

请记住,在上面的FUNCTION表单中,内部lambda是lambda表达式的一部分,表示函数并且不会被展开.

那么,现在上面的三个例子可以写成:

(map (lambda (x) (* x 2)) '(1 2 3))

(defun (y) (lambda (x) (* x y)))

(defparameter *twice-fn* (lambda (x) (* x 2)))
Run Code Online (Sandbox Code Playgroud)

它略短,看起来有点混乱,看起来与Scheme代码略微相似.对于用于读写Scheme代码的程序员来说,这看起来好一点.

摘要

a)(function(lambda(x)(*x 2)))是编写将函数作为值返回的代码的"真实"方式.

b)#'(lambda(x)(*x 2))是上述较短的符号

c)(lambda(x)(*x 2))甚至更短,但使用宏扩展来创建a)的形式.


Mar*_*ark 11

#'是简写function,它返回一个指向函数的指针(而不是应用它). lambda返回一个函数,通常需要一个指向该函数的指针.由于这是如此常见,因此还有一个宏(在可变空间中)为您完成,也可以调用lambda它.两行代码都是相同的.

哪个更好归结为Lisp-1/Lisp-2的争论:在Common Lisp中你可以做到,这要归功于宏.一如既往,保持一致.