Subject: Re: constantp values always available at macro expansion time?
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 11 Nov 2004 04:32:53 -0600
Newsgroups: comp.lang.lisp
Message-ID: <ZJadnf74lMdIog7cRVn-rA@speakeasy.net>
[Sorry for the late response... Work's been busy...]

Peter Seibel  <peter@javamonkey.com> wrote:
+---------------
| I have vague recollection of someone (Tim Bradshaw maybe) posting
| something about certain impls (CMUCL maybe?) not making constants
| available at compile time...
+---------------

Yeah, Tim & me both. I first ran into it [I use CMUCL, he doesn't] as
an issue with a certain version of Tim's HTOUT macros [circa Aug'03]
that attempted to do more aggressive compile-time constant aggregation
[e.g., collapsing (PROGN (WRITE "foo") (WRITE "bar")) into (WRITE "foobar"),
that sort of thing], and had a lengthy private sidebar with Tim that
led to his backing out part of the new optimization [or putting it under
feature test, I forget]. Then there was some discussion of it here in
May'04. See my article <news:EtmdnQsRh-rxxzbdRVn-gQ@speakeasy.net>
and nearby articles.

+---------------
| ...leading code like the following to behave badly when THING is
| a DEFCONSTANT'd constant:
|   (defmacro foo (thing)
|     `(print 
|        ,(if (constantp thing) (frob thing) `(frob ,thing))))
+---------------

Yup! That's exactly the scenario which can break in CMUCL, if THING
is a symbol defined with DEFCONSTANT (though it works if THING is
a keyword symbol).

+---------------
| Before I go try to track the whole thing down in Google, I was
| wondering if someone who was involved could give me the executive
| summary of the "resolution"--e.g. "everyone" agreed that such impls
| are either conformant or non-conformant or everyone just agreed to
| disagree.
+---------------

Well, despite any concensus of what the standard *should* have said,
IMHO most agreed that what it *actually* says is that CMUCL *is*
conformant. The problem is that the CLHS requires that:

    ...symbols declared as constant by the user in the indicated
    environment using DEFCONSTANT are always considered constant forms
    and must be recognized as such by CONSTANTP.

yet does *NOT* require that the *value* of such a symbol be available
at compile time [emphasis added]:

    If a defconstant form appears as a top level form, the compiler must
    recognize that name names a constant variable. AN IMPLEMENTATION MAY
    CHOOSE TO EVALUATE THE VALUE-FORM AT compile time, LOAD TIME, or both.

This means that CONSTANTP cannot portable & reliably be used to tell
whether a value is available at compile time, even if it is known to
be "constant".

Does that answer your question? [...or at least give you a place to
start Googling?]


-Rob

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