No macros in Python
Bruce Hoult
bruce at hoult.org
Wed Jan 1 03:48:58 EST 2003
In article <x78yyqiwle.fsf at guru.mired.org>, Mike Meyer <mwm at mired.org>
wrote:
> Peter Hansen <peter at engcorp.com> writes:
> > Mike Meyer wrote:
> > >
> > > Python doesn't have macros. On the other hand, looking at the world
> > > through OO glasses rather than S-expression glasses means you don't
> > > need macros as often. But the topic comes up at irregular intervals,
> > > so someone may eventually come up with a way of doing macros in Python
> > > that is right - at which point it'll be added.
> > In what way would macros (as I understand them... from C for example)
> > improve Python, other than possibly a small improvement in performance?
>
> C macros are a very poor example of the species. I was referring to
> lisp-like macros, where you get the full functionality of the language
> to manipulate the code that the macro is dealing with.
That's pretty cool, and the most flexible it's possibel to get, but I
think it's overkill for most cases, and not always the easiest to write
or to understand.
> This works particularly well in lisp, where the code is handed to the
> macro preparsed and stored in one of the fundamental data structures
> of the language. That makes writing macros easier. Since all code is
> written in that data structure, they also fit naturally into the
> language when they are invoked.
True.
> Any macro facility added to python has to deal with both these
> problems. There needs to be some way to avoid the macro author having
> to write a python parser to manipulate the code, and some way for them
> to be invoked that fits well with the language.
You should take a look at macros in Dylan. You can implement pretty
much every macro in _On Lisp_, in a language with conventional syntax.
And you don't have to write a parser! Dylan macros work by pattern
matching and replacement on token sequences.
> As for what this lets you do, the answer is "lots of things". Much of
> what is part of the syntax of Python can be implemented as macros in
> lisp - short-circuit boolean operators come readily to mind.
In the Dylan standard library:
define macro \&
{ \& (?left:expression, ?right:expression) }
=> { if (?left) ?right end }
end;
define macro \|
{ \| (?left:expression, ?right:expression) }
=> { let temp = ?left; if (temp) temp else ?right end }
end;
| and & are infix operators in Dylan, so to talk about them as functions
(or to define them) you need to refer to them as \| and \&.
> For a programmatic example, there's the ever-popular
> "with-io-redirection" macro family. A proper macro facility in python
> should let me write:
>
> with_output_to_file "filename":
> code that will be executed
> with print statement output
> going into filename
> code that will have
> print statement output
> going to where ever it was
> going before the macro
In Dylan this might be implemented like:
define macro with-output-to-file
{
with-output-to-file (?stream:variable = ?filename:expression)
?:body
end
}
=> {
let temp-stream = #f;
let saved-stream = ?stream;
block ()
temp-stream :=
make(<file-stream>, locator: ?filename,
direction: #"output");
let ?stream = temp-stream;
?body;
cleanup
if (temp-stream)
close(temp-stream);
end if;
?stream := saved-stream;
end block
}
end macro with-output-to-file;
... and used as ...
with-output-to-file (*standard-output* = "filename")
code that will be executed
with print statement output
going into filename
end;
code that will have
print statement output
going to where ever it was
going before the macro
> Which brings up the primary argument people have against macros. By
> changing the syntax of the language, they make it impossible to
> understand a program by local examination. You have to know what
> macros are in scope and thus might change the programs behavior. Then
> again, the ability to redefine operators does much the same
> thing.
So do:
- the ability to define functions
- the ability to assign new values to existing variables
> Which is why I don't buy the "they'll never be added because
> they are inherently evil" argument. The two are equally evil, for the
> same reasons. We've got one. Why not the other?
Yep.
-- Bruce
More information about the Python-list
mailing list