473,386 Members | 1,752 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

tail-rec decorator, well still blows the stack...

http://aspn.activestate.com/ASPN/Coo.../Recipe/496691

so I try it and when I run:
@Decorators.tail_recursion
def fibtr(n):
def fibt(a, b, n):
if n <= 1:
return b
else:
return fibt(b, a + b, n - 1)
if n == 0:
return 0
else:
return fibt(0, 1, n);

it still blows the stack. so what is the point? is it impossible to
get "real" tail-recursion in Python?
Jul 22 '08 #1
4 1435
I my function not proper tail-recursion?
because this doesn't blow the stack:
#!/usr/bin/env python2.4
# This program shows off a python decorator(
# which implements tail call optimization. It
# does this by throwing an exception if it is
# it's own grandparent, and catching such
# exceptions to recall the stack.

import sys

class TailRecurseException:
def __init__(self, args, kwargs):
self.args = args
self.kwargs = kwargs

def tail_call_optimized(g):
"""
This function decorates a function with tail call
optimization. It does this by throwing an exception
if it is it's own grandparent, and catching such
exceptions to fake the tail call optimization.

This function fails if the decorated
function recurses in a non-tail context.
"""
def func(*args, **kwargs):
f = sys._getframe()
if f.f_back and f.f_back.f_back \
and f.f_back.f_back.f_code == f.f_code:
raise TailRecurseException(args, kwargs)
else:
while 1:
try:
return g(*args, **kwargs)
except TailRecurseException, e:
args = e.args
kwargs = e.kwargs
func.__doc__ = g.__doc__
return func

@tail_call_optimized
def factorial(n, acc=1):
"calculate a factorial"
if n == 0:
return acc
return factorial(n-1, n*acc)

print factorial(10000)
# prints a big, big number,
# but doesn't hit the recursion limit.

@tail_call_optimized
def fib(i, current = 0, next = 1):
if i == 0:
return current
else:
return fib(i - 1, next, current + next)

print fib(10000)
# also prints a big number,
# but doesn't hit the recursion limit.
Jul 22 '08 #2
On Mon, Jul 21, 2008 at 10:01 PM, ssecorp <ci**********@gmail.comwrote:
http://aspn.activestate.com/ASPN/Coo.../Recipe/496691

so I try it and when I run:
@Decorators.tail_recursion
def fibtr(n):
def fibt(a, b, n):
if n <= 1:
return b
else:
return fibt(b, a + b, n - 1)
if n == 0:
return 0
else:
return fibt(0, 1, n);

it still blows the stack. so what is the point? is it impossible to
get "real" tail-recursion in Python?
Python does not perform tail-call elimination, and there are currently
no plans to make it do so. See
http://mail.python.org/pipermail/pyt...ly/046171.html and
the ensuing discussion for an explanation.
Jul 22 '08 #3


ssecorp wrote:
http://aspn.activestate.com/ASPN/Coo.../Recipe/496691

so I try it and when I run:
@Decorators.tail_recursion
def fibtr(n):
def fibt(a, b, n):
if n <= 1:
return b
else:
return fibt(b, a + b, n - 1)
if n == 0:
return 0
else:
return fibt(0, 1, n);

it still blows the stack. so what is the point? is it impossible to
get "real" tail-recursion in Python?
As you have used it, the decorator wraps the *outer* non-recursive
function which is just called once anyway. Useless. Try wrapping fibt
instead.

That said, this recipe significantly increases the running time by
multiplying the number of function calls by about three. I do not
regard it as removing the recursion, but, rather, as making it indirect
(via two other calls) so as to remove the unneeded stack frames (and the
space problem) in between recursive calls. Much simpler is the trivial
rewrite with while to do 'in frame recursion', or iteration. This also
removes the need for outer and inner function.

rearrange fibt as

def fibt(a,b,n):
if n 1:
return fibt(b, a+b, n-1)
else:
return b

and rewrite as

def fibi(a,b,n):
while n 1:
a,b,n = b,a+b,n-1
return b

by directly binding the new arguments to the parameters.
Move the initialization inside the function (and delete the outer
wrapper) to get

def fib(n):
if n==0:
return 0
else:
a,b = 0,1
while n 1:
a,b,n = b,a+b,n-1
return b

and even turn the induction back a step and simplify to

def fib(n):
a,b = 1,0
while n:
a,b,n = b,a+b,n-1
return b

Why do some people fight writing efficient beautiful code like this that
works with Python's design to instead write less efficient and uglier
code that works against Python's design?

If you do not want function calls (and runtime name resolution), do not
write them!

Terry Jan Reedy

Jul 22 '08 #4
thanks i already have perfect iterative versions of fibonacci.
def fib(n):
a, b = 1, 0
while n:
a, b, n = b, a+b, n-1
return b
I know the example is not the way to write pythonic code, I was just
learning about decorators and then I saw this example and tried it
out.

but thanks now i understand why it didn't work.
Jul 22 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Count Dracula | last post by:
Is there a way to write a c++ program that will print out the last few lines of a file without reading the whole file? The implementations of 'tail' I have seen all appear to be system dependent....
10
by: Mel | last post by:
i need to create a unix like "tail" function on my site. the question: the text is displayed in a scrolled area and a new line is added at the end and the entire text is scrolled down so that...
3
by: Michael B Allen | last post by:
Consider the following structures: struct bar { int i; float f; unsigned char tail; }; struct foo { struct bar b1; unsigned char _b1tail;
4
by: Sumika | last post by:
Hello, I'm a newbie here, so don't know much friends. I've problem deleting my node at the tail, so could you all help me to solve my error,I worked on it for quite sometime but it just can't...
12
by: s99999999s2003 | last post by:
hi I have a file which is very large eg over 200Mb , and i am going to use python to code a "tail" command to get the last few lines of the file. What is a good algorithm for this type of task...
8
by: Camellia | last post by:
Hi there this is an easy game which was inspired from my psychology class. I'll get 5/10 right prediction of your guess of head and tail at most time. If you could copy the code and run it that...
30
by: Chas Emerick | last post by:
I looked around for an ElementTree-specific mailing list, but found none -- my apologies if this is too broad a forum for this question. I've been using the lxml variant of the ElementTree API,...
6
by: lak | last post by:
i want to write a program that implement tail and tail -f command in unix. can any one help me in this?
3
by: sab | last post by:
Hello, I have been working on a python script to parse a continuously growing log file on a UNIX server. The input is the standard in, piped in from the log file. The application works well...
35
by: Muzammil | last post by:
int harmonic(int n) { if (n=1) { return 1; } else { return harmonic(n-1)+1/n; } } can any help me ??
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.