Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does (function) serve any purpose in Emacs?

Tags:

emacs

lisp

elisp

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?

like image 245
Malabarba Avatar asked Aug 12 '14 23:08

Malabarba


2 Answers

#' (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))
like image 92
Stefan Avatar answered Sep 21 '22 00:09

Stefan


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.

like image 39
Mark Karpov Avatar answered Sep 18 '22 00:09

Mark Karpov