ErgoEmacsEmacsLispBlogEmacsLispBuy Tutorial

12.7 Anonymous Functions

In Lisp, a function is a list that starts with lambda, a byte-code function compiled from such a list, or alternatively a primitive subr-object; names are “extra.” Although functions are usually defined with defun and given names at the same time, it is occasionally more concise to use an explicit lambda expression—an anonymous function. Such a list is valid wherever a function name is.

Any method of creating such a list makes a valid function. Even this:

     (setq silly (append '(lambda (x)) (list (list '+ (* 3 4) 'x))))
     ⇒ (lambda (x) (+ 12 x))

This computes a list that looks like (lambda (x) (+ 12 x)) and makes it the value (not the function definition!) of silly.

Here is how we might call this function:

     (funcall silly 1)
     ⇒ 13

It does not work to write (silly 1), because this function is not the function definition of silly. We have not given silly any function definition, just a value as a variable.

Most of the time, anonymous functions are constants that appear in your program. For instance, you might want to pass one as an argument to the function mapcar, which applies any given function to each element of a list (see Mapping Functions). See describe-symbols example, for a realistic example of this.

In the following example, we define a change-property function that takes a function as its third argument, followed by a double-property function that makes use of change-property by passing it an anonymous function:

     (defun change-property (symbol prop function)
       (let ((value (get symbol prop)))
         (put symbol prop (funcall function value))))
     
     (defun double-property (symbol prop)
       (change-property symbol prop (lambda (x) (* 2 x))))

In the double-property function, we did not quote the lambda form. This is permissible, because a lambda form is self-quoting: evaluating the form yields the form itself.

Whether or not you quote a lambda form makes a difference if you compile the code (see Byte Compilation). If the lambda form is unquoted, as in the above example, the anonymous function is also compiled. Suppose, however, that we quoted the lambda form:

     (defun double-property (symbol prop)
       (change-property symbol prop '(lambda (x) (* 2 x))))

If you compile this, the argument passed to change-property is the precise list shown:

     (lambda (x) (* x 2))

The Lisp compiler cannot assume this list is a function, even though it looks like one, since it does not know what change-property will do with the list. Perhaps it will check whether the car of the third element is the symbol *!

The function special form explicitly tells the byte-compiler that its argument is a function:

— Special Form: function function-object

This special form returns function-object without evaluating it. In this, it is equivalent to quote. However, it serves as a note to the Emacs Lisp compiler that function-object is intended to be used only as a function, and therefore can safely be compiled. Contrast this with quote, in Quoting.

The read syntax #' is a short-hand for using function. Generally, it is not necessary to use either #' or function; just use an unquoted lambda form instead. (Actually, lambda is a macro defined using function.) The following forms are all equivalent:

     #'(lambda (x) (* x x))
     (function (lambda (x) (* x x)))
     (lambda (x) (* x x))

We sometimes write function instead of quote when quoting the name of a function, but this usage is just a sort of comment:

     (function symbol) == (quote symbol) == 'symbol
blog comments powered by Disqus