Emacs Lisp has two primary ways to cause an expression, or a series of
expressions, to be evaluated repeatedly: one uses a
loop, and the other uses recursion.
Repetition can be very valuable. For example, to move forward four sentences, you need only write a program that will move forward one sentence and then repeat the process four times. Since a computer does not get bored or tired, such repetitive action does not have the deleterious effects that excessive or the wrong kinds of repetition can have on humans.
while special form tests whether the value returned by
evaluating its first argument is true or false. This is similar to what
the Lisp interpreter does with an
if; what the interpreter does
next, however, is different.
while expression, if the value returned by evaluating the
first argument is false, the Lisp interpreter skips the rest of the
expression (the body of the expression) and does not evaluate it.
However, if the value is true, the Lisp interpreter evaluates the body
of the expression and then again tests whether the first argument to
while is true or false. If the value returned by evaluating the
first argument is again true, the Lisp interpreter again evaluates the
body of the expression.
The template for a
while expression looks like this:
(while true-or-false-test body...)
So long as the true-or-false-test of the
returns a true value when it is evaluated, the body is repeatedly
evaluated. This process is called a loop since the Lisp interpreter
repeats the same thing again and again, like an airplane doing a loop.
When the result of evaluating the true-or-false-test is false, the
Lisp interpreter does not evaluate the rest of the
expression and `exits the loop'.
Clearly, if the value returned by evaluating the first argument to
while is always true, the body following will be evaluated
again and again ... and again ... forever. Conversely, if the
value returned is never true, the expressions in the body will never
be evaluated. The craft of writing a
while loop consists of
choosing a mechanism such that the true-or-false-test returns true
just the number of times that you want the subsequent expressions to
be evaluated, and then have the test return false.
The value returned by evaluating a
while is the value of the
true-or-false-test. An interesting consequence of this is that a
while loop that evaluates without error will return
or false regardless of whether it has looped 1 or 100 times or none at
while expression that evaluates successfully never
returns a true value! What this means is that
while is always
evaluated for its side effects, which is to say, the consequences of
evaluating the expressions within the body of the
This makes sense. It is not the mere act of looping that is desired,
but the consequences of what happens when the expressions in the loop
are repeatedly evaluated.
whileLoop 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
(), 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 Lisp considers as true any value that is not
nil, a list that returns elements will test true in a
For example, you can set the variable
evaluating the following
(setq empty-list ())
After evaluating the
setq expression, you can evaluate the
empty-list in the usual way, by placing the cursor after
the symbol and typing C-x C-e;
nil will appear in your
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 '(giraffe gazelle 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 ...
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
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
can be set to be the CDR of the original list with the
(setq animals (cdr animals))
If you have evaluated the previous expressions and then evaluate this
expression, you will see
(gazelle 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
A template for a
while loop that uses the
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
print-elements-of-list function illustrates a
loop with a list.
The function requires several lines for its output. Since the echo
area is only one line, we cannot illustrate how it works in the same
way we have been illustrating functions in the past, by evaluating
them inside Info. Instead, you need to copy the necessary
expressions to your `*scratch*' buffer and evaluate them there.
You can copy the expressions by marking the beginning of the region
with C-SPC (
set-mark-command), moving the cursor to
the end of the region and then copying the region using M-w
copy-region-as-kill). In the `*scratch*' buffer, you can
yank the expressions back by typing C-y (
After you have copied the expressions to the `*scratch*' buffer,
evaluate each expression in turn. Be sure to evaluate the last
(print-elements-of-list animals), by typing
C-u C-x C-e, that is, by giving an argument to
eval-last-sexp. This will cause the result of the evaluation
to be printed in the `*scratch*' buffer instead of being printed
in the echo area. (Otherwise you will see something like this in your
^Jgiraffe^J^Jgazelle^J^Jlion^J^Jtiger^Jnil, in which
each `^J' stands for the newline that in the `*scratch*'
buffer puts each word on its own line. You can evaluate these
expressions right now in the Info buffer, if you like, to see this
(setq animals '(giraffe gazelle lion tiger)) (defun print-elements-of-list (list) "Print each element of LIST on a line of its own." (while list (print (car list)) (setq list (cdr list)))) (print-elements-of-list animals)
When you evaluate the three expressions in sequence in the `*scratch*' buffer, this will be printed in the buffer:
giraffe gazelle lion tiger nil
Each element of the list is printed on a line of its own (that is what
while loop, and since
while loops always return
nil is printed after the last element of the list.
A loop is not useful unless it stops when it ought. Besides controlling a loop with a list, a common way of stopping a loop is to write the first argument as a test that returns false when the correct number of repetitions are complete. This means that the loop must have a counter--an expression that counts how many times the loop repeats itself.
The test can be an expression such as
(< count desired-number)
t for true if the value of
count is less
desired-number of repetitions and
nil for false if
the value of
count is equal to or is greater than the
desired-number. The expression that increments the count can be
setq such as
(setq count (1+ count)), where
1+ is a built-in function in Emacs Lisp that adds 1 to its
argument. (The expression
(1+ count) has the same result as
(+ count 1), but is easier for a human to read.)
The template for a
while loop controlled by an incrementing
counter looks like this:
set-count-to-initial-value (while (< count desired-number) ; true-or-false-test body... (setq count (1+ count))) ; incrementer
Note that you need to set the initial value of
count; usually it
is set to 1.
Suppose you are playing on the beach and decide to make a triangle of pebbles, putting one pebble in the first row, two in the second row, three in the third row and so on, like this:
* * * * * * * * * *
(About 2500 years ago, Pythagoras and others developed the beginnings of number theory by considering questions such as this.)
Suppose you want to know how many pebbles you will need to make a triangle with 7 rows?
Clearly, what you need to do is add up the numbers from 1 to 7. There
are two ways to do this; start with the smallest number, one, and add up
the list in sequence, 1, 2, 3, 4 and so on; or start with the largest
number and add the list going down: 7, 6, 5, 4 and so on. Because both
mechanisms illustrate common ways of writing
while loops, we will
create two examples, one counting up and the other counting down. In
this first example, we will start with 1 and add 2, 3, 4 and so on.
If you are just adding up a short list of numbers, the easiest way to do it is to add up all the numbers at once. However, if you do not know ahead of time how many numbers your list will have, or if you want to be prepared for a very long list, then you need to design your addition so that what you do is repeat a simple process many times instead of doing a more complex process once.
For example, instead of adding up all the pebbles all at once, what you can do is add the number of pebbles in the first row, 1, to the number in the second row, 2, and then add the total of those two rows to the third row, 3. Then you can add the number in the fourth row, 4, to the total of the first three rows; and so on.
The critical characteristic of the process is that each repetitive action is simple. In this case, at each step we add only two numbers, the number of pebbles in the row and the total already found. This process of adding two numbers is repeated again and again until the last row has been added to the total of all the preceding rows. In a more complex loop the repetitive action might not be so simple, but it will be simpler than doing everything all at once.
The preceding analysis gives us the bones of our function definition:
first, we will need a variable that we can call
total that will
be the total number of pebbles. This will be the value returned by
Second, we know that the function will require an argument: this
argument will be the total number of rows in the triangle. It can be
Finally, we need a variable to use as a counter. We could call this
counter, but a better name is
That is because what the counter does is count rows, and a program
should be written to be as understandable as possible.
When the Lisp interpreter first starts evaluating the expressions in the
function, the value of
total should be set to zero, since we have
not added anything to it. Then the function should add the number of
pebbles in the first row to the total, and then add the number of
pebbles in the second to the total, and then add the number of
pebbles in the third row to the total, and so on, until there are no
more rows left to add.
row-number are used only inside the
function, so they can be declared as local variables with
and given initial values. Clearly, the initial value for
should be 0. The initial value of
row-number should be 1,
since we start with the first row. This means that the
statement will look like this:
(let ((total 0) (row-number 1)) body...)
After the internal variables are declared and bound to their initial
values, we can begin the
while loop. The expression that serves
as the test should return a value of
t for true so long as the
row-number is less than or equal to the
(If the expression tests true only so long as the row number is less
than the number of rows in the triangle, the last row will never be
added to the total; hence the row number has to be either less than or
equal to the number of rows.)
Lisp provides the
<= function that returns true if the value of
its first argument is less than or equal to the value of its second
argument and false otherwise. So the expression that the
will evaluate as its test should look like this:
(<= row-number number-of-rows)
The total number of pebbles can be found by repeatedly adding the number of pebbles in a row to the total already found. Since the number of pebbles in the row is equal to the row number, the total can be found by adding the row number to the total. (Clearly, in a more complex situation, the number of pebbles in the row might be related to the row number in a more complicated way; if this were the case, the row number would be replaced by the appropriate expression.)
(setq total (+ total row-number))
What this does is set the new value of
total to be equal to the
sum of adding the number of pebbles in the row to the previous total.
After setting the value of
total, the conditions need to be
established for the next repetition of the loop, if there is one. This
is done by incrementing the value of the
which serves as a counter. After the
row-number variable has
been incremented, the true-or-false-test at the beginning of the
while loop tests whether its value is still less than or equal to
the value of the
number-of-rows and if it is, adds the new value
row-number variable to the
total of the previous
repetition of the loop.
The built-in Emacs Lisp function
1+ adds 1 to a number, so the
row-number variable can be incremented with this expression:
(setq row-number (1+ row-number))
We have created the parts for the function definition; now we need to put them together.
First, the contents of the
(while (<= row-number number-of-rows) ; true-or-false-test (setq total (+ total row-number)) (setq row-number (1+ row-number))) ; incrementer
Along with the
let expression varlist, this very nearly
completes the body of the function definition. However, it requires
one final element, the need for which is somewhat subtle.
The final touch is to place the variable
total on a line by
itself after the
while expression. Otherwise, the value returned
by the whole function is the value of the last expression that is
evaluated in the body of the
let, and this is the value
returned by the
while, which is always
This may not be evident at first sight. It almost looks as if the
incrementing expression is the last expression of the whole function.
But that expression is part of the body of the
while; it is the
last element of the list that starts with the symbol
Moreover, the whole of the
while loop is a list within the body
In outline, the function will look like this:
(defun name-of-function (argument-list) "documentation..." (let (varlist) (while (true-or-false-test) body-of-while... ) ... ) ; Need final expression here.
The result of evaluating the
let is what is going to be returned
defun since the
let is not embedded within any
containing list, except for the
defun as a whole. However, if
while is the last element of the
let expression, the
function will always return
nil. This is not what we want!
Instead, what we want is the value of the variable
is returned by simply placing the symbol as the last element of the list
let. It gets evaluated after the preceding
elements of the list are evaluated, which means it gets evaluated after
it has been assigned the correct value for the total.
It may be easier to see this by printing the list starting with
let all on one line. This format makes it evident that the
while expressions are the second and third
elements of the list starting with
let, and the
the last element:
(let (varlist) (while (true-or-false-test) body-of-while... ) total)
Putting everything together, the
triangle function definition
looks like this:
(defun triangle (number-of-rows) ; Version with ; incrementing counter. "Add up the number of pebbles in a triangle. The first row has one pebble, the second row two pebbles, the third row three pebbles, and so on. The argument is NUMBER-OF-ROWS." (let ((total 0) (row-number 1)) (while (<= row-number number-of-rows) (setq total (+ total row-number)) (setq row-number (1+ row-number))) total))
After you have installed
triangle by evaluating the function, you
can try it out. Here are two examples:
(triangle 4) (triangle 7)
The sum of the first four numbers is 10 and the sum of the first seven numbers is 28.
Another common way to write a
while loop is to write the test
so that it determines whether a counter is greater than zero. So long
as the counter is greater than zero, the loop is repeated. But when
the counter is equal to or less than zero, the loop is stopped. For
this to work, the counter has to start out greater than zero and then
be made smaller and smaller by one of the forms that is evaluated
The test will be an expression such as
(> counter 0) which
t for true if the value of
counter is greater
than zero, and
nil for false if the value of
equal to or less than zero. The expression that makes the number
smaller and smaller can be a simple
setq such as
counter (1- counter)), where
1- is a built-in function in
Emacs Lisp that subtracts 1 from its argument.
The template for a decrementing
while loop looks like this:
(while (> counter 0) ; true-or-false-test body... (setq counter (1- counter))) ; decrementer
To illustrate a loop with a decrementing counter, we will rewrite the
triangle function so the counter decreases to zero.
This is the reverse of the earlier version of the function. In this case, to find out how many pebbles are needed to make a triangle with 3 rows, add the number of pebbles in the third row, 3, to the number in the preceding row, 2, and then add the total of those two rows to the row that precedes them, which is 1.
Likewise, to find the number of pebbles in a triangle with 7 rows, add the number of pebbles in the seventh row, 7, to the number in the preceding row, which is 6, and then add the total of those two rows to the row that precedes them, which is 5, and so on. As in the previous example, each addition only involves adding two numbers, the total of the rows already added up and the number of pebbles in the row that is being added to the total. This process of adding two numbers is repeated again and again until there are no more pebbles to add.
We know how many pebbles to start with: the number of pebbles in the last row is equal to the number of rows. If the triangle has seven rows, the number of pebbles in the last row is 7. Likewise, we know how many pebbles are in the preceding row: it is one less than the number in the row.
We start with three variables: the total number of rows in the
triangle; the number of pebbles in a row; and the total number of
pebbles, which is what we want to calculate. These variables can be
number-of-pebbles-in-row are used only
inside the function and are declared with
let. The initial
total should, of course, be zero. However, the
initial value of
number-of-pebbles-in-row should be equal to
the number of rows in the triangle, since the addition will start with
the longest row.
This means that the beginning of the
let expression will look
(let ((total 0) (number-of-pebbles-in-row number-of-rows)) body...)
The total number of pebbles can be found by repeatedly adding the number of pebbles in a row to the total already found, that is, by repeatedly evaluating the following expression:
(setq total (+ total number-of-pebbles-in-row))
number-of-pebbles-in-row is added to the
number-of-pebbles-in-row should be decremented by one, since
the next time the loop repeats, the preceding row will be
added to the total.
The number of pebbles in a preceding row is one less than the number of
pebbles in a row, so the built-in Emacs Lisp function
1- can be
used to compute the number of pebbles in the preceding row. This can be
done with the following expression:
(setq number-of-pebbles-in-row (1- number-of-pebbles-in-row))
Finally, we know that the
while loop should stop making repeated
additions when there are no pebbles in a row. So the test for
while loop is simply:
(while (> number-of-pebbles-in-row 0)
Putting these expressions together, we have a function definition that looks like this:
;;; First subtractive version. (defun triangle (number-of-rows) "Add up the number of pebbles in a triangle." (let ((total 0) (number-of-pebbles-in-row number-of-rows)) (while (> number-of-pebbles-in-row 0) (setq total (+ total number-of-pebbles-in-row)) (setq number-of-pebbles-in-row (1- number-of-pebbles-in-row))) total))
As written, this function works.
However, it turns out that one of the local variables,
number-of-pebbles-in-row, is unneeded!
triangle function is evaluated, the symbol
number-of-rows will be bound to a number, giving it an initial
value. That number can be changed in the body of the function as if
it were a local variable, without any fear that such a change will
effect the value of the variable outside of the function. This is a
very useful characteristic of Lisp; it means that the variable
number-of-rows can be used anywhere in the function where
number-of-pebbles-in-row is used.
Here is a second version of the function written a bit more cleanly:
(defun triangle (number) ; Second version. "Return sum of numbers 1 through NUMBER inclusive." (let ((total 0)) (while (> number 0) (setq total (+ total number)) (setq number (1- number))) total))
In brief, a properly written
while loop will consist of three parts:
A recursive function contains code that tells itself to evaluate itself. When the function evaluates itself, it again finds the code that tells itself to evaluate itself, so the function evaluates itself again ... and again ... A recursive function will keep telling itself to evaluate itself again forever unless it is also provided with a stop condition.
A recursive function typically contains a conditional expression which has three parts:
Recursive functions can be much simpler than any other kind of function. Indeed, when people first start to use them, they often look so mysteriously simple as to be incomprehensible. Like riding a bicycle, reading a recursive function definition takes a certain knack which is hard at first but then seems simple.
A template for a recursive function looks like this:
(defun name-of-recursive-function (argument-list) "documentation..." body... (if do-again-test (name-of-recursive-function next-step-expression)))
Each time the recursive function is evaluated, an argument is bound to the value of the next-step-expression; and that value is used in the do-again-test. The next-step-expression is designed so that the do-again-test returns false when the function should no longer be repeated.
The do-again-test is sometimes called the stop condition, since it stops the repetitions when it tests false.
The example of a
while loop that printed the elements of a list
of numbers can be written recursively. Here is the code, including
an expression to set the value of the variable
animals to a list.
This example must be copied to the `*scratch*' buffer and each
expression must be evaluated there. Use C-u C-x C-e to evaluate
(print-elements-recursively animals) expression so that the
results are printed in the buffer; otherwise the Lisp interpreter will
try to squeeze the results into the one line of the echo area.
Also, place your cursor immediately after the last closing parenthesis
print-elements-recursively function, before the comment.
Otherwise, the Lisp interpreter will try to evaluate the comment.
(setq animals '(giraffe gazelle lion tiger)) (defun print-elements-recursively (list) "Print each element of LIST on a line of its own. Uses recursion." (print (car list)) ; body (if list ; do-again-test (print-elements-recursively ; recursive call (cdr list)))) ; next-step-expression (print-elements-recursively animals)
print-elements-recursively function first prints the first
element of the list, the CAR of the list. Then, if the list is
not empty, the function invokes itself, but gives itself as its
argument, not the whole list, but the second and subsequent elements
of the list, the CDR of the list.
When this evaluation occurs, the function prints the first element of
the list it receives as its argument (which is the second element
of the original list). Then, the
if expression is evaluated
and when true, the function calls itself with the CDR of the list
it is invoked with, which (the second time around) is the CDR of
the CDR of the original list.
Each time the function invokes itself, it invokes itself on a shorter
version of the original list. Eventually, the function invokes itself
on an empty list. The
nil. Next, the conditional expression tests the value of
list. Since the value of
if expression tests false so the then-part is not evaluated.
The function as a whole then returns
nil. Consequently, you
nil twice when you evaluate the function.
When you evaluate
(print-elements-recursively animals) in the
`*scratch*' buffer, you see this result:
giraffe gazelle lion tiger nil nil
nil is the value of the empty list that is printed;
nil is the value returned by the whole function.)
triangle function described in a previous section can also
be written recursively. It looks like this:
(defun triangle-recursively (number) "Return the sum of the numbers 1 through NUMBER inclusive. Uses recursion." (if (= number 1) ; do-again-test 1 ; then-part (+ number ; else-part (triangle-recursively ; recursive call (1- number))))) ; next-step-expression (triangle-recursively 7)
You can install this function by evaluating it and then try it by
(triangle-recursively 7). (Remember to put your
cursor immediately after the last parenthesis of the function
definition, before the comment.)
To understand how this function works, let's consider what happens in the various cases when the function is passed 1, 2, 3, or 4 as the value of its argument.
First, what happens if the value of the argument is 1?
The function has an
if expression after the documentation
string. It tests whether the value of
number is equal to 1; if
so, Emacs evaluates the then-part of the
if expression, which
returns the number 1 as the value of the function. (A triangle with
one row has one pebble in it.)
Suppose, however, that the value of the argument is 2. In this case,
Emacs evaluates the else-part of the
The else-part consists of an addition, the recursive call to
triangle-recursively and a decrementing action; and it looks like
(+ number (triangle-recursively (1- number)))
When Emacs evaluates this expression, the innermost expression is evaluated first; then the other parts in sequence. Here are the steps in detail:
(1- number)so Emacs decrements the value of
numberfrom 2 to 1.
triangle-recursivelyfunction In this case, Emacs evaluates
triangle-recursivelywith an argument of 1. This means that this evaluation of
numberis the second element of the list that starts with
+; its value is 2.
+expression receives two arguments, the first from the evaluation of
number(Step 3) and the second from the evaluation of
triangle-recursively(Step 2). The result of the addition is the sum of 2 plus 1, and the number 3 is returned, which is correct. A triangle with two rows has three pebbles in it.
triangle-recursively is called with an argument of
ifexpression is evaluated first. This is the do-again test and returns false, so the else-part of the
ifexpression is evaluated. (Note that in this example, the do-again-test causes the function to call itself when it tests false, not when it tests true.)
triangle-recursivelyfunction. We know what happens when Emacs evaluates
triangle-recursivelywith an argument of 2. After going through the sequence of actions described earlier, it returns a value of 3. So that is what will happen here.
The value returned by the function as a whole will be 6.
Now that we know what will happen when
called with an argument of 3, it is evident what will happen if it is
called with an argument of 4:
In the recursive call, the evaluation of(triangle-recursively (1- 4))
will return the value of evaluating(triangle-recursively 3)
which is 6 and this value will be added to 4 by the addition in the third line.
The value returned by the function as a whole will be 10.
triangle-recursively is evaluated, it evaluates a
version of itself with a smaller argument, until the argument is small
enough so that it does not evaluate itself.
The version of
triangle-recursively described earlier is written
if special form. It can also be written using another
special form called
cond. The name of the special form
cond is an abbreviation of the word `conditional'.
cond special form is not used as often in the
Emacs Lisp sources as
if, it is used often enough to justify
The template for a
cond expression looks like this:
where the body is a series of lists.
Written out more fully, the template looks like this:
(cond ((first-true-or-false-test first-consequent) (second-true-or-false-test second-consequent) (third-true-or-false-test third-consequent) ...)
When the Lisp interpreter evaluates the
cond expression, it
evaluates the first element (the CAR or true-or-false-test) of
the first expression in a series of expressions within the body of the
If the true-or-false-test returns
nil the rest of that
expression, the consequent, is skipped and the true-or-false-test of the
next expression is evaluated. When an expression is found whose
true-or-false-test returns a value that is not
consequent of that expression is evaluated. The consequent can be one
or more expressions. If the consequent consists of more than one
expression, the expressions are evaluated in sequence and the value of
the last one is returned. If the expression does not have a consequent,
the value of the true-or-false-test is returned.
If none of the true-or-false-tests test true, the
triangle function looks like this:
(defun triangle-using-cond (number) (cond ((<= number 0) 0) ((= number 1) 1) ((> number 1) (+ number (triangle-using-cond (1- number))))))
In this example, the
cond returns 0 if the number is less than or
equal to 0, it returns 1 if the number is 1 and it evaluates
number (triangle-using-cond (1- number))) if the number is greater than
trianglein which each row has a value which is the square of the row number. Use a
trianglethat multiplies instead of adds the values.
Go to the first, previous, next, last section, table of contents.