OT: Re: [plt-scheme] Hygenic Macros
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
this:
(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
>
>