Subject: Re: Manipulating macro parameters
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 23 May 2006 05:22:38 -0500
Newsgroups: comp.lang.lisp
Message-ID: <qrCdnevYIoDzf-_ZRVn-uQ@speakeasy.net>
Christophe Rhodes  <csr21@cam.ac.uk> wrote:
+---------------
| rpw3@rpw3.org (Rob Warnock) writes:
| > p.s. Or for a very slight performance gain:
| >     (intern (concatenate 'string (symbol-name x)
| > 				 (load-time-value (symbol-name :bar))))
| 
| This (the addition of load-time-value) looks like a performance loss
| to me.  Symbols' symbol-name never changes, so any compiler worth its
| salt will constant-fold calls to symbol-name with a constant argument;
| however, load-time-value is not foldable in general (surprising things
| can be done with make-load-form) though it probably is in this case,
| so it will be executed every time for a definition of this macro which
| is compiled but not file-compiled.
+---------------

Hmmm... I'm not sure that's correct. The CLHS for "LOAD-TIME-VALUE" says:

    If a LOAD-TIME-VALUE expression appears within a function
    compiled with COMPILE, the form is evaluated at compile time in
    a null lexical environment. The result of this compile-time
    evaluation is treated as a literal object in the compiled code.

How can a literal object be "executed every time"?

Now if it's not even *compiled*, then it certainly *might* be
evaluated every time, but even that is not mandated:

    If a LOAD-TIME-VALUE expression is processed by EVAL, "form" is
    evaluated in a null lexical environment, and one value is returned.
    Implementations that implicitly compile (or partially compile)
    expressions processed by EVAL might evaluate "form" only once,
    at the time this compilation is performed.

Finally, I just noticed that in the particular case we're discussing,
it would probably be desirable to specify the optional READ-ONLY-P
argument as T, in the hopes that that would encourage sharing and/or
single-evaluation:

    "Read-only-p" designates whether the result can be considered a
    constant object. If T, the result is a read-only quantity that can,
    if appropriate to the implementation, be copied into read-only space
    and/or "coalesced" with similar constant objects from other programs.
    If NIL (the default), the result must be neither copied nor coalesced;
    it must be considered to be potentially modifiable data.

That is:

    (load-time-value (symbol-name :bar) t)

[And yes, I understand that the string that SYMBOL-NAME returns
is already supposed to be treated as immutable, but specifying
READ-ONLY-P as T at least tells the compiler you're promising
to honor that. I'm not sure this is needed, but it might help
with some compiler(s).]


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607