[Prev][Next][Index][Thread]

Re: Camlp4's (lack of) hygiene (was Re: Macros)



I'm cross-posting to comp.lang.dylan, since this thread is on-topic
there, too.

John Prevost <prevost@maya.com> wrote:
>
> Somebody mentioned Dylan having hygienic macros, and I seem to
> remember it didn't really have a s-expy syntax (am I wrong?)  How
> does Dylan handle hygienic macros?

Dylan used to have an sexpy syntax, but it nowadays it doesn't have
one, and hasn't had it for several years. Dylan's macro system is much
like Scheme's: parsing and macro expansion are interleaved.

The way the macro system is defined is pretty cool. Program text is
parsed into a minimal grammar of program fragments, and then macros
are basically sets of patterns/templates pairs that repeatedly rewrite
the program. Macros can expand into other macros, so expansion is
continued until you have no more of them. The macro expansions are all
hygienic, and referentially transparent. (In Dylan-speak both of these
properties are lumped together under the term hygiene, but it's
important to distinguish when talking about implementing it, since
the latter touches upon the module system and the former doesn't.)

Almost all of the actual language people program in is defined as a
set of these macros -- in the Gwydion Dylan compiler basic macros like
'define class' and so on expand into special implementation specific
calls that the compiler knows how to handle specially.

Making OCamlP4 hygienic is probably most easily realized by creating a
set of functions that implement a hygienic interface -- you have the
whole parse tree available, so you can define a set of functions that
manipulate the AST in a way that preserves bindings. Keeping track of
how many times a macro has been expanded is the sort of tedium that
you want to do only once.

The feature of Dylan's implementation of macros that may be tricky to
do with OCamlP4 is that Dylan macros maintain referential transparency.
That is, if you define a macro that refers to a binding in the module
it was defined in, then a macro call in an outside module the will still
use the binding in the original definition scope.

This may be tricky to do in OCaml without exporting the variable in
the structure (is that the right word?) interface, and you may not
want to expose it publically. You'll need a bigger brain than mine
to figure out how to solve that problem. :)


Neel