Putting the function definition together
We can put these expressions together to create a function definition that works. However, on examination, we find that one of the local variables is unneeded!
The function definition 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, we do not need number-of-pebbles-in-row.
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:
- A test that will return false after the loop has repeated itself the correct number of times.
- An expression the evaluation of which will return the value desired after being repeatedly evaluated.
- 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.