*n*is the product of all the integers between 1 and

*n*inclusive. Outside of mathematics, it is a common example to explain recursion. Of course, the code here only works for non-negative integers.

Here's an iterative implementation:

(

*defun*fact (n) (check-type n unsigned-byte) (*loop*for i from 0 to n for fact = 1 then (* fact i) finally (return fact)))CPS:

(

*defun*fact (x) (*labels*((fact-aux (n k) (*cond*((zerop n) (funcall k 1)) (t (fact-aux (1- n) (*lambda*(m) (funcall k (* m n)))))))) (check-type x (integer 0 *)) (fact-aux x #'identity)))There's less wrong with the above than there used to be. It is now the case that these functions simply behave in odd ways when given negative or non-integers; and of course the recursive (first) definition can still overflow the stack.

I still prefer my take, of course...:

(

-- *defun*fact (n) ;; in a _(declarations-are-assertions) compiler like _(CMUCL) or _(SBCL), ;; I might write (_H(DECLARE) (TYPE UNSIGNED-BYTE N)) here. (_H(check-type) n _H(unsigned-byte)) (*let*((result 1)) (declare (type unsigned-byte result)) (do ((i n (1- i))) ((= i 0) result) (setf result (* result i)))))*Christophe*

Are the HyperSpec references intentional here? -- Roland Kaufmann

Well, I put them in because people might be interested in the difference between CHECK-TYPE and DECLARE, and might want to look them up. -- (Christophe)

;; A tail-recursive version, w/o an auxiliary function, inspired by Winston's fibonacci function in Lisp, 3rd edition
(

*defun*fact (n &optional (so-far 1)) (*if*(<= n 1) so-far (fact (- n 1) (* n so-far))))--*Above function overflows stack on Lispworks.*
--*I also use Lispworks (LWM 4.4.5). I don't have any issues with this function, once compiled, for values up to 10000. It seems to hog the machine for (fact 100000), no doubt understandably. Olivier *
--*If the result is not diaplayed, (fact 10000) takes 0.5 sec. and (fact 100000) takes 69 sec. on 1.8 MHz G5*

;; Factorial using anonymous recursive function
(funcall ((

*lambda*(f) #'(*lambda*(n) (funcall f f n))) #'(*lambda*(f n) (*if*(= n 0) 1 (* n (funcall f f (- n 1)))))) x)Here's another iterative implementation: