The primary difference is that in the first the fib-iter function is
only defined within the fib-2 function (lexically scoped), but in the
second it becomes a top level function that can be used anywhere in the
program, The equivalent of:
(defun fib-iter (a b c)
(if (zerop c)
b
(fib-iter (+ a b) a (1- c))))
(defun fib-2 (n)
(fib-iter 1 0 n))
If you wish to limit the scope of internal functions so they don't
exist in the global name-space, then the labels construct is preferred.
This may not be as significant if you are working within a package
and not exporting the fib-iter function. In general, when such helper
functions are use, they are given less generic names to indicate this
status.
The other approach is to put the internal state into optional arguments:
(defun fib-3 (n &optional (a 1) (b 0))
(if (zerop n)
b
(fib-3 (1- n) (+ a b) a)))
Which has the adverse effect of not being as clear about the number of
arguments the fib function should be given.
Recursive functions in Common Lisp may or may not be a problem,
depending on the number of recursions involved and whether the
implementation used does tail call optimization (TCO), which is not required.
The non-recursive approach would be something like:
(defun fib-4 (n)
(loop
for a = 1 then (+ a b)
and b = 0 then a
repeat n
finally (return b)))
--
Barry Fishman