Go to the previous, next section.

Putting the function definition together

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!

When the  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:

  1. A test that will return false after the loop has repeated itself the correct number of times.

  2. An expression the evaluation of which will return the value desired after being repeatedly evaluated.

  3. An expression to change the value passed to the true-or-false-test so that the test returns false after the loop has repeated itself the right number of times.

Go to the previous, next section.