[Python-Dev] defmacro (was: Anonymous blocks)

Jim Jewett jimjjewett at gmail.com
Mon Apr 25 23:04:34 CEST 2005


Michael Chermside:

> There are lots of things one might want to replace within macros, from
> identifiers to punctuation, but I'd be willing to live with just two of
> them: expressions, and "series-of-statements" (that's almost the same as
> a block). There are only two places I'd want to be able to USE a macro:
> where an expression is called for, and where a series-of-statements is
> called for. In both cases, I'd be happy with a function-call like syntax
> for including the macro.

I have often wanted to replace (parts of) strings, either because I'm 
writing a wrapper or because I want a non-English version to be loadable
without having to wrap strings in my own source code.  This is best done
as an import hook, but if I had read-write access to (a copy of) the source
code, I would use it.  I'm not sure I want that door opened, because if I start 
needing to parse regex substitions just to get a source code listing
... I won't
be happy.

I do think macros should be prevented from "changing the level" of the
code it replaces.  Any suites/statements/expressions (including parentheses 
and strings) that are open before the macro must still be open afterwards,
and any opened inside the macro must be closed inside the macro.

For example

def foo(x):
    print x
    macro1(x)
    print x

might print different values for x on the two lines, but I would be less 
comfortable if it could result in any of the following:

def foo(x):
    print x
    while True:        # An invisible loop, because of 
        print x           # Changing the indent level

def foo(x):
    print x
    return               # and you thought it would print twice! 
(This one is iffy)
    print x               

def foo(x)
    print x
    [("""        (unclosed string or paren eats up the rest of the file...)
    print x

def foo(x)
    "Hah!  my backspaces and rubouts eliminated the print statements!"

def foo(x)
    print x
def anotherfunc(x, y, z):
    print x   # Hey, I didn't even mess with the indent!            

And to be honest, even

def foo(x):
    macro1(x)
        stmt1()        # syntax error, except for the macro, so not ambiguous

expanding to

def foo(x)
    while x:
        print x         # macro does not end on same indent level
        stmt1()

is ... not something I want to worry about when I'm reading.

Michael Chermside:
> (hint: the answer is that it ALL happens at runtime).

I have mixed feelings on this.  It is more powerful that way,
but it also limits future implementations -- and I'm not sure
the extra power is entirely a good thing.

defmacro():
    print x # Hey, x was in global scope at runtime when *I* tested

On The Other Hand, this certainly isn't the only piece of python
that could *usually* be moved to compile-time, and I suppose it
could piggyback on whatever extension is used for speeding up
attribute lookup.

-jJ


More information about the Python-Dev mailing list