Previous: Inc Example parts, Up: Incrementing Loop Details [Contents][Index]
We have created the parts for the function definition; now we need to put them together.
First, the contents of the while
expression:
(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 nil
.
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 while
. Moreover, the
whole of the while
loop is a list within the body of the let
.
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 by
the defun
since the let
is not embedded within any containing
list, except for the defun
as a whole. However, if the 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 total
. This is returned by simply placing the
symbol as the last element of the list starting with 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 varlist and
while
expressions are the second and third elements of the list
starting with let
, and the total
is 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.
Previous: Inc Example parts, Up: Incrementing Loop Details [Contents][Index]