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

Issue: LOAD-TIME-EVAL (Version 1)



    Date: 8 Jun 87 11:21 PDT
    From: Masinter.pa@Xerox.COM
    Proposal (SHARP-COMMA-SPECIAL-FORM:LOAD-TIME-EVAL)

I'm generally in favor of something like this proposal, but there are
several problems with the details.

LOAD-TIME-EVAL is presented as if it did the same thing as sharp-comma,
but they are rather different.  #, must appear inside a quoted constant,
at least in any compiler implementation I am familiar with, whereas
load-time-eval is a form and must not appear inside a quoted constant. 
This is not a fundamental problem, it's just confusing.

The remark "Load time evaluation at the top level is possible using
(EVAL-WHEN (LOAD) ... )" does not make any sense, as what that EVAL-WHEN
special form actually does is to inhibit evaluation when loading a file
into the interpreter; it does not cause something to be evaluated at a
different time.  I think the real lesson to be learned from this little
slip is that "load time evaluation" is a poor way of describing the
feature we are trying to get at here; the feature we really want is
load-time construction of constants.

It's not crystal clear how many times LOAD-TIME-EVAL evaluates its
subform and what is done with the result.  I believe the intention is
that `(foo (load-time-eval (bar))) is roughly like
`(foo (quote ,(bar))), which explains what is done with the result.
I'm not happy with the way I just explained it, but can't think of a
better way.  Can the subform be evaluated more than once in interpreted
code?

There are also four typographical errors in the example, or else I am
even more confused by the way it was explained than I thought.

    (defmacro call-method (spec &rest args)
	      `(apply
		  (load-time-eval 
		    (load-time-look-up-method ,spec))
		  ,args)))
should be
    (defmacro call-method (spec &rest args)
      `(funcall (load-time-eval 
		  (load-time-look-up-method ',spec))
		,@args))

It might be worth discussing the obvious other way of doing this, which
would be a function called by a macro, instead of a special form
included in the expansion of a macro.  I think this would have a closer
analogy to #,; in fact you just write , in your macro's backquote where
you would have written #, when using the reader macro.  The above
example would be written as follows:

    (defmacro call-method (spec &rest args &environment env)
      `(funcall (quote ,(make-load-time-eval
			  `(load-time-look-up-method ',spec)
			  env))
		,@args))

This is more verbose than the special-form way, but it may be clearer
what's going on, since there aren't any special forms.  The environment
is passed to make-load-time-eval because I don't see how else it is
supposed to know whether the form resulting from the macro expansion is
going to be compiled into a file or evaluated right away.  I'm not sure
we really want to adopt the make-load-time-eval approach, but I think
it may be worth discussing.

I also happen not to believe the stated usefulness of this for object
oriented programming, but that's irrelevant except that I might want to
suggest removing that from the proposal.  Certainly we all know that this
type of feature is highly useful.

In conclusion, I support the general idea but cannot support the particular
wording of the current version of the proposal.  When I started writing
this message, I was going to include a complete revision of the proposal,
but I have run out of energy.