Lisp-like macros in Python?

Discussion in 'Python' started by sturlamolden, May 1, 2007.

  1. sturlamolden

    sturlamolden Guest

    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)
    sturlamolden, May 1, 2007
    #1
    1. Advertising

  2. On May 1, 5:10 pm, sturlamolden <> wrote:
    > 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.


    The 'magical macros' of lisp are executed at compile time, allowing
    arbitrary code transformations without the loss of run time
    efficiency. If you want to hack this together in python you should
    write a preprocessor that allows python code *to be run in future*
    inter spaced with python code *to be executed immediately* and
    replaces the executed code with it's output. The immediately executed
    code should be able to make use of any existing code or definitions
    that are marked as to be compiled in the future.

    This is should be quite do-able in python(I think I haven't really
    looked at it) because it has a REPL and everything that implies, but
    you'd have to implement lispy macros as some kind of def_with_macros
    which immediately produces a string which is equivalent to the macro
    expanded function definition and then evaluates it.

    Good luck in doing anything useful with these macros in a language
    with non-uniform syntax however.
    Chris Russell, May 1, 2007
    #2
    1. Advertising

  3. Pascal Costanza, May 1, 2007
    #3
  4. sturlamolden

    Duane Rettig Guest

    sturlamolden <> writes:

    > 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


    I don't know python, but check out

    http://www.cl-user.net/asp/libs/clpython

    --
    Duane Rettig Franz Inc. http://www.franz.com/
    555 12th St., Suite 1450 http://www.555citycenter.com/
    Oakland, Ca. 94607 Phone: (510) 452-2000; Fax: (510) 452-0182
    Duane Rettig, May 1, 2007
    #4
  5. sturlamolden

    Andy Freeman Guest

    On May 1, 9:10 am, sturlamolden <> wrote:
    > 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.


    How about something that can't be done with a function, such as the
    functionality of the "with" statement that was added to python 2.5?

    Yes, it has to handle a suite of statements.

    It would be nice if it handled both the "{as target}" and no target
    forms.

    Also, it shouldn't rely on magic names - if it needs a variable for
    its purposes, it should guarantee that said variable and/or use can
    not be one that affects how the rest of the user's program behaves.

    There's a fair amount of relevant discussion in http://www.python.org/dev/peps/pep-0343/
    ..
    Andy Freeman, May 1, 2007
    #5
  6. sturlamolden

    John Nagle Guest

    Duane Rettig wrote:
    > sturlamolden <> writes:
    >
    >
    >>Hello
    >>
    >>The Lisp crowd always brags about their magical macros.


    I used LISP back when LISP macros were popular.
    You don't want to go there. It degrades readability
    without improving the language.

    Check out the original "MIT loop macro", used to put
    something comparable to a FOR statement into early versions
    of LISP.

    http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/iter/loop/mit/0.html

    Note that it's at version 829. And that was with MIT people fixing it.
    That thing was a trouble spot for a decade or more.

    Scheme added a "do" statement as part of the language, which
    was the right answer. The "loop macro" was, at long last, retired
    around 1991.

    There are lots of "l33t" features one can put in a language,
    but in the end, they're mostly not that helpful.

    The people who advocate "l33t features" usually need to do more
    maintenance programming on the code of others, to get more of a sense
    of gives real, operational trouble in a programming language.
    Really. After you've fixed the bad code of others, then you're
    entitled to talk about language design.

    As someone who's programmed in all too many languages and with
    a background in formal proof systems, I would make few changes to
    Python as a language. (And most of the things I'd change involve
    removing less-used features that constrain implementations.)
    The language is fine. The problems are elsewhere.
    The CPython implementation is way too slow and some of the libraries
    are flakey. That's what needs attention.

    John Nagle
    John Nagle, May 1, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    16
    Views:
    474
    Kaz Kylheku
    Oct 28, 2003
  2. Replies:
    37
    Views:
    933
    Thomas Bartkus
    Jul 11, 2005
  3. Anthony de Almeida Lopes

    Macros within function-like macros?

    Anthony de Almeida Lopes, Dec 26, 2005, in forum: C Programming
    Replies:
    13
    Views:
    744
  4. ekzept
    Replies:
    0
    Views:
    354
    ekzept
    Aug 10, 2007
  5. jsykari

    Lisp-like macros for C?

    jsykari, Sep 30, 2009, in forum: C Programming
    Replies:
    9
    Views:
    1,348
    wolfgang.riedel
    Oct 14, 2009
Loading...

Share This Page