Chapter 3 - Essential Lisp in Twelve Lessons

Lesson 5 - Naming and Identity

A symbol is just a name

A symbol is just a name. It can stand for itself. This makes it easy to write certain kinds of programs in Lisp. For example, if you want your program to represent relationships in your family tree, you can make a database that keeps relationships like this:

(father John Barry)
(son John Harold)
(father John Susan)
(mother Edith Barry)
(mother Edith Susan)

Each relationship is a list. (father John Barry) means that John is Barry's father. Every element of every list in our database is a symbol. Your Lisp program can compare symbols in this database to determine, for example, that Harold is Barry's grandfather. If you tried to write a program like this in another language -- a language without symbols -- you'd have to decide how to represent the names of family members and relationships, and then create code to perform all the needed operations -- reading, printing, comparison, assignment, etc. This is all built into Lisp, because symbols are a data type distinct from the objects they might be used to name.

A symbol is always unique

Every time your program uses a symbol, that symbol is identical to every other symbol with the same name. You can use the EQ test to compare symbols:

? (eq 'a 'a)
-> T

? (eq 'david 'a)
-> NIL

? (eq 'David 'DAVID)
-> T

? (setq zzz 'sleeper)

? (eq zzz 'sleeper)
-> T

Notice that it doesn't matter whether you use uppercase or lowercase letters in your symbol names. Internally, Lisp translates every alphabetic character in a symbol name to a common case -- usually upper, but you can control this by setting a flag in the Lisp reader.

When you learn about packages in Lesson 10 (also see Chapter 31), you can create symbol names that are not identical given the same spelling. For now, all you need to know is that any symbol spelled with a : gets special treatment.

A symbol can name a value

Although the ability for a Lisp symbol to stand for itself is sometimes useful, a more common use is for the symbol to name a value. This is the role played by variable and function names in other programming languages. A Lisp symbol most commonly names a value or -- when used as the first element of a function call form -- a function.

What's unusual about Lisp is that a symbol can have a value as a function and a variable at the same time:

? (setq first 'number-one)

? (first (list 3 2 1))
-> 3

? first

Note how FIRST is used as a variable in the first and last case, and as a function (predefined by Lisp, in this example) in the second case. Lisp decides which of these values to use based on where the symbol appears. When the evaluation rule requires a value, Lisp looks for the variable value of the symbol. When a function is called for, Lisp looks for the symbol's function.

A symbol can have other values besides those it has as a variable or function. A symbol can also have values for its documentation, property list, and print name. A symbol's documentation is text that you create to describe a symbol. You can create this using the DOCUMENTATION form or as part of certain forms which define a symbol's value. Because a symbol can have multiple meanings, you can assign documentation to each of several meanings, for example as a function and as a variable.

A property list is like a small database with a single key per entry. We'll look at this use of symbols in Lesson 10.

The print name is what Lisp uses to print the symbol. You normally don't want to change this; if you do, Lisp will print the symbol with a different name than it originally used to read the symbol, which will create a different symbol when later read by Lisp.

A value can have more than one name

A value can have more than one name. That is, more than one symbol can share a value. Other languages have pointers that work this way. Lisp does not expose pointers to the programmer, but does have shared objects. An object is considered identical when it passes the EQ test. Consider the following:

? (setq L1 (list 'a 'b 'c))
-> (A B C)

? (setq L2 L1)
-> (A B C)

? (eq L1 L2)
-> T

? (setq L3 (list 'a 'b 'c))
-> (A B C)

? (eq L3 L1)
-> NIL

Here, L1 is EQ to L2 because L1 names the same value as L2. In other words, the value created by the (LIST 'A 'B 'C) form has two names, L1 and L2. The (SETQ L2 L1) form says, "Make the value of L2 be the value of L1." Not a copy of the the value, but the value. So L1 and L2 share the same value -- the list (A B C) which was first assigned as the value of L1.

L3 also has a list (A B C) as its value, but it is a different list than the one shared by L1 and L2. Even though the value of L3 looks the same as the value of L1 and L2, it is a different list because it was created by a different LIST form. So (EQ L3 L1)->NIL because their values are different lists, each made of the symbols A, B, and C.

Contents | Cover
Chapter 2 | Chapter 3, Introduction | Chapter 3, Lesson 4 | Chapter 3, Lesson 5 | Chapter 3, Lesson 6 | Chapter 4 |

Copyright © 1995-2001, David B. Lamkins
All Rights Reserved Worldwide

This book may not be reproduced without the written consent of its author. Online distribution is restricted to the author's site.