Common Lisp the Language, 2nd Edition

Next: Packages Up: Symbols Previous: The Print Name

# 10.3. Creating Symbols

Symbols can be used in two rather different ways. An interned symbol is one that is indexed by its print name in a catalogue called a package. A request to locate a symbol with that print name results in the same (`eq`) symbol. Every time input is read with the function `read`, and that print name appears, it is read as the same symbol. This property of symbols makes them appropriate to use as names for things and as hooks on which to hang permanent data objects (using the property list, for example).

Interned symbols are normally created automatically; the first time something (such as the function `read`) asks the package system for a symbol with a given print name, that symbol is automatically created. The function used to ask for an interned symbol is `intern`, or one of the functions related to `intern`.

Although interned symbols are the most commonly used, they will not be discussed further here. For more information, see chapter 11.

An uninterned symbol is a symbol used simply as a data object, with no special cataloguing (it belongs to no particular package). An uninterned symbol is printed as `#:` followed by its print name. The following are some functions for creating uninterned symbols.

[Function]
`make-symbol print-name`

`(make-symbol print-name)` creates a new uninterned symbol, whose print name is the string print-name. The value and function bindings will be unbound and the property list will be empty.

The string actually installed in the symbol's print-name component may be the given string print-name or may be a copy of it, at the implementation's discretion. The user should not assume that `(symbol-name (make-symbol x))` is `eq` to `x`, but also should not alter a string once it has been given as an argument to `make-symbol`.

Compatibility note: An implementation might choose, for example, to copy the string to some read-only area, in the expectation that it will never be altered.

[Function]
`copy-symbol sym &optional copy-props`

This returns a new uninterned symbol with the same print name as sym.

X3J13 voted in March 1989 (COPY-SYMBOL-PRINT-NAME) that the print name of the new symbol is required to be the same only in the sense of `string=`; in other words, an implementation is permitted (but not required) to make a copy of the print name. User programs should not assume that the print names of the old and new symbols will be `eq`, although they may happen to be `eq` in some implementations.

If copy-props is non-`nil`, then the initial value and function definition of the new symbol will be the same as those of sym, and the property list of the new symbol will be a copy of sym's.

X3J13 voted in March 1989 (COPY-SYMBOL-COPY-PLIST) to clarify that only the top-level conses of the property list are copied; it is as if `(copy-list (symbol-plist sym))` were used as the property list of the new symbol.

If copy-props is `nil` (the default), then the new symbol will be unbound and undefined, and its property list will be empty.

[Function]
`gensym &optional x`

`gensym` invents a print name and creates a new symbol with that print name. It returns the new, uninterned symbol.

The invented print name consists of a prefix (which defaults to `G`), followed by the decimal representation of a number.

The number is increased by 1 every time `gensym` is called.

If the argument x is present and is an integer, then x must be non-negative, and the internal counter is set to x for future use; otherwise the internal counter is incremented. If x is a string, then that string is made the default prefix for this and future calls to `gensym`. After handling the argument, `gensym` creates a symbol as it would with no argument. For example:

    (gensym) => G7
    (gensym "FOO-") => FOO-8
    (gensym 32) => FOO-32
    (gensym) => FOO-33
    (gensym "GARBAGE-") => GARBAGE-34

`gensym` is usually used to create a symbol that should not normally be seen by the user and whose print name is unimportant except to allow easy distinction by eye between two such symbols. The optional argument is rarely supplied. The name comes from ``generate symbol,'' and the symbols produced by it are often called ``gensyms.''

Compatibility note: In earlier versions of Lisp, such as MacLisp and Interlisp, the print name of a gensym was of fixed length, consisting of a single letter and a fixed-length decimal representation with leading zeros if necessary, for example, `G0007`. This convention was motivated by an implementation consideration, namely that the name should fit into a single machine word, allowing a quick and clever implementation. Such considerations are less relevant in Common Lisp. The consistent use of mnemonic prefixes can make it easier for the programmer, when debugging, to determine what code generated a particular symbol. The elimination of the fixed-length decimal representation prevents the same name from being used twice unless the counter is explicitly reset.

If it is desirable for the generated symbols to be interned, and yet guaranteed to be symbols distinct from all others, then the function `gentemp` may be more appropriate to use.

X3J13 voted in March 1989 (GENSYM-NAME-STICKINESS) to alter the specification of `gensym` so that supplying an optional argument (whether a string or a number) does not alter the internal state maintained by `gensym`. Instead, the internal counter is made explicitly available as a variable named `*gensym-counter*`.

If a string argument is given to `gensym`, that string is used as the prefix; otherwise ```G`'' is used. If a number is provided, its decimal representation is used, but the internal counter is unaffected. X3J13 deprecates the use of a number as an argument.

[Variable]
`*gensym-counter*`

X3J13 voted in March 1989 (GENSYM-NAME-STICKINESS) to add `*gensym-counter*`, which holds the state of the `gensym` counter; that is, `gensym` uses the decimal representation of its value as part of the generated name and then increments its value.

The initial value of this variable is implementation-dependent but will be a non-negative integer.

The user may assign to or bind this variable at any time, but its value must always be a non-negative integer.

[Function]
`gentemp &optional prefix package`

`gentemp`, like `gensym`, creates and returns a new symbol. `gentemp` differs from `gensym` in that it interns the symbol (see `intern`) in the package (which defaults to the current package; see `*package*`). `gentemp` guarantees the symbol will be a new one not already existing in the package. It does this by using a counter as `gensym` does, but if the generated symbol is not really new, then the process is repeated until a new one is created. There is no provision for resetting the `gentemp` counter. Also, the prefix for `gentemp` is not remembered from one call to the next; if prefix is omitted, the default prefix `T` is used.

[Function]
`symbol-package sym`

Given a symbol sym, `symbol-package` returns the contents of the package cell of that symbol. This will be a package object or `nil`.

[Function]
`keywordp object`

The argument may be any Lisp object. The predicate `keywordp` is true if the argument is a symbol and that symbol is a keyword (that is, belongs to the keyword package). Keywords are those symbols that are written with a leading colon. Every keyword is a constant, in the sense that it always evaluates to itself. See `constantp`.

Next: Packages Up: Symbols Previous: The Print Name