Common Lisp the Language, 2nd Edition
Symbols are Lisp data objects that serve several purposes and have several interesting characteristics. Every object of type symbol has a name, called its print name. Given a symbol, one can obtain its name in the form of a string. Conversely, given the name of a symbol as a string, one can obtain the symbol itself. (More precisely, symbols are organized into packages, and all the symbols in a package are uniquely identified by name. See chapter 11.)
Symbols have a component called the property list, or plist. By convention this is always a list whose even-numbered components (calling the first component zero) are symbols, here functioning as property names, and whose odd-numbered components are associated property values. Functions are provided for manipulating this property list; in effect, these allow a symbol to be treated as an extensible record structure.
Symbols are also used to represent certain kinds of variables in Lisp programs, and there are functions for dealing with the values associated with symbols in this role.
A symbol can be notated simply by writing its name. If its name is not empty, and if the name consists only of uppercase alphabetic, numeric, or certain pseudo-alphabetic special characters (but not delimiter characters such as parentheses or space), and if the name of the symbol cannot be mistaken for a number, then the symbol can be notated by the sequence of characters in its name. Any uppercase letters that appear in the (internal) name may be written in either case in the external notation (more on this below). For example:
FROBBOZ ;The symbol whose name is FROBBOZ frobboz ;Another way to notate the same symbol fRObBoz ;Yet another way to notate it unwind-protect ;A symbol with a - in its name +$ ;The symbol named +$ 1+ ;The symbol named 1+ +1 ;This is the integer 1, not a symbol pascal_style ;This symbol has an underscore in its name b^2-4*a*c ;This is a single symbol! ; It has several special characters in its name file.rel.43 ;This symbol has periods in its name /usr/games/zork ;This symbol has slashes in its name
In addition to letters and numbers, the following characters are normally considered to be alphabetic for the purposes of notating symbols:
+ - * / @ $ % ^ & _ = < > ~ .
Some of these characters have conventional purposes for naming things; for example, symbols that name special variables generally have names beginning and ending with *. The last character listed above, the period, is considered alphabetic provided that a token does not consist entirely of periods. A single period standing by itself is used in the notation of conses and dotted lists; a token consisting of two or more periods is syntactically illegal. (The period also serves as the decimal point in the notation of numbers.)
The following characters are also alphabetic by default but are explicitly reserved to the user for definition as reader macro characters (see section 22.1.3) or any other desired purpose and therefore should not be used routinely in names of symbols:
? ! [ ] { }
A symbol may have uppercase letters, lowercase letters, or both in its print name. However, the Lisp reader normally converts lowercase letters to the corresponding uppercase letters when reading symbols. The net effect is that most of the time case makes no difference when notating symbols. Case does make a difference internally and when printing a symbol. Internally the symbols that name all standard Common Lisp functions, variables, and keywords have uppercase names; their names appear in lowercase in this book for readability. Typing such names with lowercase letters works because the function read will convert lowercase letters to the equivalent uppercase letters.
X3J13 voted in June 1989 (READ-CASE-SENSITIVITY) to introduce
readtable-case, which controls whether read will alter the case
of letters read as part of the name of a symbol.
If a symbol cannot be simply notated by the characters of its name because the (internal) name contains special characters or lowercase letters, then there are two ``escape'' conventions for notating them. Writing a character before any character causes the character to be treated itself as an ordinary character for use in a symbol name; in particular, it suppresses internal conversion of lowercase letters to their uppercase equivalents. If any character in a notation is preceded by , then that notation can never be interpreted as a number. For example:
\( ;The symbol whose name is ( \+1 ;The symbol whose name is +1 +\1 ;Also the symbol whose name is +1 \frobboz ;The symbol whose name is fROBBOZ 3.14159265\s0 ;The symbol whose name is 3.14159265s0 3.14159265\S0 ;A different symbol, whose name is 3.14159265S0 3.14159265s0 ;A short-format floating-point approximation to APL\\360 ;The symbol whose name is APL 360 apl\\360 ;Also the symbol whose name is APL 360 \(b^2\)\ -\ 4*a*c ;The name is (B^2) - 4*A*C; ; it has parentheses and two spaces in it \(\b^2\)\ -\ 4*\a*\c ;The name is (b^2) - 4*a*c; ; the letters are explicitly lowercase
It may be tedious to insert a \ before every delimiter character in the name of a symbol if there are many of them. An alternative convention is to surround the name of a symbol with vertical bars; these cause every character between them to be taken as part of the symbol's name, as if \ had been written before each one, excepting only | itself and \, which must nevertheless be preceded by \. For example:
|"| ;The same as writing \" |(b^2) - 4*a*c| ;The name is (b^2) - 4*a*c |frobboz| ;The name is frobboz, not FROBBOZ |APL\360| ;The name is APL360, because the \ quotes the 3 |APL\\360| ;The name is APL\360 |apl\\360| ;The name is apl\360 |\|\|| ;Same as \|\|: the name is || |(B^2) - 4*A*C| ;The name is (B^2) - 4*A*C; ; it has parentheses and two spaces in it |(b^2) - 4*a*c| ;The name is (b^2) - 4*a*c