[Openmcl-devel] DEFSTRUCT and :INCLUDE

Tim Bradshaw tfb at tfeb.org
Sun Oct 11 11:22:37 UTC 2009


There has been some discussion on CLL about what happens with init  
forms for structures defined in lexical environments, particularly  
included structures.

I am not sure if the standard is precise enough about this, but I  
think CCL gets it "wrong" (where "wrong" means "not what I  
expected"...).  Consider something like this:

(let ((x 1))
   (defstruct bog
     (a x)))

I think that, clearly

(= (bog-x (make-bog)) 1)

Not what about this:

(defstruct (bat (:include bog))
   (b 3))

I think that the same thing should hold.  What CCL does is signal a  
warning at compile time, and an error at structure creation time.  In  
other words, what it's doing is reusing the source form from the  
included structure, not the compiled initform (which closes over X).

Now what about this:

(let ((x 4))
   (defstruct (fat (:include bog))
     (b 3)))

I think that (= (fat-x (make-fat)) 3) should hold, but now it is 4  
(presumably for the same reason as above).  This strikes me as  
incredibly counter-intuitive, which is why I think CCL is wrong here.

Finally:

(defstruct (splat (:include bog
                             (a 4)))
   (b 3))

CCL gets this right.

So I think there is some underlying issue that, when including a  
structure in another one, CCL is using the source of the initforms,  
when (I think) it needs to, at the point where the original structure  
is defined, stash a closure for the initform, which it can then call  
if the structure is included in another one.  It only actually *needs*  
to do this is there is a non-empty lexical environment, and I guess if  
that can be detected then it can safely reuse the source in most cases  
as that will probably make structure creation faster.

--tim



More information about the Openmcl-devel mailing list