[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

issue MACRO-ENVIRONMENT-CREATOR, version 1



    Date: Tue, 10 Jan 89 12:48:47 MST
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
    ...
    Forum:		Compiler
    Issue:		MACRO-ENVIRONMENT-CREATOR
    ...
    Problem Description:
    ...
    There is no way for a user to write a portable code walker which will
    correctly expand macros that use the &ENVIRONMENT argument, because
    there is no way to construct a non-null environment object in the
    format expected by MACROEXPAND.
    ...

Actually, I'm not totally sure I agree with this claim. It might be beyond
the limits of most programmers, but my impression is that this is (like
your argument about COMPILER-LET :-) something someone could cook up a special
solution to if the -really- needed to.

That isn't to say that I don't think the proposal is not justified from
a practical point of view, since what you suggest is easier to think up,
easier to prove correct, etc. than the alternatives I'm alluding to.

Just for fun, I've attached some code from a part of Cloe which does 
code-walking (to support a macro-version of SYMBOL-MACROLET that we've been
using during a transition to a SYMBOL-MACROLET special form). I don't have
time to explain what it does, but if anyone's bored with nothing to do they
might have the time to puzzle it out...

(DEFVAR *MAP-MACROEXPAND-1* #'MACROEXPAND-1)

(DEFUN MAP-MACROEXPAND (FORM)
  (DO ((FORM FORM)
       (FLAG NIL T))
      (NIL)
    (IF (AND (NOT (ATOM FORM))
	     (SYMBOLP (CAR FORM))
	     (MAP-FORMS-HANDLER (CAR FORM)))
	(RETURN (VALUES FORM FLAG)))
    (MULTIPLE-VALUE-BIND (EXPANSION DIFFERENT-P)
	(FUNCALL *MAP-MACROEXPAND-1* FORM)
      (IF (NOT DIFFERENT-P)
	  (RETURN (VALUES EXPANSION FLAG)))
      (SETQ FORM EXPANSION))))

...

(DEFINE-MAP-FORMS-HANDLER LISP:MACROLET (FUNCTION FORM)
  (LET ((BINDINGS (CADR FORM))
	(BODY     (CDDR FORM))
	(FN1 (GENSYM)))
    `(MACROLET ,BINDINGS
       ,(EVAL `(MACROLET ,BINDINGS
		 (MACROLET ((,FN1 (&ENVIRONMENT ENV)
			     (LET ((*MAP-MACROEXPAND-1* #'(LAMBDA (X) (MACROEXPAND-1 X ENV))))
			       `',(MAP-FORMS-PROGN ',FUNCTION ',BODY))))
		   (,FN1)))))))

If the technique used is not portable, I'd be curious about why. It
certainly ported fine between Genera and the Cloe Runtime (which have
extremely different pedigrees) with no special adaptation.