Python syntax in Lisp and Scheme

Alex Martelli aleax at aleax.it
Fri Oct 3 08:40:36 EDT 2003


mike420 at ziplip.com wrote:

> I think everyone who used Python will agree that its syntax is
> the best thing going for it. It is very readable and easy
> for everyone to learn. But, Python does not a have very good
> macro capabilities, unfortunately. I'd like to know if it may
> be possible to add a powerful macro system to Python, while
> keeping its amazing syntax, and if it could be possible to

You can surely hack a "pre-processor" on top of the Python
interpreter.  With the Python 2.3 architecture of import
hooks, it might even be quite feasible to experiment with
this idea as a pure Python package and distribute it as such:
just add a hook that scans incoming source files (modules)
for definitions and/or occurrences of the 'macros' you want,
and (respectively) squirrels away the definitions, and/or
expands the macros.  As for designing the syntax for macro
definitions and expansions while remaining 'amazing', I'll
pass -- but surely it's not beyond human possibilities;-).

Anyway, see later in this post for a toy-level example.


> add Pythonistic syntax to Lisp or Scheme, while keeping all
> of the functionality and convenience. If the answer is yes,
> would many Python programmers switch to Lisp or Scheme if
> they were offered identation-based syntax?

If you could make all of the existing Python extensions,
libraries, frameworks, etc, instantly available from Lisp or
Scheme, you'd gain a LOT of kudos in the Lisp or Scheme
community, I suspect.  That most existing Python coders
would be happy to leave the semantic simplicity of their
chosen language for the richness of Common Lisp, I very,
very strongly doubt, but in any case until the whole array
of existing extensions &c is available it's not an issue;-).


So, anyway, here's the promised toy-level example of using
custom importers with the new Python 2.3 mechanics to get
macros.  I'm cutting corners to the bone (just to mix a
couple metaphors...) by using the C preprocessor (!) as my
"macro expander", ignoring packages, _and_ only looking for
"C-macro" definitions AND expansions in files with extension
".pyp" (all others, I'll leave alone...).  Oh, also, I do
not worry about saving bytecode for such files -- I'm gonna
preprocess and recompile them on every run of the program
(far too much trouble, when macros exist, to determine
whether a bytecode file is up to date -- one should check
it, not only with respect to the date of ONE source file,
but rather of a hard-to-pin-down collection of macro and
include files... so, in the spirit of cutting corners and
keeping this a VERY toy-level example, I'm punting:-).  So,
here's the gist...:


import sys
import os
import imp

prepro = 'cat %s | gcc -E -'

class MacroImporter(object):

    def __init__(self, path):
        self.path = path

    def find_module(self, modname):
        look_for_file = os.path.join(self.path, modname+'.pyp')
        self.code = os.popen(prepro % look_for_file).read()
        if self.code: return self
        else: return None
        
    def load_module(self, modname):
        mod = imp.new_module(modname)
        sys.modules[modname] = mod
        mod.__file__ = "<Macro-Expanded %s>" % modname
        exec self.code in mod.__dict__
        return mod

sys.path_hooks.append(MacroImporter)

example = open('pippo.pyp', 'w')
example.write('''
#define unless(cond) if not(cond)
def pippo(x):
    print 'x is', x
    unless(x>=2): print '  x is smaller than two'
    unless(x<=4): print '  x is bigger than four'
''')
example.close()

import pippo
pippo.pippo(1)
pippo.pippo(7)


Removing the various oversimplifications, and, in particular, designing
a better macro scheme than gcc -E supplies, is left as a trivial exercise
for the reader (I have in fact devised a perfect scheme, of course, but,
unfortunately, the margins of this post are too narrow for me to write it
down...).


Alex





More information about the Python-list mailing list