Subject: Re: Separating evaluation and compilation environments.
From: (Rob Warnock)
Date: Tue, 11 Jan 2005 23:36:34 -0600
Newsgroups: comp.lang.lisp
Message-ID: <>
Duane Rettig  <> wrote:
| Marcus Breiing <> 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.



    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] <>

[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			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607