From: Hallvard Traetteberg
Subject: compile and defconstant
Date: 
Message-ID: <HALTRAET.91Nov19094815@safir.ibt.unit.no>
I'm trying to make a constant list of one element, with both the cons
and element "bound" to a constant-symbol:

(defconstant *elt*     (make-struct ...))
(defconstant *elt-cons (list *elt*))
(defun eq-test () (eq (car *elt-cons*) *elt*))

After compiling the above (eq-test) gives NIL, while after evaling the
same call returns T. Of course I agree with the latter. I have tried
using defvar and defparameter instead and it works. I feel however, that
defconstant is what I really nead. I looked in CLtL 2, and didn't quite
understand the phrase "the value in the defconstant form should always
evaluate to the same, whether evaled at eval, load and/or compile time"
[not a direct quote].

I'm using CMUCL and wonder whether I'm wrong or they are.
--

                                                           - hal
From: Rob MacLachlan
Subject: Re: compile and defconstant
Date: 
Message-ID: <1991Nov20.184212.295281@cs.cmu.edu>
In article <······················@safir.ibt.unit.no> ········@safir.ibt.unit.no (Hallvard Traetteberg) writes:
>I'm trying to make a constant list of one element, with both the cons
>and element "bound" to a constant-symbol:
>
>(defconstant *elt*     (make-struct ...))
>(defconstant *elt-cons (list *elt*))
>(defun eq-test () (eq (car *elt-cons*) *elt*))
>
>After compiling the above (eq-test) gives NIL, while after evaling the
>same call returns T. Of course I agree with the latter. I have tried
>using defvar and defparameter instead and it works. I feel however, that
>defconstant is what I really nead. I looked in CLtL 2, and didn't quite
>understand the phrase "the value in the defconstant form should always
>evaluate to the same, whether evaled at eval, load and/or compile time"

The use of non-EQL-comparable values in defconstants is rather poorly defined.
Named constant evaluation is supposed to be EQL preserving (presumably
implemented via a SYMBOL-VALUE call at run-time.)  And when a DEFCONSTANT
definition is re-evaluated, the new value is required to be the "same" as the
old.  But if "same" means EQL, then this is virtually impossible for lists,
etc.  And if "same" means similar-as-a-constant, then EQL-preservation might be
violated.

>
>I'm using CMUCL and wonder whether I'm wrong or they are.

In the alpha version I am running, the body of EQ-test is constant-folded to T.
I don't know why it returns NIL for you, but in looking at the compiler, I did
fix a case where EQLness would not being preserved.  

In any case, the possibly of constant-folding raises a bunch of nasty issues.
Suppose EQ-TEST was partially constant-folded to:
  (eq #S(STRUCT ...) *ELT*)

Is the compiler supposed to recognize that #S(STRUCT ...) is a substructure of
a named constant, and thus preserve EQLness for it too?  This is impractical,
so if EQLness is to be preserved, the only possible conclusion is that:
    You can't constant-fold expressions of named constants.

which is counter-intuitive, to say the least.

I think that the whole idea of named constant EQL preserving was a mistake
coming from the semantics of the old LISPM DEFCONST (which was really
DEFPARAMETER), combined with the lack of the concept of similar-as-a-constant.
The defconstant value should be similar-as-a-constant, and leave it at that.

  Rob