6.6.6 Symbols

Symbols in Scheme are widely used in three ways: as items of discrete data, as lookup keys for alists and hash tables, and to denote variable references.

A symbol is similar to a string in that it is defined by a sequence of characters. The sequence of characters is known as the symbol’s name. In the usual case — that is, where the symbol’s name doesn’t include any characters that could be confused with other elements of Scheme syntax — a symbol is written in a Scheme program by writing the sequence of characters that make up the name, without any quotation marks or other special syntax. For example, the symbol whose name is “multiply-by-2” is written, simply:

multiply-by-2

Notice how this differs from a string with contents “multiply-by-2”, which is written with double quotation marks, like this:

"multiply-by-2"

Looking beyond how they are written, symbols are different from strings in two important respects.

The first important difference is uniqueness. If the same-looking string is read twice from two different places in a program, the result is two different string objects whose contents just happen to be the same. If, on the other hand, the same-looking symbol is read twice from two different places in a program, the result is the same symbol object both times.

Given two read symbols, you can use eq? to test whether they are the same (that is, have the same name). eq? is the most efficient comparison operator in Scheme, and comparing two symbols like this is as fast as comparing, for example, two numbers. Given two strings, on the other hand, you must use equal? or string=?, which are much slower comparison operators, to determine whether the strings have the same contents.

(define sym1 (quote hello))
(define sym2 (quote hello))
(eq? sym1 sym2) ⇒ #t

(define str1 "hello")
(define str2 "hello")
(eq? str1 str2) ⇒ #f
(equal? str1 str2) ⇒ #t

The second important difference is that symbols, unlike strings, are not self-evaluating. This is why we need the (quote …)s in the example above: (quote hello) evaluates to the symbol named "hello" itself, whereas an unquoted hello is read as the symbol named "hello" and evaluated as a variable reference … about which more below (see Symbols as Denoting Variables).