recursive decorator

Ethan Furman ethan at stoneleaf.us
Fri Sep 4 13:03:17 EDT 2009


Michele Simionato wrote:
> On Sep 3, 6:41 pm, Ethan Furman <et... at stoneleaf.us> wrote:
> 
>>The original thread by Bearophile:
>>   http://mail.python.org/pipermail/python-list/2009-May/711848.html
> 
> 
> I have read the thread. What Bearophile wants can be implemented with
> a bytecode hack, no
> need for the decorator module. Let me call 'recur' the self-function,
> like in Clojure.
> You can define a decorator that makes "self-conscious" a recursive
> function as follows:
> 
> # requires byteplay by Noam Raphael
> # see http://byteplay.googlecode.com/svn/trunk/byteplay.py
> from byteplay import Code, LOAD_GLOBAL, STORE_FAST, LOAD_FAST
> 
> def enable_recur(f):
>     print f.func_code.co_names
>     if 'recur' not in f.func_code.co_names:
>         return f # do nothing on non-recursive functions
>     c = Code.from_code(f.func_code)
>     c.code[1:1] = [(LOAD_GLOBAL, f.__name__), (STORE_FAST, 'recur')]
>     for i, (opcode, value) in enumerate(c.code[2:]):
>         if opcode == LOAD_GLOBAL and value == 'recur':
>             c.code[i+2] = (LOAD_FAST, 'recur')
>     f.func_code = c.to_code()
>     return f
> 
> ## example of use
> 
> @enable_recur
> def f(x):
>     if x == 1:
>         return 1
>     else:
>         return x*recur(x-1)
> 
> print f(4) # =>24
> 
> 
> Please accept this without explanation since it would take me a lot of
> time
> to explain how it works. Just accept that bytecode hacks are
> incredible
> (and nonportable too) ;-)
> 
>                                     Michele Simionato

No worries -- not sure I would understand the explanation at this point, 
anyway!

Just to verify, using the decorator module is portable, yes?

~Ethan~



More information about the Python-list mailing list