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

Re: macro expansion



    Date: 2 Sep 1982 18:09 PDT
    From: JonL at PARC-MAXC
    In-reply-to: Moon at SCRC-TENEX's message of Sunday, 29 August 1982, 21:26-EDT

Sorry for the slow response, I am behind on my mail.  There seemed to be a couple
things in this message that shouldn't be left hanging.

      1) Why not have MACROEXPAND return the second value, as obtained
        from MACROEXPAND-1 ?
That would be all right with me, I just overlooked it when writing the sample code.

        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.
I can't see any point to this one.

      2) We saw the need for a function called FIND-MACRO-DEFINITION,
Having this would be fine with me.  I think the committee decided that this
should not be in the portable language, because only MACROEXPAND-1 should
be calling it, and removed this functionality from MACROP or MACRO-P.  I'd
stick with that unless there is a good reason to put it back in.

      3) ocasionally there is 
        a macro which wants to say "don't memoize me at all".
I don't see the use for this, since the macro can't control when the interpreter
or compiler remembers the macro expansion of a form versus when it calls
MACROEXPAND again.  Or was this only an effiency hack, for macros that somehow
knew that memoization took longer than expanding them?

	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.  
I think I don't understand this; perhaps you could elaborate.  If a hash table
entry is absent, you call the expansion function, otherwise you don't.

      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.
That would be nice, but perhaps hard to do in general and consistently across
implementations.  Is there a way to leave room for it for the future?  (I wouldn't
like to do this by passing an extra argument which everyone is supposed to ignore!)

    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.
I don't see what advantage is gained by splitting the hook in half.  Don't forget
that Common Lisp provides a variety of built-in table mechanisms, including hash
tables, so the user doesn't have to implement the table lookup himself the way
he might in Maclisp.

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

Surely each implementation provides the default functions as the initial values
of these variables, rather than each implementation being required to test
explicitly for NIL in the variable.  Actually we could leave the implementation
free to do it either way, and guarantee nothing about the initial values except
that they provide a certain behavior.