[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: recursive macro definitions
Date: Tue, 18 Jul 1995 16:18:35 +0900
From: Matthias Blume <blume@hip.atr.co.jp>
....
To state it simply: Are the right-hand sides of a macro definition in
LETREC-SYNTAX allowed to use (invoke) any of the macros defined by the
very same LETREC-SYNTAX expression? -- We have two conflicting
intuitions here:
1. Yes -- because the definition is recursive!
2. No -- how can I invoke a macro whose transformer I don't
know yet?
This question is the same one that Scheme answers so nicely regarding
lambda and procedures:
*Semantics:* A lambda expression evaluates to a procedure. The
environment in effect when the lambda expression was evaluated is
remembered as part of the procedure.
An analogous translation would read something like:
*Semantics:* A syntax-lambda expression syntax-evaluates to a
macro. The environment in effect when the syntax-lambda
expression was evaluated is remembered as part of the macro.
It would make sense to use Scheme's solution to recursive function
definition for recursive macro definition as well. I believe that
that syntactic-closures implement this sort of idea.
For values we have the notion of a `suspended execution', and uses of a
LETREC-bound variable within the right-hand sides of the binding
LETREC must only occur suspended. Unfortunately, this property cannot
be checked reliably at compile-time:
(letrec ((ones (f 1 (delay ones))))
...)
Since DELAY can be expressed as a macro, and since macro expansion can
be interpreted at compile time, I don't see why DELAY should pose any
special difficulty to a compiler. The difficulty represented by DELAY
must be a member of a larger class of troublesome expressions.
Other languages (e.g. SML) adopt the policy of not permitting anything
but LAMBDA expressions in the binding initializers, which effectively
eliminates the problem.
[...]
I am more interested in getting rid of LETREC-SYNTAX and using LETREC
for all kinds of recursive bindings. This is slightly tricky, since
it requires determining the nature of the right-hand side of a
definition. [In my model of a low-level macro system all macros are
ultimately specified by some `primitive' transformer, for which there
is a special form.] In order to do this we might have to expand a few
macros. But for ordinary value definitions it must be possible to
invoke macros defined within the same LETREC, because otherwise it
would be pointless to mix the two together in the first place.
It sounds like detection of the macros is really the problem. I think
a requirement that the top level form of any macro binding be
1) a primitive transformer OR
2) a macro invocation returning a macro would
make them easily detectable while not burdensome to use.