Metasyntax/Macros
Michele Simionato
mis6 at pitt.edu
Wed Jun 4 12:08:10 EDT 2003
Donald 'Paddy' McCarthy <paddy3118 at blueyonder.co.ukNOTthisBIT> wrote in message news:<3ED52C50.3020002 at blueyonder.co.ukNOTthisBIT>...
<snip>
> Anyone for meta-macro programming ;-)
The subject of macros come often in this newgroup. I've got
the impression that it is not difficult to implement them, the
problem is that the developers DON'T WANT them. I think they are
most probably right. Nevertheless, I have just finished an
experimental
project with the purpose of adding a macro facility to Python (it was
a proof of concept for me). This is done via a pure Python module,
called (according to the Principle of Minimal Surprise ;) 'macro.py'.
At the moment, it is still little tested, but it works along the
following
lines:
1. In order to define a macro, the user has to supply a template
function,
i.e. is a function that takes as arguments Python expressions in
string
format and returns as output a string Python expression (or
statement).
In the present implementation I have forced the time-honored
convention
that macros/template functions are all capitals.
An example is the following:
#<example1.py>
def PRINT(*args):
"The arguments are strings; returns a print statement"
return "print "+','.join(['"%s =",%s' % (a,a) for a in args])
#</example1.py>
PRINT works as follows:
>>> from example1 import PRINT
>>> PRINT()
'print '
>>> PRINT('x')
'print "x =",x'
>>> PRINT('x','y') # etc.
'print "x =",x,"y =",y'
2. In order to use the macro (the macro evaluate the output of the
template
function) the user has to write it inside a function or inside a
class;
the function or the class are then explicitly interpreted by using the
command 'expand' in the 'macro' module, which expands the template
function.
This is an example of usage:
#<example1.py>
import macro
def print_x(x):
PRINT(x) # will expand --> print "x=",x
expanded_print_x=macro.expand(print_x)
#</example1.py>
3. At this point, in ``expanded_print_x`` the macro PRINT(x) is
effectively
expanded to ``print "x=",x`` and calling the function gives the result
>>> from example1 import expanded_print_x
>>> expanded_print_x(1)
x = 1
4. Since using macro.expand repetitively can be annoying, I have
provided a metaclass facility. When a class has a ``__metaclass__ =
macro.expand()`` attribute, macros are automagically expanded in all
its methods and attributes, and in its derived classes, too.
#<example2.py>
import macro,example1
class B(object):
__metaclass__=macro.expand()
class C(B): # macros are automagically expanded
def __init__(self,x=None):
example1.PRINT(x) # --> print "x=",x
#</example2.py>
>>> from example2 import C
>>> c=C()
x = None
It works also for macros containing other macros (but
not for recursive macros).
Consider for instance the following ternary operator
#<example3.py>
def IF(cond,e1,e2):
return '(%s and [%s] or [%s])[0]' % (cond,e1,e2)
#</example3.py>
It can be composed with PRINT as in the following script:
#<example3.py>
from example1 import PRINT,macro
def print_ternary():
PRINT(IF(True,1,0)) # --> IF(True,1,0) = 1
print_ternary=macro.expand(print_ternary)
#</example3.py>
Here is how it works:
>>> from example3 import print_ternary
>>> print_ternary()
IF ( True , 1 , 0 ) = 1
I wonder if this approach could satisfy your requirements.
My module is still experimental and not for distribution; as I said,
the principal interest to me was to show that implementing macros IN
SOME WAY in pure Python is indeed possible with a reasonable amount of
effort.
However, implementing them WELL is a completely different story and I
expect
it to be extremely difficult ;)
Cheers,
--
Michele Simionato - Dept. of Physics and Astronomy
210 Allen Hall Pittsburgh PA 15260 U.S.A.
Phone: 001-412-624-9041 Fax: 001-412-624-9163
Home-page: http://www.phyast.pitt.edu/~micheles/
More information about the Python-list
mailing list