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

Re: macro expansion



I think Scott may be mistaken when he says that Chapter 8 of the Colander
edition is the MacLisp style -- it's more the LispM style from some months
ago.  I and RWK introduced multiple-value returning MACROEXPAND into
MacLisp/NIL some years ago, and shortly thereafter added in an expander
hook;  I think those changes were documented in the usual LISP.RECENT
messages.   Since then, the NIL version has been supplanted by yet a third
(incompatible) scheme, but this brings up a couple of questions on your 
proposal as of this dateline:

  1) Why not have MACROEXPAND return the second value, as obtained
    from MACROEXPAND-1  ?  A typical usage merely wants to "do all and 
    any expansions" and also be informed as to whether or not anything really
    happened.   It might even be worthwhile for this second return value, when
    non-null, to distinguish between the case of having actually run the
    expansion function and having found the expansion in some "memoization"
    facililty.    (the file [MC]NILCOM;DEFMAX > shows the "...-1" function 
    spelled MACROEXPAND-1*M, but only to retail losing compatibility with 
    the Lispm on the name MACROEXPAND-1). 

  2) We saw the need for a function called FIND-MACRO-DEFINITION,
    which more-or-less fulfills the purpose of the "blank" in your
    definition labelled "---get expander function---";  thus there is one
    place responsible for things like:
      2a) autoloading if the macro is not resident but does have an 
        AUTOLOAD property, or 
      2b) looking on the the alist found in MACROLIST so that one may 
        lambda-bind a macro definition without disturbing the function
        definition cell (nor the propertylist).

  3) although MacLisp/NIL didn't call it a general macro-expander-hook 
    the variable MACRO-EXPANSION-USE supplied just that facility
    (in coordination with DEFMACRO); also, it "distributed" the fetching of
    memoized expansions on a per-macro basis, so that there could be some 
    variablilty;  after all, a uniform *default* is fine, but ocasionally there is 
    a macro which wants to say "don't memoize me at all".   I'd say that there
    is a lacuna in your proposal in that you don't exhibit code for the case of   
    traditional memoizing by hashtable -- that will show how the macroexpansion
    function is selectively called depending on the hashtable entry.  

  4) we often felt the need for an additional argument to the expansion
    function which tells *why* this macro call is being expanded -- e.g.,
    EVAL, or COMPILE, or  FOR-VALUE, or FOR-EFFECTS etc.  I can't
    characterise all such cases, but GSB, KMP, and RWK may have some
    good inputs here.


Point 3 brings up another possibililty -- maybe your current definition of
*MACROEXPAND-HOOK* is an over-generalization.  That is, why not
have two hooks, one for testing whether or not a "memoization" is present
for the macro call in question (and returning it if present), and another hook
of three arguments namely:
      i) a pointer to the original cell (macro call),
     ii) the already-computed expansion form, and
    iii) a symbol to indicate the reason why the macro call was "expanded"
I realise that iii) will require more discussion, so maybe now is not the time
to put it into CommonLisp; also the memoization hook would have to return
a second value to indicate whether a memo was present.

In any case, I'd rather see the default value for these macro hooks be NIL,
so that one didn't have to understand the complexities of expansions and
memoizations just to get the default case (that is, unless someone plans to
allow NIL as a valid function name and . . . )