OT: Re: [plt-scheme] Hygenic Macros

From: Brian Campbell (lambda at mac.com)
Date: Thu Sep 12 19:54:14 EDT 2002

Well, besides being a little off topic, I have got to say that I 
respectfully disagree with a lot of Paul Graham's theories on language 
design. For instance, in the case of hygienic vs. classic macros, it's 
wrong to eliminate hygienic macros because you find them limiting. They 
may be limiting in some cases, but classic macros are also limiting in 
some cases.

To refute Graham's argument about how complicated hygienic macros are, 
I will explain them in one sentence: hygienic macros preserve lexical 
scoping. No more, no less. It has been demonstrated numerous times that 
lexical scoping is much better at keeping a program modular than 
dynamic scoping. The same is true for hygienic macros. It may be true 
that their implementation is not simple. But the whole idea of 
abstraction is that you have a simple interface on top of a complex 
implementation. Hygienic macros offer just that.

In any real system, you will have multiple hackers working on different 
portions of a project. No one hacker will know all the details of all 
of the code. So one coder may write a macro, and another may use it. If 
it is not a hygienic macro, it will break if the user binds one of the 
variables used in the definition of the macro, and it will break if the 
macro binds one of the variables the user doesn't expect to be bound. 
In order to get around the second problem, you can use gensyms in the 
macro definition. There is no way to get around the first without a 
hygienic macro system (at least that I'm aware of; I'm open to 
suggestion). For instance, if I write a macro that allows you to access 
elements of an array, I will probably use some sort of array reference 
function. Let's call it ref, and the macro elt. Now if I call it like 

(let ((ref 1))
   (elt (1 2 3) array))

The macro will break. Even worse results can happen in more subtle ways 
if there isn't an immediate type conflict, that can cause subtle 
problems to creep up for absolutely no reason.

Now, don't get me wrong. I think that unhygienic macros have their 
place. In fact, I've written the biggest, hairiest, least hygienic 
macro I've ever seen when I wrote a macro that allowed expressions to 
be evaluated and interpolated in strings. But you know, hygienic macros 
are damn useful. Why do extra work with gensyms that won't do 
everything you want when you could just use hygienic macros, which are 
easy to understand and preserve the idea of lexical scoping?

In an ideal language, you can do both. You can use the convenient, 
simple, safe hygienic macros when they are all you need, and you can 
selectively break the hygiene when you need something else. Hm, sort of 
like the new macro system in PLT Scheme 200+. It's the best designed 
macro system I've ever seen. You can write hygienic macros easily, and 
then selectively break that hygiene wherever you want. The one flaw I 
see in it is that you always have to convert syntax objects to lists 
and back, with a bunch of bookkeeping. I think that it should work like 
the collection system in Goo <http://www.googoogaga.com/>. You should 
be able to treat any collection the same way, using the same kinds of 
iterators (map, foreach, etc.). Lists, vectors, and syntax objects 
would all be sequences, and you could do all the same kinds of things 
to them. But of course, this would require an object system like Goo's 
(for those who don't know, it's pretty much a minimal CLOS), which I 
don't see PLT scheme adopting in the near future.

There are also things I could criticize about his other quotes, but 
I've done enough off-topic ranting for now.

On Thursday, September 12, 2002, at 06:55  PM, Jeff Stephens wrote:

> I was reading an article on the proposed Arc language at Paul Graham's 
> website,
> http://www.paulgraham.com/popular.html and came across these quotes 
> all by
> Dr. Graham.  I really enjoyed these and have placed the last three in 
> my signature
> file for future use. 
> "Classic macros are a real hacker's tool-- simple, powerful, and 
> dangerous. It's so easy to understand what they do: you call a 
> function on the macro's arguments, and whatever it returns gets 
> inserted in place of the macro call. Hygienic macros embody the 
> opposite principle. They try to protect you from understanding what 
> they're doing. I have never heard hygienic macros explained in one 
> sentence. And they are a classic example of the dangers of deciding 
> what programmers are allowed to want. Hygienic macros are intended to 
> protect me from variable capture, among other things, but variable 
> capture is exactly what I want in some macros."
> "Brevity is one place where strongly typed languages lose.
> All other things being equal, no one wants to begin a
> program with a bunch of declarations. Anything that can
> be implicit, should be."
> "...a hacker's idea of a good programming language is not
> the same as most language designers'.  Between the two, the
> hacker's opinion is the one that matters."
> "Programming languages are not theorems. They're tools,
> designed for people, and they have to be designed to
> suit human strengths and weaknesses..."
> Paul Graham
> author of ANSI Common Lisp

Posted on the users mailing list.