我目前正在阅读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添加前缀,可能会出错吗?是否依赖于实现?
答案 0 :(得分:20)
LAMBDA表达
(lambda ...)
仅在某些地方被视为 lambda表达式,例如function
表单或函数调用的头部。不评估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表达式:
(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
LAMBDA宏
LAMBDA是一个宏。它将(lambda ...)
扩展为(function (lambda ...))
,相当于#'(lambda ...))
。
CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))
宏可以为你节省一些写/读,就是这样。在Common Lisp的第一个版本(CLtL1)中没有LAMBDA
宏。它已在稍后添加,现在是 ANSI Common Lisp 的一部分,
FUNCTION特殊操作符
FUNCTION是一个特殊的运营商。它需要一个函数名或一个 lambda表达式。因此,不评估名称或 lambda表达式。事实上,根本无法评估 lambda表达式。在FUNCTION
内, lambda表达式是而不是宏形式,因此不将再次展开。 FUNCTION
的目的是返回由名称或 lambda表达式表示的相应函数对象。它将函数对象作为值返回。使用此特殊运算符,可以从全局函数和词法函数访问函数对象。
Common Lisp中需要FUNCTION
运算符,因为它有值,函数和其他一些东西的单独命名空间。它是一个所谓的 Lisp-2 ,甚至是 Lisp-n ,有两个或更多名称空间。
函数形式的函数位置的Lambda表达式
Common Lisp的内置语法支持 ((lambda (foo) foo) 10)
。请参阅Lambda Forms。
<强>混淆强>
这是合乎逻辑的,但令人困惑。不要担心你并不孤单,但在实践中并不是什么大不了的事。