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.