18

我目前正在阅读 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 加前缀,会不会出现任何问题#',它是否依赖于实现?

4

1 回答 1

25

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

The LAMBDA macro

LAMBDA is a macro. It expands (lambda ...) to (function (lambda ...)), which is the equivalent of #'(lambda ...)).

CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))

The macro saves you a bit of writing/reading, that's all. In the first version of Common Lisp (CLtL1) there was no LAMBDA macro. It has been added later and is now a part of ANSI Common Lisp,

The FUNCTION special operator

FUNCTION is a special operator. It expects a function name or a lambda expression. Thus the name or the lambda expression are not evaluated. In fact lambda expressions can't be evaluated at all. Inside FUNCTION, the lambda expression is not a macro form and thus will not be expanded again. The purpose of FUNCTION is to return the corresponding function object which is denoted by the name or by the lambda expression. It returns the function object as a value. With this special operator one can access the function object from global functions and lexical functions.

The FUNCTION operator is necessary in Common Lisp, because it has separate namespaces for values, functions and a few other things. It as a so-called Lisp-2 or even Lisp-n, with two or more namespaces.

Lambda expressions in function position in a function form

((lambda (foo) foo) 10) is supported by built-in syntax for Common Lisp. See Lambda Forms.

Confusing

This is all logical, but confusing. Don't worry you are not alone, but in practice it's not a big deal.

于 2012-11-03T21:38:43.003 回答