Lisp-like macros in Python?

sturlamolden sturlamolden at yahoo.no
Tue May 1 12:10:25 EDT 2007


Hello

The Lisp crowd always brags about their magical macros. I was
wondering if it is possible to emulate some of the functionality in
Python using a function decorator that evals Python code in the stack
frame of the caller. The macro would then return a Python expression
as a string. Granted, I know more Python than Lisp, so it may not work
exactly as you expect.

Any comments and improvements are appreciated.

Regards,
Sturla Molden




__codestore__ = {}

def macro(func):

    """
        Lisp-like macros in Python
        (C) 2007 Sturla Molden

        @macro decorates a function which must return a Python
expression
        as a string. The expression will be evaluated in the context
(stack frame)
        of the caller.
    """

    def macro_decorator(*args,**kwargs):
        global __codestore__
        import sys
        pycode = '(' + func(*args,**kwargs) + ')'
        try:
            ccode = __codestore__[pycode]
        except:
            ccode = compile(pycode,'macrostore','eval')
            __codestore__[pycode] = ccode
        frame = sys._getframe().f_back
        try:
            retval = eval(ccode,frame.f_globals,frame.f_locals)
            return retval
        except:
            raise
    macro_decorator.__doc__ = func.__doc__
    return macro_decorator


# Usage example

def factorial(x):

    """ computes the factorial function using macro expansion """

    @macro
    def fmacro(n):

        """ returns '1' or 'x*(x-1)*(x-2)*...*(x-(x-1))' """

	if n == 0:
            code = '1'
        else:
           code = 'x'
           for x in xrange(1,n):
               code += '*(x-%d)' % (x)
        return code

    return fmacro(x)




More information about the Python-list mailing list