When to use #' (function) in front of lambda e

2019-07-05 17:44发布

I understand that, because there are separate namespaces in Common Lisp for functions and variables, you can do this:

((lambda (x) (* 2 x)) 3)

and you can also do this:

(funcall #'(lambda (x) (* 2 x)) 3)

When should we use #' as opposed to not using it? I read in another StackOverflow question that #' was only kept around for historic reasons and shouldn't be used anymore. Is this true? My question is not a duplicate, I am asking about when I would use these in my code.

标签: common-lisp
1条回答
ら.Afraid
2楼-- · 2019-07-05 18:49

It's not an issue of lisp-2 versus lisp-1. With lambda expressions in a position where a function value is needed, it's simply a stylistic choice. Some people like the visual marker of #' and some don't. The lambda macro already expands into the function form for which #' provides an abbreviation:

Macro LAMBDA

    (lambda lambda-list [[declaration* | documentation]] form*)
 ==  (function (lambda lambda-list [[declaration* | documentation]] form*))
 ==  #'(lambda lambda-list [[declaration* | documentation]] form*)

#'x is just syntactic sugar for (function x), and the function special operator provides "the functional value of name in the current lexical environment." T

Special Operator FUNCTION

The value of function is the functional value of name in the current lexical environment.

If name is a function name, the functional definition of that name is that established by the innermost lexically enclosing flet, labels, or macrolet form, if there is one. Otherwise the global functional definition of the function name is returned.

While (lambda ...) is the name of a function, it's not a name that could ever be established by a flet, label, or macrolet form, so you're always getting "the global definition of the function name", which is just the lambda function. Since (lambda ...) expands to (function (lambda ...)), there's no difference. It's just a matter of style.

However, it is important to note that in the first case that you talked about,

((lambda (x) (* x 2)) 3)

you could not do:

(#'(lambda (x) (* x 2)) 3)            ; or
((function (lambda (x) (* x 2))) 3)

The support for ((lambda ...) ...) is part of the language, unrelated to the fact that there's a definition of lambda as a macro. It's a particular type of compound form, namely a lambda form, which is described in the HyperSpec:

3.1.2.1.2.4 Lambda Forms

A lambda form is similar to a function form, except that the function name is replaced by a lambda expression.

A lambda form is equivalent to using funcall of a lexical closure of the lambda expression on the given arguments. (In practice, some compilers are more likely to produce inline code for a lambda form than for an arbitrary named function that has been declared inline; however, such a difference is not semantic.)

For further information, see Section 3.1.3 (Lambda Expressions).

查看更多
登录 后发表回答