Monday, March 30, 2009

nested defun caveat

I just got to know that nested defun is not really the solution for local functions in lisp. Let me clarify it with an example, if I am to write a tail recursive definition of factorial in lisp, this is how I thought it will be done...
(defun factorial (n)
(defun fact-iter (n result)
(if (= n 0) result
(fact-iter (- n 1) (* result n))))
(fact-iter n 1))

I used nested defun so that I could hide the detail about fact-iter, but in Lisp it seems no matter where defun is executed it'll put that binding in global environment i.e. fact-iter will be put in global environment once we execute factorial which I wanted to hide.
Instead labels are used for local function in lisp and here is the "correct" version of above program.
(defun factorial (n)
(labels ((fact-iter (n result)
(if (= n 0) result
(fact-iter (- n 1) (* result n)))))
(fact-iter n 1)))

No comments:

Post a Comment