Macros[by implementor of toy compiler]

Michal Gajda
Mon, 7 May 2001 17:48:47 +0200 (CEST)

On Fri, 4 May 2001, Alan Bawden wrote:

> (...)
> But I think that in many circumstances macros do
> such a good job that I don't see the need to clutter up the language with
> the special-prupose features needed to replace them.
> (...)

I'm currently making fun by writing compiler from eager lambda calculus
with hygienic macros to it's desugared form(when using parser combinators,
I estimate 2k lines of ML code), so I take freedom to share my
experiences. Working(simple and without typechecking, so only the
syntactic correctness is checked) version expected at the end of the

* Introduction of general hygienic macro's as you propose, forces us to
cope with following problems:
1. Full typechecking of macros(in place of definition) seems to need
second-rank polymorphism. (Decidable, but harder to implement) Of course
you can delay typechecking until you expand all macros, but then
error-messages become unreadable.
[in Lisp it is non-issue]

2. Macros make the parsed grammar dynamic. Usually compiler has hard-coded
parser generated by LALR parser generator(like Happy or Yacc) compiled in.
Introducing each macro like you proposed would need(I think) generating
new parser(at least for the fragment of the grammar).
[In Lisp we just separate form with macro named head, and then apply
macro's semantic function to macro's body at COMPILE TIME. So:
a) the basic syntax is unchanged
b) we need to evaluate expressions at compile-time]
* On the other hand it yields following advantages:
1. Powerful enough to implement do-notation(for sure) and (probably) all
or most other to-core Haskell translations.
2. Lifts (unsurprisingly) the need to use cpp preprocessor when handling
compatibility issues.

	Hope it helps :-) [and feel free to mail me if you are interested]
		Michal Gajda