Hacker News new | past | comments | ask | show | jobs | submit login
Tail recursion in Python (paulbutler.org)
30 points by benhoyt on March 28, 2009 | hide | past | favorite | 5 comments



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/


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.


Good point. To be fair, however, he's probably just being intellectually curious -- that is, "hacking". There's no way you'd test a number for evenness in real life by either recursion or iteration. You'd always do either (n&1)==0 or n%2==0.


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.


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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: