Date: Mon Dec 1, 2003 15:29:29 US/Eastern
Subject: Re: Beyond SYNTAX-RULES
Taylor Campbell wrote:
You might also be thinking 'um, why not just use SYNTAX-CASE?'
There are several reasons: (1) Do you really _need_ full Scheme at
macro-expand-time? Probably not, but you _might_ need some of the
directives, such as UNHYGIENE. (2) Does the _implementor_ want to
allow for arbitrary Scheme code at macro-expand-time? Maybe, maybe
not: it introduces lots of problems regarding phase separation and
syntactic environment towers.
SYNTAX-RULES is sufficient for 90% of all of the macros you will
ever need to write. Of the remaining 10%, SYNTAX-RIASTRADH probably
solves 9%. The remaining 1% is solvable only through low-level macro
systems such as R4RS's low-level system, SYNTAX-CASE, explicit
renaming, syntactic closures, et cetera, and to try to specify them in
a standard would open up a huge can of worms that no one wants to try
Amen. Frankly, I can't think of any way to put it better.
Now that the Christmas season is upon us, perhaps I may be permitted
to profess a few wishes. For one thing, it would be nice to clarify
some gray areas in syntax-rules, for example, the one mentioned in
It has been mentioned that such an undefined behavior is a consequence
of an incomplete specification for a top-level define (it is left
unspecified if the top-level define binds or merely sets). It should
be pointed out that two different syntax-rule macro-expanders may have
different behavior on the same Scheme system. It seems what matters
not what a Scheme system thinks define does, but what a macro-expander
thinks the Scheme system thinks define does. Perhaps we can
deterministically fix the macro-expander's thinking.
Another wish is for the body of a top-level let-syntax and
letrec-syntax to behave as the body of a top-level begin. For example,
(let-syntax () (define foo 1))
should print 1. Actually, it does so on Petite Chez Scheme, but not on
many Scheme system. The above feature would make it possible to write
modular macros that expand into definitions. Otherwise, such macros
be either monolithic or top-level-namespace-polluting. I vaguely
remember that something like that was discussed on Scheme 1998
workshop and agreed upon.
Perhaps we can standardize this practice in the SRFI.
- (unhygiene UNHYGIENIC-GENERATOR-IDENTIFIER)
Specifies an identifier to be used in the template to
unhygienically produce identifiers. See the examples later
for how to use this. There is no default if this directive
is not specified.
The original Kohlbecker algorithm (described in the paper "Hygienic
Macro expansion" by Kohlbecker, Friedman, Felleisen and Duba) had a
provision for unhygienic identifiers. Their discussion is quite
illuminating. Two paragraphs of the second column of p. 157 (beginning
with the sentence "Now that we have a hygienic expansion algorithm, we
can think about the implementation of exceptions to the HC/ME rule")
are very illuminating. They point out dangers in capturing identifiers
and describe their design choice, which seems sensible. Of course,
their system did not support macros generating macros (i.e.,
let-syntax). Incidentally, we can still use their design decision if
we require that (unhygiene ...) may occur only in top-level macros.
Al Petrofsky wrote:
In practice (assuming we do not allow identifier concatenation), I
think the first argument to the unhygiene operator will always be the
identifier that was used to invoke the macro. (That statement might
be way off: someone with more syntax-case experience please correct me
if so, and provide motivation for other first arguments to
macros in Dan Friedman's paper "Object-Oriented Style" show
non-trivial uses of the first argument to datum->syntax-object.
Please see with-implicit, extend-shadow, and especially