www.delorie.com/gnu/docs/elisp-manual-21/elisp_171.html   search  
 
Buy the book!


GNU Emacs Lisp Reference Manual

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.8 Accessing Function Cell Contents

The function definition of a symbol is the object stored in the function cell of the symbol. The functions described here access, test, and set the function cell of symbols.

See also the function indirect-function in 9.2.4 Symbol Function Indirection.

Function: symbol-function symbol
This returns the object in the function cell of symbol. If the symbol's function cell is void, a void-function error is signaled.

This function does not check that the returned object is a legitimate function.

 
(defun bar (n) (+ n 2))
     => bar
(symbol-function 'bar)
     => (lambda (n) (+ n 2))
(fset 'baz 'bar)
     => bar
(symbol-function 'baz)
     => bar

If you have never given a symbol any function definition, we say that that symbol's function cell is void. In other words, the function cell does not have any Lisp object in it. If you try to call such a symbol as a function, it signals a void-function error.

Note that void is not the same as nil or the symbol void. The symbols nil and void are Lisp objects, and can be stored into a function cell just as any other object can be (and they can be valid functions if you define them in turn with defun). A void function cell contains no object whatsoever.

You can test the voidness of a symbol's function definition with fboundp. After you have given a symbol a function definition, you can make it void once more using fmakunbound.

Function: fboundp symbol
This function returns t if the symbol has an object in its function cell, nil otherwise. It does not check that the object is a legitimate function.

Function: fmakunbound symbol
This function makes symbol's function cell void, so that a subsequent attempt to access this cell will cause a void-function error. (See also makunbound, in 11.4 When a Variable is "Void".)

 
(defun foo (x) x)
     => foo
(foo 1)
     =>1
(fmakunbound 'foo)
     => foo
(foo 1)
error--> Symbol's function definition is void: foo

Function: fset symbol definition
This function stores definition in the function cell of symbol. The result is definition. Normally definition should be a function or the name of a function, but this is not checked. The argument symbol is an ordinary evaluated argument.

There are three normal uses of this function:

Here are examples of these uses:

 
;; Save foo's definition in old-foo.
(fset 'old-foo (symbol-function 'foo))

;; Make the symbol car the function definition of xfirst.
;; (Most likely, defalias would be better than fset here.)
(fset 'xfirst 'car)
     => car
(xfirst '(1 2 3))
     => 1
(symbol-function 'xfirst)
     => car
(symbol-function (symbol-function 'xfirst))
     => #<subr car>

;; Define a named keyboard macro.
(fset 'kill-two-lines "\^u2\^k")
     => "\^u2\^k"

;; Here is a function that alters other functions.
(defun copy-function-definition (new old)
  "Define NEW with the same function definition as OLD."
  (fset new (symbol-function old)))

When writing a function that extends a previously defined function, the following idiom is sometimes used:

 
(fset 'old-foo (symbol-function 'foo))
(defun foo ()
  "Just like old-foo, except more so."
  (old-foo)
  (more-so))

This does not work properly if foo has been defined to autoload. In such a case, when foo calls old-foo, Lisp attempts to define old-foo by loading a file. Since this presumably defines foo rather than old-foo, it does not produce the proper results. The only way to avoid this problem is to make sure the file is loaded before moving aside the old definition of foo.

But it is unmodular and unclean, in any case, for a Lisp file to redefine a function defined elsewhere. It is cleaner to use the advice facility (see section 17. Advising Emacs Lisp Functions).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003