<div dir="ltr">You can just use a memoize decorator to automatically convert your recursive solution to a fast linear time one.  Search for "python memoization decorator".<div><br></div><div>Best,</div><div><br></div><div>Neil<br><br>On Sunday, May 26, 2013 8:00:13 AM UTC-4, Ram Rachum wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi everybody,<div><br></div><div>Here's an idea I had a while ago. Now, I'm an ignoramus when it comes to how programming languages are implemented, so this idea will most likely be either (a) completely impossible or (b) trivial knowledge.</div><div><br></div><div><span style="font-size:13px">I was thinking about the implementation of the factorial in Python. I was comparing in my mind 2 different solutions: The recursive one, and the one that uses a loop. Here are example implementations for them:</span><br></div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>def factorial_recursive(n):</div><div>    if n == 1:</div><div>        return 1</div><div>    return n * factorial_recursive(n - 1)</div><div><br></div><div>def factorial_loop(n):</div><div>    result = 1</div><div>    for i in range(1, n + 1):</div><div>        result *= i</div><div>    return result</div></blockquote><div><br></div><div>I know that the <span style="font-size:13px">recursive</span><span style="font-size:13px"> </span><span style="font-size:13px">one is problematic, because it's putting a lot of items on the stack. In fact it's using the stack as if it was a loop variable. The stack wasn't meant to be used like that.</span></div><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">Then the question came to me, why? Maybe the stack could be built to handle this kind of (ab)use?</span></div><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">I read about tail-call optimization on Wikipedia. If I understand correctly, the gist of it is that the interpreter tries to recognize, on a frame-by-frame basis, which frames could be completely eliminated, and then it eliminates those. Then I read Guido's blog post explaining why he doesn't want it in Python. In that post he outlined 4 different reasons why TCO shouldn't be implemented in Python.</span></div><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">But then I thought, maybe you could do something smarter than eliminating individual stack frames. Maybe we could create something that is to the current implementation of the stack what `xrange` is to the old-style `range`. A smart object that allows access to any of a long list of items in it, without actually having to store those items. </span><span style="font-size:13px">This would solve the first argument that Guido raises in his post, which I found to be the most substantial one.</span></div><div><span style="font-size:13px"><br></span></div><div><font size="2">What I'm saying is: Imagine the stack of the interpreter when it runs the factorial example above for n=1000. It has around 1000 items in it and it's just about to explode. But then, if you'd look at the contents of that stack, you'd see it's </font>embarrassingly<font size="2"> regular, a compression algorithm's wet dream. It's just the same code location over and over again, with a different value for `n`.</font></div><div><font size="2"><br></font></div><div><font size="2">So what I'm suggesting is an algorithm to compress that stack on the fly. An algorithm that would detect regularities in the stack and instead of saving each individual frame, save just the pattern. Then, there wouldn't be any problem with showing informative stack trace: Despite not storing every individual frame, each individual frame could still be <i>accessed</i>, similarly to how `xrange` allow access to each individual member without having to store each of them.</font></div><div><font size="2"><br></font></div><div><font size="2">Then, the stack could store a lot more items, and tasks that currently require recursion (like pickling using the standard library) will be able to handle much deeper recursions.</font></div><div><font size="2"><br></font></div><div><font size="2">What do you think?</font></div><div><font size="2"><br></font></div><div><font size="2"><br></font></div><div><font size="2">Ram.</font></div></blockquote></div></div>