RFC -- HYGIENIC MACROS IN PYTHON

Courageous jkraska at san.rr.com
Tue Feb 5 19:04:24 EST 2002


>Why do you want this? Isn't it just an implementation detail?
>I can see advantages in having it implemented as a preprocessor --
>you could look at the preprocessor output and see what Python is 
>generated. This might help with debugging complex macros.

Well, in systems where the macro system is native, they are
often even easier to debug. C++ templates, for example. While
early renditions were as difficult to debug as macros, macros
had to be hand pre processed. By your macro system really being
a first-class form which implements limited macro semantics,
you end up with first-class error handling of the macro itself.
Errors in macro definition are reported as the appropriate
kinds of exceptions, instead of through secondary effects, like
bizarre cascades of syntax errors.

I believe I can do this natively and do it correctly, which has
lots of value points.

>What if a macro needs to create local variables in its expansion?

This is perfectly legitimate. What's not legitimate is...

	deflingo myterm (i, codeblock):
		j=3

...where j=3 modifies the variable "j" in the context of the caller
if this variable is preexisting in the caller. That's non hygienic
behavior. Past experience with macros has shown this to be bad
behavior; hence there is a design in the community for good "hygiene,"
as it were.

>This would probably make more sense to me if you gave an example.

Yes; will observe now that I'm guilty of having selected deliberately
trivial macros. The point wasn't to demonstrate _utility_, I wanted to
show syntax. This appears to have been a mistake. :)

>>	invariant:
>>		dosomething()

Entire block of code delimited by ':' INDENT codeblock DEDENT is
evaluated in some heretofor undefined way by the invocation of the
"invariant" lingo. Note well that the block of code can be any
series of valid python expressions. I'm not sure how this particular
form would be made to be _useful_.

(GEEZE! PESTER ME WITH DETAILS WILL YA?!!) :) :)

>Why not factor(17) ?

This was a bad example. It would have been more useful to show...

	incf x

Details of the python lexer/parser might force it to be...

	$incf x

...however.

>IMO it is more Pythonic to say:
>
>   do:
>      dosomething()
>      while i <10                                                                                        

Correct. I'm not quite sure how to handle that one.

But of course macros themselves significantly erode simplicity, making
them _per se_ unpythonic, wouldn't you say? :)

>I think Python could benefit from a macro system. But the devil's
>in the details.

One of those nasty details would be collecting _sub_ macro forms separately
from parent macro forms. Note that this is distinctly different than _peer_
macro forms. Although I suppose that tree walking the ast at a later date
could do the proper manipulation. I'm having acid with that, but it's doable.

I see some difficulty (but not impossibility) of processing:

	do:
		dox()
		until i < 10
		doy()

Further, a moment of stupidity illustrated very clearly why macro systems
are dangerous. It would be _impossible_ to cleanly implement a macro which
overrode a preexisting keyword like that; at least not without a special
delimiter. In the above example I corrected the form to "until".

Egg on my face. :)

C//




More information about the Python-list mailing list