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

Re: draft of alternate proposal for EVAL-WHEN-NON-TOP-LEVEL



    Date: Tue, 7 Mar 89 10:29:19 MST
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)

    > Should we include forms within the body of a top-level MACROLET?  This
    > seems reasonable.  What about LOCALLY?  This also seems reasonable,
    > modulo the question of whether LOCALLY is a macro or a special form.
    > Is this a slippery slope?

    I think we reached consensus at the last meeting that both MACROLET and
    SYMBOL-MACROLET should pass through toplevelness.

I thought so too (but I might have thought that only because it was
my own position :-).

    LOCALLY is still a sticky issue.  I tend to agree with JonL that since
    it can add things like SPECIAL declarations to the environment, its
    body should never be considered toplevel. 

Here is the criterion I prefer to use: a form is non-top-level if its
lexical environment cannot be fully constructed at compile time or if it
is not manifestly executed at load time exactly once.  In other words,
the form is enclosed in a variable binding, a block, a tagbody, a loop,
or a conditional.  The reason I prefer this criterion is that it is
directly related to the reason we have the kludge of top-level forms in
the language in the first place: compile-file's modelling at compile
time of the actions that will occur at load time.

A lexical environment consists of variables, functions, blocks, go tags,
and declarations.  Variables, blocks, and go tags cannot be fully
constructed at load time.  Declarations can be fully constructed at
compile time, and functions can also be, unless the definition is a
closure that cannot be fully constructed at compile time; but the way
lexical environments nest in Common Lisp prevents that case from arising
except when the lexical environment of the binding already cannot be
fully constructed at compile time.  I think function bindings being
fully constructable at compile time depends on the illegality of using
setf to alter a local function binding, otherwise function bindings
would be just like variable bindings.

Since what LOCALLY adds to the lexical environment can be fully
constructed at compile time, its body should be top-level.

We have tacitly chosen to rule out smart compilers that prove a form is
effectively top-level when a naive compiler might think it was
non-top-level.  For example, we require all compilers to treat the defun
in
  (let ((x 1))
    (defun foo (y)
      (expt y 2)))
as non-top-level even though a smart compiler might discover that the
binding of x is irrelevant.  Similarly we don't allow a smart compiler
to discover that what appears to be a loop is actually executed exactly
once and treat the forms in its body as top-level.  Similarly we don't
allow a smart compiler to "optimize"
(eval '(defun ...)) into (defun ...).  I think this was a good decision.

We seem to have added an additional criterion, which is that a form is
non-top-level if its value is used.  This means any form that is an
argument to a function, as well as forms appearing in certain special
forms such as DEFPARAMETER, are non-top-level.  I think that criterion
may be unnecessary but I have no objection to it.  I suspect the reason
for this criterion is nothing more profound than that it allows LOAD's
implementation of the top-level forms to not produce values and hence
to not be nestable inside other top-level forms.