[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.