Python syntax in Lisp and Scheme

Kaz Kylheku kaz at ashi.footprints.net
Mon Oct 13 16:01:19 EDT 2003


gregm at cs.uwa.edu.au wrote in message news:<blr1cq$bb1$1 at enyo.uwa.edu.au>...
> In comp.lang.functional Erann Gat <my-first-name.my-last-name at jpl.nasa.gov> wrote:
> :> I can't see why a LISP programmer would even want to write a macro.
> : That's because you are approaching this with a fundamentally flawed
> : assumption.  Macros are mainly not used to make the syntax prettier
> : (though they can be used for that).  They are mainly used to add features
> : to the language that cannot be added as functions.
> 
> Really? Turing-completeness and all that... I presume you mean "cannot

``Turing completeness and all that'' is an argument invoked by the
clueless.

Turing completeness doesn't say anything about how long something
takes to compute, or how easy it is to express some interesting
computation.

In the worst case, for you to get the behavior in some program I wrote
in language A in your less powerful (but Turing complete!) language B,
you might have to write an A interpreter or compiler, and then just
run my original program written in A! The problem is that you did not
actually find a way to *express* the A program in language B, only a
way to make its behavior unfold.

Moreover, you may have other problems, like difficulties in
communicating between the embedded A program and the surrounding B
code! These difficulties could be alleviated if you could write an A
*compiler* in B, a compiler which is integrated into your B compiler,
so that a mixture of A and B code is processed as one unit!

This is precisely what Lisp macros allow us to do: write compilers for
embedded languages, which operate together, all in the same pass.

So for instance an utterance in the embedded language can refer
directly to a local variable defined in a lexically surrounding
construct of the host language.

> : DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented
> : any other way because they take variable names and code as arguments.
> 
> What does it mean to take a variable-name as an argument? How is that
> different to taking a pointer? What does it mean to take "code" as an
> argument? Is that different to taking a function as an argument?

Sheesh. A funtion is an object containing a program, and an
environment that establishes the meaning of entities like variables
for that program.

Code, in this context, means source code: a raw data structure
representing syntax.

Code can be analyzed, subject to transformations, and interpreted to
have arbitrary semantics.

A function can merely be invoked with arguments.

A compiler or interpreter for a functional language like Haskell still
has to deal with the representation of the program at some point: it
has to parse the source characters, recognize the syntax and translate
it into some meaning.

Lisp macros are part of the toolset that allow this translation itself
to be programmable. Thus you are not stuck with a fixed phrase
structure grammar with fixed semantics.

Nearly every programming language has macros, it's just that most of
them have a hard-coded set of ``factory defined'' macros in the form
of a fixed set of production rules with rigidly defined semantics.

What is a macro? It's a recognizer for syntax that implements some
kind of syntax-directed translation. I would argue that   while (expr)
statement   in the C language is a macro: it's a pattern that matches
a parse subtree that is tagged with the ``while'' token and translates
it into looping code, whose semantics call for the repeated testing of
the guarding expression, followed by execution of the statement if
that expression is true.




More information about the Python-list mailing list