Earlier quoted context omitted.
It won't help unless you call it in a specific order e.g., fib(10_000) may produce RecursionError unless you run for n in range(10_000): fib(n)
Right, it's a memoiser. You side-step some recursion through previously stored results. It works well for some class of algorithms, which coincides with quite a large subsection of problems where TCO would help formulate algorithms. There are still a bunch of limits, because you're caching results, not eliminating call frames. The first obvious drawback is performance and memory use: All results get stored in a dicti…
Tail recursion in Python
41–50 of 87 posts
Re: Tail recursion in Python
#42I do think it's a shame that Python doesn't have general TCO. It's said to be unpythonic because it means there will be two ways to do things. But some things are so easily expressed as a recursion but require considerable thought to be turned into a loop.
Re: Tail recursion in Python
#43Code snippets you won't see if you have JS disabled: https://gist.github.com/ChrisPenner/c0b3f4feb054daa2f6370d2e... https://gist.github.com/ChrisPenner/c958afbf6e7a763c188d8b83...
JS fully disabled in this day and age?
Re: Tail recursion in Python
#441. https://tomforb.es/adding-tail-call-optimization-to-python/
2. https://gist.github.com/orf/41746c53b8eda5b988c5#file-tail_c...
Re: Tail recursion in Python
#45A patch that implements TCO in Python with explicit syntax like 'return from f(x)' could likely get accepted, ending these hacks
Edit: I didn't see shakna's comment.
[0] http://neopythonic.blogspot.de/2009/04/tail-recursion-elimin...
Re: Tail recursion in Python
#46Code snippets you won't see if you have JS disabled: https://gist.github.com/ChrisPenner/c0b3f4feb054daa2f6370d2e... https://gist.github.com/ChrisPenner/c958afbf6e7a763c188d8b83...
JS fully disabled in this day and age?
This was one of the best quality of life decision in terms of web browsing I have ever made.
The vast majority of pages that I randomly access (e.g. from hacker news) are text based and usually work just fine without js. But the time until I can start reading is much faster (less jumping around of content) and I don't get the growth hackers modals shoven down my throat two paragraphs in. The pages I use regularly are usually white listed
Re: Tail recursion in Python
#47The hackyness/speed issues aside: When compiling/transpiling/whatever between languages, I have found that relying on regular procedure calls and TCO is generally a lot simpler than having to force the looping facility of one language into the semantics of another language. The only one I can actually imagine porting other loops to is the common lisp loop macro, but that is probably the most flexible looping facility…
With regards to stacks that can use all of the memory: Gambit and AFAIK Chicken behave that way, too. This is one of the reasons I chose Scheme over OCaml (and Haskell) over a decade ago when looking for a new language to move to.
Gambit seems to also not grow the stack dynamically, but I could be wrong.
Re: Tail recursion in Python
#48This is the same as recur in Clojure. It's not general TCO, though, which is much more powerful. I do think it's a shame that Python doesn't have general TCO. It's said to be unpythonic because it means there will be two ways to do things. But some things are so easily expressed as a recursion but require considerable thought to be turned into a loop.
Do you have some examples of problem+solutions where tco works fine (in a language with tco) - but the manual translation is hard(ish)?
I wonder in part after reading the Julia thread on tco - and difficulties with providing guarantees in the general case with tco:
Re: Tail recursion in Python
#49> if n == 0: return 1
> else: return tail_factorial(n-1, accumulator * n)
Does this ever return the accumulator?
[ed: ah, no. I see the first comment on the article is about this bug; it should return accumulator, not 1]
Re: Tail recursion in Python
#50Earlier quoted context omitted.
This only works in specific cases (namely those where dynamic programming algorithms suffice), and does not avoid the recursion limit in general.
Don't dismiss one of my favorite higher order functions so soon :) "Recursion + memoization provides most of the benefits of dynamic programming, including usually the same running time." -- Steven Skiena lru_cache decorator is great for people who are happy to let the language handle the caching of results for them, and often leads to code which is much more concise than the dynamic programming approach. The limitat…
This isn't dismissive. lru_cache is one of my favorites too, but it has limitations.