我目前正在读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表达式 ,如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 ...)
到(function (lambda ...))
这是相当于#'(lambda ...))
CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))
宏为您节省一点写入/读出,仅此而已。 在Common Lisp的(CLtL1)的第一个版本没有LAMBDA
宏。 据后来补充,现在是ANSI Common Lisp的一部分,
该功能特别操作
功能是一个特殊的操作。 它需要一个函数名或lambda表达式 。 因此,名称或lambda表达式不被评估。 事实上lambda表达式不能在所有被评估。 内部FUNCTION
,lambda表达式 不是宏形式,因此将不再次扩大。 的目的FUNCTION
是返回其由名称或λ表达式表示的相应的功能的对象。 它返回功能对象作为值。 有了这个特殊的运营商一个可以访问全局函数和词法函数的函数对象。
该FUNCTION
操作是Common Lisp的必要,因为它具有价值,功能和一些其他的东西不同的命名空间。 它作为一个所谓的Lisp-2甚至是Lisp的-N,有两个或多个命名空间。
lambda表达式在功能位置中的函数形式
((lambda (foo) foo) 10)
是由支持内置语法Common Lisp的。 见lambda形式 。
扑朔迷离
这是所有的逻辑,但令人困惑。 不要担心,你并不孤单,但实际上它不是一个大问题。