From the documentation of the function
form:
Like `quote', but preferred for objects which are functions. In byte compilation, `function' causes its argument to be compiled. `quote' cannot do that.
So one would do #'(lambda ...)
to enable byte compilation of the lambda form.
On the other hand, as mentioned in the manual, That is no longer necessary.
The lambda form has one other effect: it tells the Emacs evaluator and byte-compiler that its argument is a function, by using
function
as a subroutine.
[...] The following forms are all equivalent:
(lambda (x) (* x x))
(function (lambda (x) (* x x)))
#'(lambda (x) (* x x))
This renders the function form useless in this case.
Is there any other situation where the function form would have been useful?
Is there any case when its presence is neither unnecessary nor identical to quote
?
#'
(aka function
) is used internally by lambda
, since lambda
is defined as a macro that wraps itself in a function
.
But other than that, you indeed can write pretty much any Elisp code without using #'
. There is one other subtlety, tho: if you write #'foo
you tell Emacs that you think foo
is the name of a function, so recent versions of the byte-compiler will then warn if foo
is not a known function (just like they've been warning about calls to (foo ...)
for many years already).
As pointed out by @Bruce, the use of #'foo
instead of 'foo
also makes a real difference for functions defined locally via cl-flet
or cl-labels
: in that case #'foo
refers to the locally defined function, whereas 'foo
will simply refer to the foo
symbol, which is not actually related to the local function definition and may hence by unbound or bound to another function:
(cl-flet ((a () 1)) (list 'a (functionp 'a) #'a))
returns
(a nil (lambda nil 1))
lambda
is a macro. It has to be expanded and it is expanded every time. Like this:
(lambda (x) x) -> (function (lambda (x) x)) ; #'(lambda (x) x)
function
is a special operator. In fact, it treats lambda
forms specially, otherwise we would never be able to expand lambda
macro:
(lambda (x) x) ->
(function (lambda (x) x)) ->
(function (function (lambda (x) x))) ->
...
function
looks at its argument and if it is a lambda
form, it compiles the function. If its argument is a symbol, then it searches for compiled function associated with the symbol.
So, we see now, that function
(like quote
) does not evaluate its argument. It must have special behavior, thus it is a special operator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With