Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs Lisp: difference between (function (lambda ...)) and (lambda ...)?

What is the difference between

(function (lambda ...))

and

(lambda ...) 

and

'(lambda ...)

?

It seems three are interchangeable in a lot of cases.

like image 733
Yoo Avatar asked Dec 05 '09 17:12

Yoo


1 Answers

They are pretty interchangeable. The answer is that function enables the lambda to be byte compiled, whereas the other two do not (and are equivalent). Note: this does not mean that function actually byte compile the lambda.

How might one figure that out? A little Emacs lisp introspection provides some clues. To start: C-h f function RET:

function is a special form in 'C source code'.

(function arg)

Like 'quote', but preferred for objects which are functions. In byte compilation, 'function' causes its argument to be compiled. 'quote' cannot do that.

Ok, so that's the difference between (function (lambda ...)) and '(lambda ...), the first tells the byte compiler that it may safely compile the expression. Whereas the 'ed expressions may not necessarily be compiled (for they might just be a list of numbers.

What about just the bare (lambda ...)? C-h f lambda RET shows:

lambda is a Lisp macro in `subr.el'.

(lambda args [docstring] [interactive] body)

Return a lambda expression. A call of the form (lambda args docstring interactive body) is self-quoting; the result of evaluating the lambda expression is the expression itself. The lambda expression may then be treated as a function, i.e., stored as the function value of a symbol, passed to 'funcall' or 'mapcar', etc.

Therefore, (lambda ...) and '(lambda ...) are equivalent.

Also, there is the notation #'(lambda ...), which is syntactic sugar for (function (lambda ...)).

For more information on functions in Emacs lisp, read the Functions info pages.

Just to check all this, you can type the following into the *scratch* buffer and evaluate the expressions:

(caddr '(lambda (x) (+ x x)))
(+ x x)

(caddr (lambda (x) (+ x x)))
(+ x x)

(caddr (function (lambda (x) (+ x x))))
(+ x x)

(equal '(lambda (x) (+ x x))
       (function (lambda (x) (+ x x))))
t

(equal '(lambda (x) (+ x x))
       (lambda (x) (+ x x)))
t

So, all three variants of using lambda just build up lists that may be used as functions (one of which may be byte compiled).

like image 155
Trey Jackson Avatar answered Oct 19 '22 17:10

Trey Jackson