[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
overloading defstruct accessors
Date: Fri, 15 Jul 88 16:01:08 EDT
From: fritzson@PRC.Unisys.COM
The following example can be viewed as an attempt to overload the
accessor function "get-a" by making it access the "get-a" fields of
both a "foo" structure and a "bar" structure.
-------
(defstruct (foo (:conc-name ())) get-a)
(defstruct (bar (:conc-name ()) (:include foo)) get-b)
(setq afoo (make-foo :get-a 1))
(setq abar (make-bar :get-a 2 :get-b 3))
-------
One could argue that the second defstruct redefines the accessor
function "get-a" so that it will only work on bar-s. On the other
hand, it is relatively easy to implement this so that "get-a" will
work both on foos and bars.
Xerox Common Lisp (Lyric release) objects to
(get-a afoo)
by complaining that "afoo is not a bar". Franz Allegro Common Lisp
allows it. I haven't tried any other lisps.
Lucid Common Lisp originally (in Release 1.0) had the behavior you
describe in Xerox Common Lisp. This was changed in later releases so
that the GET-A defined by FOO is not replaced by the GET-A defined by
BAR. There is no structure slot access type checking in Franz Allegro
Common Lisp or MIT-derived Lisp Machines, other than making sure the
argument is an array whose length is greater than the index of the
slot being accessed.
Is there a consensus on what an implementation of Common Lisp should
do with this?
My personal opinion is that it is a bug for BAR to define GET-A such
that only objects of type BAR are allowed. It is easy to overlook
this problem, as I did until someone discovered it. It is too bad
(but probably not offically wrong) that many implementations of
DEFSTRUCT don't do any type checking. I think this is a legacy of
DEFSTRUCT's origin as "just a way to give mnemonic names to array
slots." For example, in Zetalisp the default was for DEFSTRUCTs to be
unnamed, rather like :TYPE VECTOR in CL.
-Rich Fritzson
ARPA: fritzson@prc.unisys.com
UUCP: {sdcrdcf,psuvax1,cbmvax}!burdvax!fritzson
P.S. Please, no complaints about the stylistic appropriateness of
using (:conc-name nil) in this way. This was written by someone who
should be using CLOS.