I have a problem in understanding the performance of a Common Lisp function (I am still a novice). I have two versions of this function, which simply computes the sum of all integers up to a given n
.
Non-tail-recursive version:
(defun addup3 (n)
(if (= n 0)
0
(+ n (addup (- n 1)))))
Tail-recursive version:
(defun addup2 (n)
(labels ((f (acc k)
(if (= k 0)
acc
(f (+ acc k) (- k 1)))))
(f 0 n)))
I am trying to run these functions in CLISP with input n = 1000000
. Here is the result
[2]> (addup3 1000000)
500000500000
[3]> (addup2 1000000)
*** - Program stack overflow. RESET
I can run both successfully in SBCL, but the non-tail-recursive one is faster (only by a little, but that seems strange to me). I've scoured Stackoverflow questions for answers but couldn't find something similar. Why do I get a stack overflow although the tail-recursive function is designed NOT to put all recursive function calls on the stack? Do I have to tell the interpreter/compiler to optimise tail calls? (I read something like (proclaim '(optimize (debug 1))
to set the debug level and optimize at the cost of tracing abilities, but I don't know what this does).
Maybe the answer is obvious and the code is bullshit, but I just can't figure it out.
Help is appreciated.
Edit: danlei pointed out the typo, it should be a call to addup3
in the first function, so it is recursive. If corrected, both versions overflow, but not his one
(defun addup (n)
"Adds up the first N integers"
(do ((i 0 (+ i 1))
(sum 0 (+ sum i)))
((> i n) sum)))
While it may be a more typical way to do it, I find it strange that tail recursion is not always optimised, considering my instructors like to tell me it's so much more efficient and stuff.
addup
, which is essentially the function you described. If I correct the typo, it overflows as well. Still, I'm puzzled that thedo
construct is more capable than the recursive one. I don't seem to find anything regarding TCO for CLISP when googling and browsing the spec at clisp.org. Wouldn't it be strange if tail recursion is not more powerful than ordinary recursion? – Coupon