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

Issue COMPILER-LET-CONFUSION, v3



    Date: Mon, 2 Jan 89 00:13:53 PST
    From: Jon L White <jonl@lucid.com>

    COMPILER-LET has abundantly been demonstrated to generate immense
    confusion in the user community.  And the fact that its defenders have
    *no* convincing examples where this construct is either critical
    or suprememly better than the alternatives means it is simply a
    confusing hack.  It's rare uses hardly justify its enormous drawback.

Most uses of compiler-let i have seen (and often been responsible for)
have been maintaining a "stack" of data for some macrology to make use
of.  That is, it takes the general form
(defmacro with-new-frob (... &body body)
  (compiler-let ((*frobs* (cons '(,name . ,data) *frobs*)))
     ...)
and some other macro or macros reference *frobs*.

It is not obvious to me how to get macrolet to do something similar in a
straightforward and readable fashion.

It is the case that using compiler-let for things like this does not
have the correct behavior, because what I want is something which (1)
follows lexical scoping rules and (2) is available for analysis at
macroexpansion time.

If there were a facility which permitted user code to associate symbols
with data and have this associated with macroexpansion environments and
scoped in the normal lexical fashion, perhaps many of the uses of
compiler-let would be subsumed.

For instance:
(defmacro with-new-frob (... &body body &environment env)
  `(macrovar-let ((frobs '((,name . ,data) ,@(macrovar 'frobs env))))
    ,@body))
MACROVAR-LET is a special form syntactically like COMPILER-LET.  Instead of
binding those names to the given values however, the names are
associated with the values in such a way that macros expanded lexically
within the body can access the data by giving MACROVAR arguments of the
name, and their environment argumnet.  SETF should work on MACROVAR, but
should be an error if there is no "binding".

I believe CL could use this kind of functionality (perhaps as part of
syntactic-environment-access?).  I cannot see flushing compiler-let
unless something like this is provided.