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

Re: DEFMETHOD compile-time processing



> The general issue that we try to address is that it should be possible for
> some implementations to precompute a certain number of characteristic of CLOS
> programs at compile-file time. These precomputation involve metaobjects
> (looking at user class definitions, method object, generic functions) in a
> state that should be close enough to their state when the program is loaded in
> the remote environment. It is not generally possible to simulate the remote
> environment as far as running remote code. Therefore, precomputation at
> compile time, by doing metaprogramming on remote environment objects is more
> restrictive that doing metaprogramming on local environment objects. However,
> we don't want to introduce two distinct metaprogrammings. Chapter 3 is trying
> to unify remote and local metaprogramming. All the side effect that are done
> when the program is loaded, is simulated in the remote environment(
> Add-method, ensure-class...).

I think I see the principle you're presenting here, but I'm still not
clear on how it applies to this case.  The calls to MAKE-METHOD-LAMBDA and
ADD-METHOD are done by the implementation of the DEFMETHOD macro or its
expansion, and the Meta-Object Protocol doesn't specify any intermediate
points at which the user can get involved.  Under what circumstances would
the user know or care whether the compiler called ADD-METHOD?  Sure, I
suppose that a macro could use ENSURE-GENERIC-FUNCTION to look up the
compile-time definition, invoke FIND-METHOD or GENERIC-FUNCTION-METHODS,
and then look at the method objects, but is there really any reason to
want to do that?  Given the precedent that certain operations are not
valid on uninitialized objects or un-finalized classes, who would be hurt
if we said that FIND-METHOD and GENERIC-FUNCTION-METHODS were not valid on
generic functions in the remote environment?

Looking some more at pages 3-16 and 3-17, I think it's interesting that it
doesn't really say anything about compilation, just about the side effects
of what the compiler does.  Presumably the lambda expression computed at
compile time by MAKE-METHOD-LAMBDA is compiled, and the resulting compiled
function is what is actually used in the run-time call to MAKE-INSTANCE
for the method.

There appears to be an additional problem, though, in that the
compile-time call to MAKE-METHOD-LAMBDA depends on the result of
GENERIC-FUNCTION-METHOD-CLASS, yet it is specified that
GENERIC-FUNCTION-METHOD-CLASS is called again at load time.  If we can't
assume that the value will be the same, then what does that say about the
validity of the compiled method function?  It looks like either you don't
want to do it again at load time, or else you do it again in order to
signal an error if it doesn't match the compile-time value.

Also aside from the question of lexical environments is the issue of
control flow context.  There has been discussion in the compiler committee
that seems to have come to the conclusion that we don't want things like
DEFMACRO side-effecting the compile-time environment if they are embedded
in a function or conditional such that they really happen at some
indeterminate run time rather than when the file is loaded.  The same
consideration would apply to DEFCLASS, DEFGENERIC, and DEFMETHOD.  This
requires being able to conceptually separate the actions needed to compile
the run-time code from the actions simulating what happens at load time.

And yet another issue:  if the user says

  (EVAL-WHEN (EVAL COMPILE LOAD)
    (DEFMETHOD ...))

because he really does want to call that generic function from one of his
macros, does that mean that the compile-time ADD-METHOD in this case needs
to be to the resident installed definition instead of the remote
environment?  Or is this not legal?