(lispref.info)Creating Symbols

Next: Property Lists Prev: Definitions Up: Symbols

Creating and Interning Symbols

   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

   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 (*note

     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.

 - Function: symbol-name SYMBOL
     This function returns the string that is SYMBOL's name.  For

          (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!

 - Function: make-symbol NAME
     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

 - Variable: obarray
     This variable is the standard obarray for use by `intern' and

 - 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
               => 1871

     See `documentation' in Note: Accessing Documentation, for another
     example using `mapatoms'.

automatically generated by info2www