Common lisp 用公共lisp编写lambda表达式

Common lisp 用公共lisp编写lambda表达式,common-lisp,lambda,clisp,Common Lisp,Lambda,Clisp,我目前正在阅读Paul Graham的ANSI Common Lisp,我有一个关于编写lambda表达式的问题 我们是否需要在lambda表达式前面加上#'?。如果我在REPL中写这样的东西,它会工作得很好 > ((lambda (x) (+ x 1)) 1) 2 这也会如此 > (mapcar (lambda (x) (+ x x)) '(1 2 3 4)) (2 4 6 8) 我知道#'表示函数。所以我的问题是,这是某种惯例还是推荐做法?如果我不在LAMBDA前面加

我目前正在阅读Paul Graham的ANSI Common Lisp,我有一个关于编写lambda表达式的问题

我们是否需要在lambda表达式前面加上
#'
?。如果我在REPL中写这样的东西,它会工作得很好

> ((lambda (x) (+ x 1)) 1)
  2
这也会如此

> (mapcar (lambda (x) (+ x x)) '(1 2 3 4))
  (2 4 6 8)

我知道
#'
表示函数。所以我的问题是,这是某种惯例还是推荐做法?如果我不在LAMBDA前面加上
#“
,会出什么问题吗?它依赖于实现吗?

LAMBDA表达式

(lambda…
仅在某些地方被视为lambda表达式,如
函数
窗体或函数调用的开头。不计算Lambda表达式

(function              ; special operator FUNCTION
  (lambda () 'foobar)) ; <- this is a lambda expression


(                    ; a function call
 (lambda (foo) foo)  ; <- this is a lambda expression
 'bar                ; argument
)
LAMBDA宏

是一个宏。它将
(lambda…
扩展为
(函数(lambda…)
,这相当于
#'(lambda…)

宏可以为您节省一些写/读的时间,仅此而已。在Common Lisp(CLtL1)的第一个版本中,没有
LAMBDA
宏。它是后来添加的,现在是ANSI Common Lisp的一部分

功能特殊操作员

他是一名特殊操作员。它需要函数名或lambda表达式。因此,不会计算名称或lambda表达式。事实上,lambda表达式根本无法计算。在
函数
中,lambda表达式是宏形式,因此将再次展开
FUNCTION
的目的是返回由名称或lambda表达式表示的相应函数对象。它将函数对象作为值返回。通过这个特殊的操作符,可以从全局函数和词法函数访问函数对象

函数
运算符在Common Lisp中是必需的,因为它对值、函数和其他一些东西有单独的名称空间。它被称为Lisp-2甚至Lisp-n,具有两个或多个名称空间

函数形式中函数位置的Lambda表达式

((lambda(foo)foo)10)
由公共Lisp的内置语法支持。看

混乱


这完全合乎逻辑,但令人困惑。别担心,你并不孤单,但实际上这没什么大不了的。

谢谢,我还是不明白为什么人们会在lambda表达式之前明确地写上#。这是风格的问题。有些人喜欢,有些人不喜欢。我更喜欢它,因为它允许轻松识别用作值的实际函数。它还使替换为
flet
labels
功能更加容易。除了lambdas之外,它还可以查找函数的定义。如果您不知道某个实现是否强制预先执行,这可能是可取的,例如,
(mapcar'frob my list)
可能会查找
frob
符号函数
的次数与
my list
中的元素的次数相同。Doug Hoyte提供了一个不使用#语法的参数。雷纳在这里暗示了这一点;事实上((lambda(foo))是内置语法,并且(lambda宏,意味着您可以在使用读取宏时利用这种语法的双重性做一些有趣的事情。查看Hoyte的cl ppcre读取宏扩展作为一个例子:关于Clayton Stanley的评论:一个快速警告,“忽略lambda”包含一些宏技术,一些人发现这些技术在风格和可维护性方面存在问题。我喜欢book并衷心推荐购买它,但请注意其中蕴含着深刻的魔力,我们应该认真考虑最终用户/编码人员,他们将在将来查看您的代码。您可能想看看我的。
(funcall             ; calling a function via funcall
 (lambda (foo) foo)  ; this is not a lambda expressions, but the macro lambda
                     ;  as all arguments to FUNCALL it will be
                     ;    macro expanded and evaluated
                     ;  it expands to (function (lambda (foo) foo))
 'bar)               ; argument
CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))