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

24. Symbols and Variables


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

24.1 Introduction to Symbols

A symbol is basically just an object with four fields: a name (a string), a value (some Lisp object), a function (some Lisp object), and a property list (usually a list of alternating keyword/value pairs). What makes symbols special is that there is usually only one symbol with a given name, and the symbol is referred to by name. This makes a symbol a convenient way of calling up data by name, i.e. of implementing variables. (The variable’s value is stored in the value slot.) Similarly, functions are referenced by name, and the definition of the function is stored in a symbol’s function slot. This means that there can be a distinct function and variable with the same name. The property list is used as a more general mechanism of associating additional values with particular names, and once again the namespace is independent of the function and variable namespaces.


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

24.2 Obarrays

Variable: obarray

The identity of symbols with their names is accomplished through obarray, which is a hash table mapping from strings to symbols (where the symbol names reflect those strings).

Function: intern string &optional (package obarray)

This function looks for a string in package, a hash table with test equal or equalp; if it’s not found, a new symbol is automatically created with the specified name, added to the hash table, and returned. This is what happens when the Lisp reader encounters a symbol (or more precisely, encounters the name of a symbol) in some text that it is reading.

If package is not specified, the value of the variable obarray is used.

Note that, once a symbol is in a hash table, it stays there until something is done about it, and the standard obarray obarray always stays around. Once you use any particular variable name, a corresponding symbol will stay around in obarray until someone calls unintern on it, or until XEmacs exits.

Observe that obarray itself is a variable, and as such there is a symbol in obarray whose name is "obarray" and which contains obarray as its value.

Observe also that this call to intern normally occurs when in the Lisp reader, not when the code is executed (at which point the symbol is already around, stored as such in the definition of the function).

Usually symbols are created by intern, but if you wish, you can explicitly create a symbol using make-symbol, giving it some name. The resulting symbol is not in any obarray (i.e. it is uninterned). Therefore its primary purpose is as a symbol to use in macros to avoid namespace pollution. It can also be used as a carrier of information, but cons cells could probably be used just as well.

Function: intern-soft name &optional (package obarray) default

This is like intern, but the supplied name can be either a string or a symbol. package defaults to obarray, and default defaults to nil; it is useful to set this to a non-symbol value to handle those cases where nil may be symbol of interest.

Function: unintern name &optional (package obarray)

This removes the symbol named name from the hash table package. If name is a symbol, that symbol and only that symbol is removed from package, if present. If it is a string any symbol with that name in package is removed.

Finally, mapatoms maps over all of the symbols in an obarray.


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

24.3 Symbol Values

The value field of a symbol normally contains a Lisp object. However, a symbol can be unbound, meaning that it logically has no value. This is internally indicated by storing a special Lisp object, called the unbound marker and stored in the global variable Qunbound. The unbound marker is of a special Lisp object type called opaque. Despite its name, it is not a symbol. It is impossible for the Lisp programmer to directly create or access any object of this type. Printing it will cause the message ‘INTERNAL EMACS BUG’ to appear as part of the print representation.(1)

When a symbol is created, its value field (and function field) are set to Qunbound. The Lisp programmer can restore these conditions later using makunbound or fmakunbound, and can query to see whether the value of function fields are bound (i.e. have a value other than Qunbound) using boundp and fboundp. The fields are set to a normal Lisp object using set (or setq) and fset.

Other special markers are used to indicate variables that have non-normal properties. These markers are of type “symbol-value-magic”, and are used for any variables that are tied into C variables (setting the variable magically sets some global variable in the C code, and likewise for retrieving the variable’s value), variables that magically tie into slots in the current buffer, variables that are buffer-local, etc. The symbol-value-magic object is stored in the value cell in place of a normal object, and the code to retrieve a symbol’s value (i.e. symbol-value) knows how to do special things with them. This means that you should not just fetch the value cell directly if you want a symbol’s value.

You must not let any “symbol-value-magic” object escape to the Lisp level. Printing any of these objects will cause the message ‘INTERNAL EMACS BUG’ to appear as part of the print representation. (You may see this normally when you call debug_print() from the debugger on a Lisp object.) If you let one of these objects escape to the Lisp level, you will violate a number of assumptions contained in the C code.

The exact workings of this are rather complex and involved and are well-documented in comments in ‘buffer.c’, ‘symbols.c’, and ‘lisp.h’.


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

This document was generated on September 25, 2026 using texi2html 1.82.