Kay Schluehr wrote: > > Diez B. Roggisch wrote: >> Kay Schluehr wrote: >> >> > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691 >> >> Neat. >> >> Diez > > Hi Diez, > > for all those who already copied and pasted the original solution and > played with it I apologize for radical changes in the latest version ( > the recipe is on version 1.5 now ! ). The latest implementation is > again a lot faster than the previous one. It does not only get rid of > exceptions but also of stack-frame inspection. > > Regards, > Kay > I'm not convinced by this. You have to recognise that the function is using tail recursion, and then you have to modify the code to know that it is using tail recursion. This is not always trivial. For example, the given example is:
@tail_recursion def factorial(n, acc=1): "calculate a factorial" if n == 0: return acc res = factorial(n-1, n*acc) return res but a more common way to write the function would be: @tail_recursion def factorial(n): "calculate a factorial" if n == 0: return 1 return n * factorial(n-1) which won't work because it isn't actually tail recursion, but it looks sufficiently close to tail recursion that it would probably mislead a lot of people into expecting it will work. If you are going to have to rewrite functions in a stilted manner, and they use simple tail recursion, then why not just factor out the tail recursion in the first place. My other problem with this is that the decorator is very fragile although this may be fixable. e.g. (using the published example) an exception thrown inside the function makes future calls return garbage: >>> factorial(3) 6 >>> factorial('a') Traceback (most recent call last): File "<pyshell#5>", line 1, in -toplevel- factorial('a') File "<pyshell#1>", line 12, in result tc = g(*args,**kwd) File "<pyshell#3>", line 6, in factorial res = factorial(n-1, n*acc) TypeError: unsupported operand type(s) for -: 'str' and 'int' >>> factorial(3) ('continue', (3,), {}) -- http://mail.python.org/mailman/listinfo/python-list