LEARNING LISP

Contents | More Lists | Bag of Predicates

Atoms and Values

In the previous chapters we discussed lists of objects. These objects could have been either atoms or lists. The exact meaning of atom was sidestepped. Here we will look a little deeper into what an atom is and how they hold information.

Let's go back and repeat the definition of an atom given in chapter 2: An atom is a word or a number or the pair of parentheses "()" which we will call "NIL". So, by that description, all of the following are atoms:

hello
31415
()
car
axe
0
stephen
anatom
12345

In fact, there are a few more things that we can use as atoms also. The rules for creating atoms are, to be exact, as follows.

Using the above rules, these are not atoms:
456test
a sentence like this is not an atom
some'stuff
this(isn't(one(either
(1 2 3 4)   [this one's a list, remember?]

As we usually do, we'll see what happens when atoms are given to Lisp to evaluate.

:ANATOM

    ** ERROR: UNDEFINED ATOM **
      EVAL :: ANATOM

+()

  NIL

:T

  T

:NIL

  NIL

:()

  NIL

:567

  567
That seemed to work alright, except for the first one. What happened? It looks like some atoms are defined according to Lisp and some aren't.

Atoms have values. Some atoms have values that are automatically set by Lisp when you start it. Others need to be given values by you, the user, when you want to do something. When an atom is typed into Lisp it is evaluated just like a list except that instead of executing a function, the result of the evaluation is the value of that atom.

We can see the types of atoms mentioned in the previous paragraph used in the example above. The atoms "T" and "NIL" seem to already have values in Lisp. The value of "T" is "T". The value of "NIL" is "NIL" or "()" which, as we've said over and over, is the same thing. The atom 567 also has a value. In fact, all numeric atoms have values that are the numbers they represent. Numbers and those special atoms are called self-defining atoms.

Okay, then how do we define those atoms that aren't self-defining? There's a way to do that too! [There's a way to do most everything in Lisp.]

Watch this:

:LOVE

    ** ERROR: UNDEFINED ATOM **
      EVAL :: LOVE

+()

  NIL

:(SETQ LOVE 5)

  5

:LOVE

  5

:(SETQ HAPPINESS LOVE)

  5

:HAPPINESS

  5

:(SETQ POWER FREEDOM)

    ** ERROR: UNDEFINED ATOM **
      EVAL :: FREEDOM

+()

  NIL
The first example just shows that, in fact, the value of love is undefined. Let's define it.

The SETQ function takes the name of an atom and the value to "assign" to that atom. It puts that value into the named atom and then, voila, instant definition! Note that the value returned by SETQ is the same as the value of the second argument. You will find that all Lisp expressions return a value of some kind.

Note that, in the fourth example, the atom now properly defined has a value that can be used to assign to other atoms. An error will occur if you try to assign the value of an undefined atom in a SETQ operation.

As with a list, if we want to tell Lisp not to try to evaluate an atom, you can simply put a single quote before it:

:THE-VALUE

    ** ERROR: UNDEFINED ATOM **
      EVAL :: THE-VALUE

+()

  NIL

:(SETQ ATOM1 'THE-VALUE)

  THE-VALUE

:(CONS ATOM1 '(IS THE VALUE OF ATOM1))

  (THE-VALUE IS THE VALUE OF ATOM1 )

:(SETQ ATOM2 (CONS ATOM1 '(IS THE VALUE

: OF ATOM1))))

  (THE-VALUE IS THE VALUE OF ATOM1 )
Above, we have used the value of ATOM1 and the CONS function to create a list made up of the value of ATOM1 and some other atoms. You should be very careful about the placement of quotes at all times. A quote is used when you mean the expression itself rather than the result of evaluation of the expression.

In the last example, the result of the CONS operation is SETQed into a new atom: ATOM2.

You will find that one of the best uses of SETQ is to save you from having to type the same list over and over again. We can use atom values in our examples to save our typing also. This is one of the examples from chapter 2 redone with value atoms and SETQ's:

:(SETQ SANDWITCH '(SAND WITCH))

  (SAND WITCH)

:(CDR SANDWITCH)

  (WITCH )

:(CDR (CDR (CDR  SANDWITCH)))))

  NIL

:(CAR (CDR SANDWITCH))

  WITCH

:(CAR (CAR (CDR (SETQ CLOWNY ' (() ((BOZO

:) (NO NO))))))))
  (BOZO )

:(CDR (CAR (CDR CLOWNY)))

  ((NO NO ) )

:(CAR (CAR (CDR (CAR (CDR CLOWNY)))))))
You should go back to the example in the previous chapter and carefully study what was done in order to use value-atoms. Let's not lose sight of the evaluation process in all thiss mumbo-jumbo. Remember that the arguments of a function are evaluated first and the results are replaced for that position in the expression. Using this rule, let's go through the evaluation of the last expression above.

We start out with:

:(CAR (CAR (CDR (CAR (CDR CLOWNY)))))

  NO
First, "clowny" is evaluated as a list that was SETQed to it previously, giving us:
(car (car (cdr (car (cdr '(()  ((bozo) (no no))))))))
[The underlined portion is the SETQed text]. The various CARs and CDRs are evaluated giving:
(car (car (cdr (car  '(((bozo) (no no))))))))
(car (car (cdr  '((bozo) (no no)))))
(car (car  '((no no))))
(car  '(no no))
no
This process is the most important thing that you need to know and it is assumed in all our discussions.

One last thing before we move on. It is often useful to be able to put funny characters [like spaces and open or close parens] into atom names. The most obvious use of this is to print things out. Even though it's technically against the rules to use spaces, etc., in atom names, Lisp provides a way to do so. The quotation character ["] can be used to enclose atom names. Don't confuse this with the quote that stops evaluation. For example:

:(SETQ "A LONG ATOM NAME" 5)

  5

:"A LONG ATOM NAME"

  5

:(SETQ "ANOTHER NAME" '"A MESSAGE")

  A MESSAGE

:"ANOTHER NAME"

  A MESSAGE

:
In the second example above, we quoted an enclosed atom in order to put a message with spaces in as the value of the atom: A LONG ATOM NAME
Note that Lisp doesn't print out the quotation marks around enclosed names. This is convenient because it permits us to use them as messages. You'll see this used if you look over the code for the Lisp editor that is included in an appendix. Don't look now, though. You'll need to know more of the language first.

Exercises

  1. Indicate what you think Lisp would respond with if you type in the following:
    1. :(setq apple 'fruit)
    2. :(setq pear apple)
    3. :(setq iq 140)
    4. :(setq 15 12)
    5. :'apple
    6. :apple
    7. :"apple"
    8. :'"()"
  2. Remember all the recopying that we did in the most recent set of exercises. Well, now you should be able to figure out how to set the phone list as the value of some variable, and just use that variable. Try it.

Answers

  1. FRUIT
  2. FRUIT
  3. 140
  4. You should expect this to cause an error; since numeric atoms are self-defining, you shouldn't be able to change their values.
  5. APPLE
  6. FRUIT
  7. FRUIT. Note that APPLE and "APPLE" denote the same atom, since the atom names are the same (double quotes enclose atom names, but are not part of the name).
  8. (). This creates an atom whose name is the characters "(" and ")". It is NOT the same as the atom NIL.

Contents | More Lists | Bag of Predicates