RFC -- HYGIENIC MACROS IN PYTHON

Courageous jkraska at san.rr.com
Tue Feb 5 06:36:47 CET 2002


NOTE! This is _not_ a python enhancement proposal. Please don't
respond as if it were. The Python steering committee rightly
worries themselves with the idea that macros can seriously
worsen the maintainability and comprehensibility of code when
misused; further Guido has historically been adamantly opposed
to macros in Python. I am not addressing any of those political
issues at this moment in time.

Onward...

I am currently experimenting with an implementation of hygienic macros
in a custom Python parser as part of a larger experiment. One of the
things I wish to accomplish in this experiment is a practical idea
of what it means to have a macro in a whitespace-sensitive language,
to what useful ends it can be put, lexing/parsing issues, how to
express declaration and invocation thereof, and so on.

I've come up with this concept that I'm calling "lingos": the name
was chosen to evoke the idea of defining one's own lingo as a subset
of the language. I'm still very much in the concept definition stage.

I'm certain of little, but I'm certain that I want lingos to have
at least the following properties.

1. Lingos must be understood natively by the parser. No preprocessor
front-ends or any other hack.

2. Lingos must be "hygienic". For those unfamiliar with the term,
this means that names and symbols in the macro definition must not
permute or modify the symbols in the namespace of the caller except
where such a possibility is explicitly expressed: i.e., only the
arguments to the macro itself can be permuted.

3. Lingos should be able to modify arguments as if the code in the
lingo were used in place of the lingo itself. I suppose that this
is a fancy way of saying that one additional level of referentiality
is supported. I'm a bit fuzzy about this one; what I do know is that
I don't necessarily mean that it will behave strictly like a macro
and be _expanded_ at the caller. That may or may not be a solution;
perhaps note.

4. Lingos should be able do deal with _code itself_ as a parameter.
This affords the opportunity to have lingos masquerade as proper
Python block forms.

5. Lingos might be able to support serial lingo forms, where one
lingo knows how to aggregate multiple lingos into one lingo
invocation. What I mean by this last is easier to describe by
example.

I've actually been able to get some of what I want to parse in my
environment, although it's not clear to me that I'll be able to
avoid special symbols, or even whether or not I _should_ avoid
special symbols (one might argue that the use of lingo implies a
special behavior and using a symbol to mark this might be appropriate;
if so I suppose "$" is the logical choice).

Discarding the issue of special symbols for the moment, here are
some possible lingos by example:

1. Here "invariant" is a lingo macro which has 0 expression arguments
   and 1 code argument:

	invariant:
		dosomething()

2. Here "unless" is a lingo macro taking 1 expression argument and 1
   code argument:

	unless i < 3:
		dosomething()

3. Here "factor" is a lingo macro taking 1 expression argument and
   no code argument:

	result = factor 17

4. Here "do" is a lingo macro taking 0 expression arguments, a code
   argument, and acting as an aggregator for exactly 1 "while" lingo
   form:

	do:
		dosomething()
	while i <10

So. That, at last, brings me to the point of this message. Ideas?
Feedback? This has been an interesting experiment so far, I'm just
wondering how many folks find this sort of thing interesting and if
anyone has any input.


Joe Kraska
San Diego
CA




More information about the Python-list mailing list