[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: problem with defstruct



Bjoern Hoefling <hoefling@dfki.uni-kl.de> points out a problem that occurs
when using DEFSTRUCT with :INCLUDE option and the same :CONC-NAME for both
structures:

| > (defstruct (object (:conc-name object-) (:predicate object?))
|     (reference    'NUNA)
|   )
| OBJECT

| > (setq a (make-object))
| #S(OBJECT :REFERENCE NUNA)

| > (object-reference a)
| NUNA

| > (defstruct (unknown (:predicate unknown?) (:conc-name object-)
|                       (:include object)
|              )
|     (abstract-functions   nil :type list)
|   )
| UNKNOWN

| > (object-reference a)
| 
| *** - SYSTEM::%STRUCTURE-REF: #S(OBJECT :REFERENCE NUNA) ist keine
| Structure vom Typ UNKNOWN.
| 1. Break> 

By executing the second DEFSTRUCT form, you have in fact redefined the
function OBJECT-REFERENCE. The first one accepted all structures of
type OBJECT, the second one only those which have the additional slot
ABSTRACT-FUNCTIONS.

Your code is not covered by CLtL, and it breaks under both
CLISP and CMUlisp.

Correct it. Either

a) Use another CONC-NAME for the including strcutures,

or

b) Repeat the first DEFSTRUCT form after the second. If you have a tree
   of including structures, you must repeat all the non-leaves in an
   leaf-to-root order. For example, change
     (defstruct a ...)
     (defstruct (b (:include a)) ...)
     (defstruct (c (:include b)) ...)
     (defstruct (d (:include c)) ...)
     (defstruct (e (:include b)) ...)
   to
     (defstruct a ...)
     (defstruct (b (:include a)) ...)
     (defstruct (c (:include b)) ...)
     (defstruct (d (:include c)) ...)
     (defstruct (e (:include b)) ...)
     (defstruct (c (:include b)) ...)
     (defstruct (b (:include a)) ...)
     (defstruct a ...)


Bruno Haible
haible@ma2s2.mathematik.uni-karlsruhe.de