Duane Rettig <duane@franz.com> wrote:
+---------------
| Marcus Breiing <expire-20050224@breiing.com> writes:
| > Now, the language about the reference to X causing undefined behavior
| > means that a binding for X in the evaluation environment doesn't have
| > to bind X to a value either.
|
| It's interesting and appropriate that you stated this in this way:
| "a binding ... does't have to bind ..." because that makes my job
| easier of explaining this second environment.
|
| Correct. X doesn't have a binding here, in this environment.
| ...
| > Thus, the Lisp may notice that, even though there may be a binding for
| > X (in any of our environments), it doesn't bind X to a _value_, and
| > emit an appropriate error.
|
| Agreed, if the binding in the evaluation environment is indeed unbound.
+---------------
This discussion reminds me of a very similar [or at least related] topic
that comes up from time to time, on whether DEFCONSTANT is required to
provide a value for the variable at compile time (it isn't, see [1]) as
opposed to merely noting that whenever the variable *does* eventually
have a value, it will be constant, so as to meet the contract between
DEFCONSTANT & CONSTANTP. As has been mentioned before, I bumped into
this with CMUCL while using macros originally written for LispWorks.[2]
Try compiling and loading the following small example and see what
*your* Lisp says:
(defconstant +foo+ 37)
(defmacro hack (x &environment e)
(if (constantp x e)
`(format t "~a"
,(with-output-to-string (s)
(format s "C: +foo+ type = ~s, +foo+ = ~s~%" (type-of x) x)))
`(format t "R: +foo+ type = ~s, +foo+ = ~s~%" (type-of ,x) ,x)))
(hack +foo+)
CMUCL prints: C: +foo+ type = SYMBOL, +foo+ = +FOO+
CLISP[3] prints: R: +foo+ type = FIXNUM, +foo+ = 37
LispWorks[4] prints: C: +foo+ type = FIXNUM, +foo+ = 37
Note that all three are technically legal[1,5], though only the last one
is useful for doing interesting partial evaluation at macroexpansion time.
-Rob
[1] CLHS "Macro DEFCONSTANT":
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.
Therefore, users must ensure that the initial-value can be evaluated at
compile time (regardless of whether or not references to name appear in
the file) and that it always evaluates to the same value.
[2] <http://www.cliki.net/htout>
[3] On a fairly-old version. Recent ones may differ.
[4] If I remember/understand what Tim told me several years ago.
[5] CONSTANTP may return NIL if "it cannot be determined [presumably in
that implementation --rpw3] whether or not form is a constant form".
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607