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

defstruct, and the :named option

I have developed the impression that the issue concerning the :named
option to make-array is misguided.  The object is to be able to have
defstruct produce implementation-independent code for the important
default case where the structure is typed.  To specify that this is
necessarily within the domain of arrays is needlessly constraining.

There are three basic functions needed to define a typed structure.
One must define the type, create a structure, and reference the
structure.  The type definition may be done with define-structure:

(define-structure <name> <size> [<included-structure-type>]).

This is a macro, which expands into whatever is needed by the
implementation to actually define <name> so that it may be used as a
type specifier, and for its use with make-structure.  The "arguments"
are not evaluated.  For instance, the astronaut defstruct in the Laser
edition would produce
(define-structure astronaut <size> person).

(make-structure <name> <size>)

creates an empty (uninitialized?) structure for <name>.  Perhaps
<size> is not really needed here, but would save looking up <name> in
implementations where no other information is needed.

(structure-ref <structure> <index>)

returns the <index>th slot of <structure>, and works with setf.  The
indexing is zero origined.  Obviously the compiler can increment the
index if it is a compile-time constant and that is necessary for the
implementation.  Checking for such things as :read-only, and hacking
with types (in whatever way), are done by defstruct before the
structure-ref stage is reached.
Additional changes/documentation modifications:

The :named vector type should be specified as not necessarily being
the same as the normal typed structure type, and thus probably not
distinguishable with typep.  It may not be different, however, 
depending on the implementation!

The predicate defined by the :predicate option should be documented as
being only a heuristic unless the structure is defined in the default
manner.  (Should there be a name for this default :type?  How about
:typed?  :typed-structure?  Just :structure?)

The vector type should NOT be :named by default.

The :unnamed option should be eliminated.  It only makes sense for the
explicitly specified types (list and vector), which are not named by
default.  (Additionally, if the vector has an element-type specified,
it may not, in fact probably will not, be possible to make the vector
be :named.  The documentation should point this out, if not make
:named illegal for all but (vector t).)

:initial-offset ???  Presumably this is more reasonable than ever if
we have structure-ref.  It might be a good idea to define the order in
which defstruct allocates slots for linear structures (which all of
the Common-Lisp ones are, since there is no :type :tree).
There are a couple alternatives for make-structure which might want to
be considered.  For instance, it may be reasonable for make-structure
to be given a template structure to initialize the created structure
to.  That way, constant slot initializations will have been done at
structure creation type.  This is beneficial in implementations where
data creation needs for some reason or another to initialize the
contents to something.  We use this in NIL for flavor instance
initialization now;  it speeds things up measurably.  If this kind of
thing is added, then possibly the size and/or name might not need to
be given to make-structure.  My feeling, however, is that the cleanest
and safest interface would be for a template to be an optional third
argument to make-structure, and be of type (simple-vector t).

Another possibility is for make-structure to take an &rest argument
which specifies the slot initializations, in order.  This would have
the advantage of not forcing defstruct to produce a string of setfs to
do the initializations.