eintr: Loop Example

 
 11.1.1 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.