
Tail recursion in Python - benhoyt
http://www.paulbutler.org/archives/tail-recursion-in-python/
======
amix
If you code in Python, then code like a Pythonist would code. Don't code like
you would code in Scheme or like you would code in Java. Why? It produces some
pretty hard to read code - there's nothing worse than reading some Python code
that is written like Java or some other language X. And some languages are
optimized for certain things and function calls in Python are pretty
expensive...

A little tip: tail_rec is a decorator and it would have been nice if the
decorator syntax was used: <http://www.python.org/dev/peps/pep-0318/>

~~~
paulgb
I agree that coding in the style of the language is important, and I can
assure you that my python code has gotten a fair bit more pythonic since
writing this :).

Still, there are times when things like this could be useful. Even though I
code in python more than anything these days, I still find it useful to "think
in scheme" sometimes, and having access to unlimited tail recursion helps. A
fair bit of my code is experimental or write-once run-once, so as long as I
can understand it performance and readability is not a huge issue.

> A little tip: tail_rec is a decorator [...]

Unfortunately, it's not that easy. The tail-recursive function itself needs to
be able to reference itself (unmodified by a decorator) when it creates the
lambda. There is a way around this (by having the function take a copy of
itself as an argument, as in the y-combinator), but that has a negative net
effect on readability.

------
silentbicycle
Lua has tail call optimization (and is otherwise very similar to Python).

    
    
      function even(x)
         if x == 0 then
            return true
         else
            return odd(x - 1)
         end
      end
      
      function odd(x)
         if x == 0 then
            return false
         else
            return even(x - 1)
         end
      end
    
    
      -- (at the repl)
      > print(even(10e6 + 1))
      false
    

Testing that way is slow, of course, but if you wanted speed you'd use
something more like

    
    
      function even(x) return x % 2 == 0 end
    

(and Lua is typically faster than Python, anyway.)

There's also Stackless Python, though I haven't personally done much with it.

------
smanek
Heh, funny. I just spent a few hours doing basically the same thing with Java.
Right now it works with either functors or dynamic proxies, and I think I
might be able to do it with annotation processing (roughly the same as
decorators).

I'll see if I can get permission from work to share the code - it would make a
good blog entry.

