Go to the previous, next section.
To understand how symbols are created in GNU Emacs Lisp, you must know how Lisp reads them. Lisp must ensure that it finds the same symbol every time it reads the same set of characters. Failure to do so would cause complete confusion.
When the Lisp reader encounters a symbol, it reads all the characters of the name. Then it "hashes" those characters to find an index in a table called an obarray. Hashing is an efficient method of looking something up. For example, instead of searching a telephone book cover to cover when looking up Jan Jones, you start with the J's and go from there. That is a simple version of hashing. Each element of the obarray is a bucket which holds all the symbols with a given hash code; to look for a given name, it is sufficient to look through all the symbols in the bucket for that name's hash code.
If a symbol with the desired name is found, then it is used. If no such symbol is found, then a new symbol is created and added to the obarray bucket. Adding a symbol to an obarray is called interning it, and the symbol is then called an interned symbol. In Emacs Lisp, a symbol may be interned in only one obarray--if you try to intern the same symbol in more than one obarray, you will get unpredictable results.
It is possible for two different symbols to have the same name in
different obarrays; these symbols are not eq or equal.
However, this normally happens only as part of abbrev definition
(see section Abbrevs And Abbrev Expansion).
Common Lisp note: in Common Lisp, a symbol may be interned in several obarrays at once.
If a symbol is not in the obarray, then there is no way for Lisp to find it when its name is read. Such a symbol is called an uninterned symbol relative to the obarray. An uninterned symbol has all the other characteristics of symbols.
In Emacs Lisp, an obarray is represented as a vector. Each element of
the vector is a bucket; its value is either an interned symbol whose
name hashes to that bucket, or 0 if the bucket is empty. Each interned
symbol has an internal link (invisible to the user) to the next symbol
in the bucket. Because these links are invisible, there is no way to
scan the symbols in an obarray except using mapatoms (below).
The order of symbols in a bucket is not significant.
In an empty obarray, every element is 0, and you can create an obarray
with (make-vector length 0). This is the only
valid way to create an obarray. Prime numbers as lengths tend
to result in good hashing; lengths one less than a power of two are also
good.
Do not try to create an obarray that is not empty. This
does not work--only intern can enter a symbol in an obarray
properly. Also, don't try to put into an obarray of your own
a symbol that is already interned in the main obarray, because in
Emacs Lisp a symbol cannot be in two obarrays at once.
Most of the functions below take a name and sometimes an obarray as
arguments. A wrong-type-argument error is signaled if the name
is not a string, or if the obarray is not a vector.
This function returns the string that is symbol's name. For example:
(symbol-name 'foo)
=> "foo"
Changing the string by substituting characters, etc, does change the name of the symbol, but fails to update the obarray, so don't do it!
This function returns a newly-allocated, uninterned symbol whose name is
name (which must be a string). Its value and function definition
are void, and its property list is nil. In the example below,
the value of sym is not eq to foo because it is a
distinct uninterned symbol whose name is also `foo'.
(setq sym (make-symbol "foo"))
=> foo
(eq sym 'foo)
=> nil
Function: intern name &optional obarray
This function returns the interned symbol whose name is name. If
there is no such symbol in the obarray, a new one is created, added to
the obarray, and returned. If obarray is supplied, it specifies
the obarray to use; otherwise, the value of the global variable
obarray is used.
(setq sym (intern "foo"))
=> foo
(eq sym 'foo)
=> t
(setq sym1 (intern "foo" other-obarray))
=> foo
(eq sym 'foo)
=> nil
Function: intern-soft name &optional obarray
This function returns the symbol whose name is name, or nil
if a symbol with that name is not found in the obarray. Therefore, you
can use intern-soft to test whether a symbol with a given name is
interned. If obarray is supplied, it specifies the obarray to
use; otherwise the value of the global variable obarray is used.
(intern-soft "frazzle") ; No such symbol exists.
=> nil
(make-symbol "frazzle") ; Create an uninterned one.
=> frazzle
(intern-soft "frazzle") ; That one cannot be found.
=> nil
(setq sym (intern "frazzle")) ; Create an interned one.
=> frazzle
(intern-soft "frazzle") ; That one can be found!
=> frazzle
(eq sym 'frazzle) ; And it is the same one.
=> t
This variable is the standard obarray for use by intern and
read.
Function: mapatoms function &optional obarray
This function applies function to every symbol in obarray.
It returns nil. If obarray is not supplied, it defaults to
the value of obarray, the standard obarray for ordinary symbols.
(setq count 0)
=> 0
(defun count-syms (s)
(setq count (1+ count)))
=> count-syms
(mapatoms 'count-syms)
=> nil
count
=> 1871
See documentation in section Access to Documentation Strings, for another
example using mapatoms.
Go to the previous, next section.