A `while' Loop and a List
-------------------------
A common way to control a `while' loop is to test whether a list has
any elements. If it does, the loop is repeated; but if it does not,
the repetition is ended. Since this is an important technique, we will
create a short example to illustrate it.
A simple way to test whether a list has elements is to evaluate the
list: if it has no elements, it is an empty list and will return the
empty list, `()', which is a synonym for `nil' or false. On the other
hand, a list with elements will return those elements when it is
evaluated. Since Emacs Lisp considers as true any value that is not
`nil', a list that returns elements will test true in a `while' loop.
For example, you can set the variable `empty-list' to `nil' by
evaluating the following `setq' expression:
(setq empty-list ())
After evaluating the `setq' expression, you can evaluate the variable
`empty-list' in the usual way, by placing the cursor after the symbol
and typing `C-x C-e'; `nil' will appear in your echo area:
empty-list
On the other hand, if you set a variable to be a list with elements,
the list will appear when you evaluate the variable, as you can see by
evaluating the following two expressions:
(setq animals '(gazelle giraffe lion tiger))
animals
Thus, to create a `while' loop that tests whether there are any
items in the list `animals', the first part of the loop will be written
like this:
(while animals
...
When the `while' tests its first argument, the variable `animals' is
evaluated. It returns a list. So long as the list has elements, the
`while' considers the results of the test to be true; but when the list
is empty, it considers the results of the test to be false.
To prevent the `while' loop from running forever, some mechanism
needs to be provided to empty the list eventually. An oft-used
technique is to have one of the subsequent forms in the `while'
expression set the value of the list to be the CDR of the list. Each
time the `cdr' function is evaluated, the list will be made shorter,
until eventually only the empty list will be left. At this point, the
test of the `while' loop will return false, and the arguments to the
`while' will no longer be evaluated.
For example, the list of animals bound to the variable `animals' can
be set to be the CDR of the original list with the following expression:
(setq animals (cdr animals))
If you have evaluated the previous expressions and then evaluate this
expression, you will see `(giraffe lion tiger)' appear in the echo
area. If you evaluate the expression again, `(lion tiger)' will appear
in the echo area. If you evaluate it again and yet again, `(tiger)'
appears and then the empty list, shown by `nil'.
A template for a `while' loop that uses the `cdr' function
repeatedly to cause the true-or-false-test eventually to test false
looks like this:
(while TEST-WHETHER-LIST-IS-EMPTY
BODY...
SET-LIST-TO-CDR-OF-LIST)
This test and use of `cdr' can be put together in a function that
goes through a list and prints each element of the list on a line of its
own.