.c -*-Bolio-*-

.chapter "Defstruct"
.setq defstruct-page page

.section "Introduction"

	This chapter is a modification of the description of
3defstruct* appearing in the Maclisp Extensions Manual
ref{Maclisp-Extensions}.  There are three sorts of changes:
.table 2 250 250 0 0 0
.item (1)
Deletion of topics not applicable to lan{nil};
.item (2)
Deletion of things which do not yet work in lan{nil};
.item (3)
Modifications of the defaults, as the lan{nil} 3defstruct* is
intended to be upwards-compatible with the lan{common lisp}
3defstruct*.
.end_table
For these reasons, some of the
wording may seem a bit strange, in that the original document is
concerned with helping users write code compatible in differing Lisp
implementations.  3defstruct* is part of the lan{common lisp}
standard (but not all the parts of it), and the documentation on it
will be fixed in the future.  Any inaccuracies in this modification of
it are purely the fault of GSB.

	The keywords which are used in 3defstruct* are all
interned in the keyword package, just like other keywords in
lan{nil}.  For compatibility with lan{maclisp} programs, however,
3defstruct* will accept those 2not* in the keyword package.
Conversely, the lan{maclisp} defstruct will check for symbols which
have a leading ":" in their names.  In lan{nil}, one should use the
colons for stylistic consistency.

.section "A Simple Example"
.setq example-section-page section-page

.defmac defstruct
3defstruct* is a macro defining macro.  The best way to explain
how it works is to show a sample call to 3defstruct*, and then to show
what macros are defined and what each of them does.
.end_defmac

Sample call to 3defstruct*:
.lisp
(defstruct (elephant (:type :list))
  color
  (size 17.)
  (name (gensym)))
.end_lisp
This form expands into a whole rat's nest of stuff, but the effect is
to define five macros: 3elephant-color*, 3elephant-size*,
3elephant-name*, 3make-elephant* and 3alter-elephant*.
Note that none of these symbols appeared in the original form,
they were created by 3defstruct*.  The definitions of 3color*,
3size* and 3name* are easy, they expand as follows:
.lisp
(elephant-color x) ==> (car x)
(elephant-size x)  ==> (cadr x)
(elephant-name x)  ==> (caddr x)
.end_lisp

You can see that 3defstruct* has decided to implement an elephant as a
list of three things; its color, its size and its name.  The
expansion of 3make-elephant* is
somewhat harder to explain, let's look at a few cases: 
.lisp
(make-elephant)		      ==>  (list nil 17. (gensym))
(make-elephant :color 'pink)  ==>  (list 'pink 17. (gensym))
(make-elephant :name 'fred :size 100)
			      ==>  (list nil 100 'fred)
.end_lisp

	As you can see, 3make-elephant* takes a "setq-style" list of
part names and forms, and expands into a call to 3list* that
constructs such an elephant.  Note that the unspecified parts get defaulted
to pieces of code specified in the original call to 3defstruct*.
Note also that the order of the setq-style arguments is ignored in
constructing the call to 3list*.  (In the example, 3100* is
evaluated before 3'fred* even though 3'fred* came first in the
3make-elephant* form.)  Care should thus be taken in using code with
side effects within the scope of a 3make-elephant*.  (This
particular behaviour will be "fixed" by lan{common lisp}, but has
not yet been worked into lan{nil}.)  Finally, take note
of the fact that the 3(gensym)* is evaluated 2every time* a new
elephant is created (unless you override it).

	The explanation of what 3alter-elephant* does is delayed until
(alterant-section-page).

	So now you know how to construct a new elephant and how to examine
the parts of an elephant, but how do you change the parts of an already
existing elephant?  The answer is to use the 3setf* macro
((setf-section-page)).
.lisp
(setf (name x) 'bill)	==> (rplaca (cddr x) 'bill)
.end_lisp
which is what you want.

	And that is just about all there is to 3defstruct*; you now know
enough to use it in your code, but if you want to know about all its
interesting features, then read on.

.section "Syntax of defstruct"
.setq syntax-section-page section-page

	The general form of a 3defstruct* form is:
.lisp
(defstruct (2name* 2option-1* 2option-2* ... 2option-n*)
  2slot-description-1*
  2slot-description-2*
  ...
  2slot-description-m*)
.end_lisp

	2name* must be a symbol, it is used in constructing names
(such as "make-elephant") and it is given a 3defstruct-description* property
of a structure that describes the structure completely.

	Each 2option-i* is either the atomic name of an option, or a
list of the form 3(2option-name* 2arg* . 2rest*)*.  Some
options have defaults for 2arg*; some will complain if they are
present without an argument; some options complain if they are present
2with* an argument.  The interpretation of 2rest* is up to the option
in question, but usually it is expected to be 3nil*.

	Each 2slot-description-j* is either the atomic name of a
slot in the structure, or a list of the form 3(2slot-name*
2init-code*)*, or a list of byte field specifications.
2init-code* is used by constructor macros (such as 3make-elephant*) to
initialize slots not specified in the call to the constructor.  If the
2init-code* is not specified, then the slot is initialized to
whatever is most convenient. (In the 3elephant* example, since the
structure was a list, 3nil* was used.  If the structure had been a
fixnum array, such slots would be filled with zeros.)

	A byte field specification looks like: 3(2field-name*
2bytespec*)* or 3(2field-name* 2bytespec*
2init-code*)*.  Note that
since a byte field specification is always a list, a list of byte
field specifications can never be confused with the other cases of a
slot description.  The byte field feature of 3defstruct* may be
undergoing change in lan{nil} due to the incompatible change of
bytespec format (see (byte-manipulation-section-page)), so is
discouraged for the present.

.section "Options to defstruct"
.setq options-section-page section-page

	The following sections document each of the options
3defstruct* understands in detail.

	On the Lisp Machine and in lan{nil}, all these
3defstruct* options are
'cindex packages
interned on the keyword package.

.subsection ":type"
.setq type-section-page section-page

	The 3:type* option specifies what kind of lisp object
3defstruct* is going to use to implement your structure, and
how that implementation is going to be carried out.  The
3:type* option is illegal without an argument.  If the 3:type*
option is not specified, then 3defstruct* will choose an appropriate
default:  in lan{nil}, 3defstruct* will implement the structure
as a vector-like object, which will be defined as a type whose name is
the name given to 3defstruct*.  One can then check for objects of
this type with 3typep*.  (This differs from the way
3defstruct* 2currently* operates in lan{maclisp} and
lan{lispm}.)  It is possible for the user to teach
3defstruct* new ways
to implement structures, the interested reader is referred to
(extension-section-page), for more information.  Many useful types
have already been defined for the user.  A table of these "built in"
types follows: (On the Lisp Machine and in lan{nil} all defstruct type
names are interned
'cindex packages
on the keyword package.)

.defstruct_type :list "All implementations"
Uses a list.  This is the default in lan{multics maclisp}.
.end_defstruct_type

.defstruct_type :named-list "All implementations"
Like 3:list,* except the car of each instance of this structure will
be the name symbol of the structure.  This is the only "named"
structure type defined on Multics and is the default named type there.
(See the 3:named* option documented in (named-section-page).)
.end_defstruct_type

.defstruct_type :tree "All implementations"
Creates a binary tree out of conses with the slots as leaves.  The
theory is to reduce car-cdring to a minimum.  The 3:include*
option ((include-section-page)) does not work with
structures of this type.
.end_defstruct_type

.defstruct_type :list* "All implementations"
Similar to 3:list*, but the last slot in the structure will be
placed in the cdr of the final cons of the list.  Some people call
objects of this type "dotted lists".  The 3:include*
option ((include-section-page)) does not work with
structures of this type.
.end_defstruct_type

.defstruct_type :array "All implementations"
Uses an array object (2not* a symbol with an array property).
This is the default on Lisp Machines.  Eventually, many of the same
hairy array options which 3defstruct* supports on the Lisp Machine
will be supported in lan{nil};  until the new array scheme is
implemented, however, lan{nil} users are advised to use
3:vector* instead.
.end_defstruct_type

.defstruct_type :sfa "PDP-10 MacLisp and NIL"
Uses an SFA.  The constructor macros for this type accept the keywords
3:sfa-function* and 3:sfa-name*.  Their arguments (evaluated, of
course) are used, respectively, as the function and the printed
representation of the SFA.  See also the 3:sfa-function*
((sfa-function-section-page)) and 3:sfa-name*
((sfa-name-section-page)) options.  (SFAs are available in
lan{nil} for compatibility with lan{pdp-10 maclisp}.  They should
not normally be used, and are not documented in the lan{nil} manual.)
.end_defstruct_type

.defstruct_type :vector "PDP-10 MacLisp and NIL"
Uses an vector.  This will be a simple-vector.
.end_defstruct_type

.defstruct_type :named-vector "PDP-10 MacLisp and NIL"
Like vector, except element number 0 always contains the name symbol
of the structure.  Note that this is 2not* the default 2named*
type in lan{nil}, 3:extend* is.
.end_defstruct_type

.defstruct_type :extend "NIL only"
.setq defstruct-extend-type-section-page section-page
This is the default named type in lan{nil}.  Normally you don't need
to know that it has this weird name, because this has been the default
defstruct type if 3:named* is specified for a while, and it is now
the default type period.  See also the 3:class-symbol* option
((class-symbol-section-page)).
.end_defstruct_type

.c .defstruct_type :fixnum "All implementations"
.c This type allows one to use the byte field feature of 3defstruct* to
.c deal symbolically with fixnums that aren't actually stored in any
.c structure at all.  Essentially, a structure of type 3:fixnum* has exactly
.c one slot.  This allows the operation of retrieving the contents of
.c that slot to be optimized away into the identity operation.  See
.c (byte-field-section-page) for more information about byte
.c fields.
.c .end_defstruct_type
.c 

.subsection ":constructor"
.setq constructor-section-page section-page

	The 3:constructor* option specifies the name to be given to the
constructor macro.  Without an argument, or if the option is not
present, the name defaults to the concatenation of "make-" with the
name of the structure.  If the option is given with an argument of
3nil*, then no constructor is defined.  Otherwise the argument is the
name of the constructor to define.  Normally the syntax of the
constructor 3defstruct* defines is:
.lisp
(2constructor-name*
    2keyword-1* 2code-1*
    2keyword-2* 2code-2*
    ...
    2keyword-n* 2code-n*)
.end_lisp

	Each 2keyword-i* must be the name of a slot in the
structure, or one of the special keywords allowed for the particular
type of structure being constructed.  All of these keywords are
symbols interned in the keyword package, although for
upwards-compatibility (this is new behaviour) that is not required.
For each keyword that is the name of a slot, the constructor expands
into code to make an instance of the structure using 2code-i* to
initialize slot 2keyword-i*.  Unspecified slots default to the
forms given in the original 3defstruct* form, or, if none was
given there, to some convenient value such as 3nil* or 30*.

	For keywords that are not names of slots, the use of the
corresponding code varies.  Usually it controls some aspect of the
instance being constructed that is not otherwise constrained.  The
only one of these which is used in lan{nil} is the
3:sfa-function* option ((sfa-function-section-page)).

	If the 3:constructor* option is given as
3(:constructor 2name* 2arglist*)*, then instead of making a keyword
driven constructor, 3defstruct* defines a "function style" constructor.
The 2arglist* is used to describe what the arguments to the
constructor will be.  In the simplest case something like
3(:constructor make-foo (a b c))* defines 3make-foo* to be a three
argument constructor macro whose arguments are used to initialize the
slots named 3a*, 3b* and 3c*.

	In addition, the keywords 3&optional*, 3&rest* and
3&aux* are recognized in the argument list.  They work in the way
you might expect, but there are a few fine points worthy of
explanation:
.lisp
(:constructor make-foo
	(a &optional b (c 'sea) &rest d &aux e (f 'eff)))
.end_lisp
This defines 3make-foo* to be a constructor of one or more
arguments.  The first argument is used to initialize the 3a* slot.
The second argument is used to initialize the 3b* slot.  If there
isn't any second argument, then the default value given in the body of
the 3defstruct* (if given) is used instead.  The third argument is
used to initialize the 3c* slot.  If there isn't any third argument,
then the symbol 3sea* is used instead.  The arguments from the
fourth one on are collected into a list and used to initialize the
3d* slot.  If there are three or less arguments, then 3nil* is
placed in the 3d* slot.  The 3e* slot is 2not initialized*.
It's value will be something convenient like 3nil* or 30*.  And
finally the 3f* slot is initialized to contain the symbol 3eff*.

	The 3b* and 3e* cases were carefully chosen to allow the
user to specify all possible behaviors.  Note that the 3&aux*
"variables" can be used to completely override the default
initializations given in the body.

	Since there is so much freedom in defining constructors this
way, it would be cruel to only allow the 3:constructor* option to be
given once.  So, by special dispensation, you are allowed to give the
3:constructor* option more than once, so that you can define several
different constructors, each with a different syntax.

	Note that even these "function style" constructors do not currently
guarantee that their arguments will be evaluated in the order that you
wrote them.

.subsection ":alterant"
.setq alterant-section-page section-page

	The 3:alterant* option defines a macro that can be used to
change the value of several slots in a structure together.  Without an
argument, or if the option is not present, the name of the alterant
macro defaults to the concatenation of "alter-" with the name of the
structure.  If the option is given with an argument of 3nil*, then
no alterant is defined.  Otherwise the argument is the name of the
alterant to define.  The syntax of the alterant macro 3defstruct*
defines is:
.lisp
(2alterant-name* 2code*
   2slot-name-1* 2code-1*
   2slot-name-2* 2code-2*
   ...
   2slot-name-n* 2code-n*)
.end_lisp
2code* should evaluate to an instance of the structure, each
2code-i* is evaluated and the result is made to be the value of slot
2slot-name-i* of that structure.  The slots are all altered in
parallel after all code has been evaluated.  (Thus you can use an
alterant macro to exchange the contents to two slots.)  As for the
keyworded constructor macro, the 2slot-name-i* should be symbols
interned in the keyword package, although (again) that is not required.
.break
Example:
.lisp
(defstruct (lisp-hacker (:type :list)
			:conc-name
			:default-pointer
			:alterant)
  (favorite-macro-package nil)
  (unhappy? t)
  (number-of-friends 0))

(setq lisp-hacker (make-lisp-hacker))
.end_lisp
Now we can perform a transformation:
.lisp
(alter-lisp-hacker lisp-hacker
	favorite-macro-package 'defstruct
	number-of-friends 23.
	unhappy? nil)

==> ((lambda (G0009)
       ((lambda (G0011 G0010)
	  (setf (car G0009) 'defstruct)
	  (setf (caddr G0009) G0011)
	  (setf (cadr G0009) G0010))
	23.
	nil))
     lisp-hacker)
.end_lisp

	Although it appears from this example that your forms will be
evaluated in the order in which you wrote them, this is not currently
guaranteed.

	Alterant macros are particularly good at simultaneously
modifying several byte fields that are allocated from the same word.
They produce better code than you can by simply writing consecutive
3setf*s.  They also produce better code when modifying several slots of
a structure that uses the 3:but-first* option
((but-first-section-page)).

	For 3defstruct* types whose accessors take more than one
argument, all of those arguments must be supplied to the alterant
macro in place of just the usual one.
(See (multi-arg-accessors-section-page) for how accessors
with more than one argument can come to be, there are no built-in
3defstruct* types with this property.)

.subsection ":named"
.setq named-section-page section-page

	This option tells 3defstruct* that you desire your structure to
be a "named structure".  In lan{pdp-10 maclisp} this means you want
your structure implemented with a 3:named-hunk*, 3:named-list*
or 3:named-vector*.  On a Lisp Machine this indicates that you
desire either a 3:named-array* or a 3:named-array-leader* or a
3:named-list*.  On Multics this indicates that you desire a
3:named-list*.  In lan{nil} this indicates that you desire a
3:extend*, a 3:named-vector* or a 3:named-list*.
3defstruct* bases its decision as to what named type to use on
whatever value you did or didn't give to the 3:type* option;  in
lan{nil}, the default named type is 3:extend*, and 3:named*
is the default--the significance of this was explained in
(type-section-page).  It is an error to use this option with an
argument.

.subsection ":predicate"
.setq predicate-section-page section-page

	The 3:predicate* option causes 3defstruct* to generate a
predicate to recognize instances of the structure.  Naturally it only
works for some 3defstruct* types.  Currently it works for all the
named types as well as the types 3:sfa* (lan{pdp-10 maclisp} and
lan{nil} only) and 3:extend* (lan{nil} only).  The argument to
the 3:predicate*
option is the name of the predicate.  If it is present without an
argument, then the name is formed by concatenating "-p" to the end of
the name symbol of the structure.  If the option is not present, then
no predicate is generated.  Example:
.lisp
(defstruct (foo :named :predicate)
  foo-a
  foo-b)
.end_lisp
defines a single argument function, 3foo-p*, that is true only of
instances of this structure.

.subsection ":print"
.setq print-section-page section-page

	The 3:print* option allows the user to control the printed
representation of his structure in an implementation independent way:
.lisp
(defstruct (pair :named
		 (:print "{~S . ~S}"
			 (pair-first pair)
			 (pair-second pair)))
  pair-first
  pair-second)
.end_lisp

	The arguments to the 3:print* option are used as if they were
arguments to the 3format* function ((format-fun)), except that the
first argument (the stream) is omitted.  They are evaluated in an
environment where the name symbol of the structure (3pair* in this
case) is bound to the instance of the structure to be printed.

	This option presently only works on Lisp Machines and in lan{nil},
using the 3defstruct* types 3:named-array* and 3:extend*
respectively.  We hope to make it work in lan{pdp-10 maclisp} for the
3:named-hunk* type soon.  In lan{multics maclisp}, this option is
ignored.  Notice that if you just specify the 3:named* option without
giving an explicit 3:type* option, each 3defstruct* implementation
will default to a named type that can control printing if at all
possible.

.subsection ":default-pointer"
.setq default-pointer-section-page section-page

	Normally the accessors are defined to be macros of exactly one
argument.  (They check!)  But if the 3:default-pointer* option is present
then they will accept zero or one argument.  When used with one
argument, they behave as before, but given no arguments, they expand
as if they had been called on the argument to the 3:default-pointer*
option.  An example is probably called for:
.lisp
(defstruct (room (:type :tree)
		 (:default-pointer **current-room**))
  (room-name 'y2)
  (room-contents-list nil))
.end_lisp
Now the accessors expand as follows:
.lisp
(room-name x)		==> (car x)
(room-name)		==> (car **current-room**)
.end_lisp

If no argument is given to the 3:default-pointer* option, then the
name of the structure is used as the "default pointer".
3:default-pointer* is most often used in this fashion.

.subsection ":conc-name"
.setq conc-name-section-page section-page

	Frequently all the accessor macros of a structure will want to
have names that begin the same way; usually with the name of the
structure followed by a dash.  The 3:conc-name* option allows the
user to specify this prefix.  Its argument should be a symbol whose
print name will be concatenated onto the front of the slot names when
forming the accessor macro names.  If the argument is not given, then
the name of the structure followed by a dash is used, as it is if the
3:conc-name* option is not present.  (This is different than it
used to be!)  If it is desired that the slot names, as specified, be
used as the accessor macros, then 3(:conc-name nil)* may be used.
An example illustrates a common use of the 3:conc-name* option
along with the 3:default-pointer* option:
.lisp
(defstruct (location :default-pointer
		     :conc-name)
  (x 0)
  (y 0)
  (z 0))
.end_lisp
Now if you say
.lisp
(setq location (make-location x 1 y 34 z 5))
.end_lisp
it will be the case that
.lisp
(location-y)
.end_lisp
will return 34.  Note well that the name of the slot ("y") and the
name of the accessor macro for that slot ("location-y") are
different.

.subsection ":include"
.setq include-section-page section-page

	The 3:include* option inserts the definition of its argument
at the head of the new structure's definition.  In other words, the
first slots of the new structure are equivalent to (i.e. have the same
names as, have the same inits as, etc.) the slots of the argument to
the 3:include* option.  The argument to the 3:include* option must
be the name of a previously defined structure of the same type as the
new one.  If no type is specified in the new structure, then it is
defaulted to that of the included one.  It is an error for the
3:include* option to be present without an argument.  Note that
3:include* does not work on certain types of structures (e.g.
structures of type 3:tree* or 3:list**).  Note also that the
3:conc-name*, 3:default-pointer*, 3:but-first* and
3:callable-accessors* options only apply to the accessors defined in
the current 3defstruct*; no new accessors are defined for the
included slots.

.group
	An example:
.lisp
(defstruct (person (:type :list))
  name
  age
  sex)

(defstruct (spaceman (:include person)
		     (:conc-name nil)
		     :default-pointer)
  helmet-size
  (favorite-beverage 'tang))
.end_lisp
Now we can make a spaceman like this:
.lisp
(setq spaceman (make-spaceman :name 'buzz
			      :age 45.
			      :sex t
			      :helmet-size 17.5))
.end_lisp
To find out interesting things about spacemen:
.lisp
(helmet-size)		==> (cadddr spaceman)
(person-name spaceman)	==> (car spaceman)
(favorite-beverage x)	==> (car (cddddr x))
.end_lisp
.end_group

	As you can see the accessors defined for the 3person*
structure have names that start with "person-" and they only take one
argument.  The names of the accessors for the last two slots of the
3spaceman* structure are the same as the slot names, but they allow
their argument to be omitted.  The accessors for the first three slots
of the 3spaceman* structure are the same as the accessors for the
3person* structure.

	Often, when one structure includes another, the default
initial values supplied by the included structure will be undesirable.
These default initial values can be modified at the time of inclusion
by giving the 3:include* option as:
.lisp
(:include 2name* 2new-init-1* ... 2new-init-n*)
.end_lisp
Each 2new-init-i* is either the name of an included slot or of the
form 3(2included-slot-name* 2new-init*)*.  If it is just a slot
name, then in the new structure (the one doing the including) that
slot will have no initial value.  If a new initial value is given,
then that code replaces the old initial value code for that slot in
the new structure.  The included structure is unmodified.

.subsection ":copier"
.setq copier-section-page section-page

	This option causes 3defstruct* to generate a single argument
function that will copy instances of this structure.  The argument to
the 3:copier* option is the name of the copying function.  If this
option is present without an argument, then the name is formed by
concatenating "copy-" with the name of the structure.  

	Example:
.lisp
(defstruct (coat-hanger (:type :list) :copier)
  current-closet
  wire-p)
.end_lisp
Generates a function approximately like:
.lisp
(defun copy-coat-hanger (x)
  (list (car x) (cadr x)))
.end_lisp

.subsection ":class-symbol"
.setq class-symbol-section-page section-page

	For use with the 3:extend* 3defstruct* type available
only in lan{nil} ((defstruct-extend-type-section-page)), this option
allows the user to control 2how* the flavor definition is
performed.  This option 2must* be given a variable name as an
argument;  the value of that variable is used as the flavor (class)
object of the object which the 3defstruct*-defined constructor
will create.  3defstruct* will not define the flavor.

	This option was originally implemented for bootstrapping
purposes, so that typed objects in lan{nil} could be created before the
flavor system was fully loaded.  Eventually it will be fully outmoded
by extensions to the flavor system, which already has the capability
of defining accessor macros for instance variables.

.subsection ":sfa-function"
.setq sfa-function-section-page section-page

	Available in lan{pdp-10 maclisp} and in lan{nil}, this
option allows the user to
specify the function that will be used in structures of type 3:sfa*.
Its argument should be a piece of code that evaluates to the desired
function.  Constructor macros for this type of structure will take
3:sfa-function* as a keyword whose argument is also the code to
evaluate to get the function, overriding any supplied in the original
3defstruct* form.

	If 3:sfa-function* is not present anywhere, then the
constructor will use the name-symbol of the structure as the function.

.subsection ":sfa-name"
.setq sfa-name-section-page section-page

	Available only in lan{pdp-10 maclisp} and lan{nil},
this option allows the user to
specify the object that will be used in the printed representation of
structures of type 3:sfa*.  Its argument should be a piece of code
that evaluates to that object.  Constructor macros for this type of
structure will take 3:sfa-name* as a keyword whose argument is also
the code to evaluate to get the object to use, overriding any supplied
in the original 3defstruct* form.

	If 3:sfa-name* is not present anywhere, then the constructor
will use the name-symbol of the structure as the function.

.subsection ":size-symbol"
.setq size-symbol-section-page section-page

	The 3:size-symbol* option allows a user to specify a symbol
whose value will be the "size" of the structure.  The exact meaning of
this varies, but in general this number is the one you would need to
know if you were going to allocate one of these structures yourself.
The symbol will have this value both at compile time and at run time.
If this option is present without an argument, then the name of the
structure is concatenated with "-size" to produce the symbol.

.subsection ":size-macro"
.setq size-macro-section-page section-page

	Similar to 3:size-symbol*.  A macro of no arguments is defined
that expands into the size of the structure.  The name of this macro
defaults as with 3:size-symbol*.

.subsection ":initial-offset"
.setq initial-offset-section-page section-page

	This option allows you to tell 3defstruct* to skip
over a certain number of slots before it starts allocating
the slots described in the body.  This option requires an
argument, which must be a fixnum, which is the number of
slots you want 3defstruct* to skip.  To make use of this
option requires that you have some familiarity with how
3defstruct* is implementing you structure, otherwise you
will be unable to make use of the slots that 3defstruct*
has left unused.

.subsection ":but-first"
.setq but-first-section-page section-page

	This option is best explained by example:
.lisp
(defstruct (head (:type :list)
		 (:conc-name nil)
		 (:default-pointer person)
		 (:but-first person-head))
  nose
  mouth
  eyes)
.end_lisp
So now the accessors expand like this:
.lisp
(nose x)	==> (car (person-head x))
(nose)		==> (car (person-head person))
.end_lisp

The theory is that 3:but-first*'s argument will likely be an
accessor from some other structure, and it is never expected that this
structure will be found outside of that slot of that other structure.
(In the example I had in mind that there was a 3person* structure
which had a slot accessed by 3person-head*.)  It is an error for the
3:but-first* option to be used without an argument.

.subsection ":callable-accessors"
.setq callable-accessors-section-page section-page

	This option controls whether the accessors defined by 3defstruct*
will work as "functional arguments" (as the first argument to 3mapcar*,
for example).  On the Lisp Machine and in lan{nil} accessors are callable by
default, but in lan{pdp-10 maclisp} it is expensive to make this work, so they
are only callable if you ask for it.  (Currently on Multics the feature
doesn't work at all...)  The argument to this option is 3nil* to indicate
that the feature should be turned off, and 3t* to turn the feature on.
If the option is present with no argument, then the feature is turned on.

.subsection ":eval-when"
.setq eval-when-section-page section-page

	Normally the macros defined by 3defstruct* are defined at
eval-time, compile-time and at load-time.  This option allows the user
to control this behavior.  3(:eval-when (eval compile))*, for example,
will cause the macros to be defined only when the code is running
interpreted and inside the compiler, no trace of 3defstruct* will be
found when running compiled code.  (See 3eval-when*,
(eval-when-fun).)

	Using the 3:eval-when* option is preferable to wrapping an
3eval-when* around a 3defstruct* form, since nested
3eval-when*s can interact in unexpected ways.

.subsection ":property"
.setq property-section-page section-page

	For each structure defined by 3defstruct*, a property list is
maintained for the recording of arbitrary properties about that
structure.

	The 3:property* option can be used to give a 3defstruct*
an arbitrary property.  3(:property 2property-name* 2value*)*
gives the 3defstruct* a 2property-name* property of 2value*.
Neither argument is evaluated.  To access the property list, the user
will have to look inside the 3defstruct-description* structure
himself, he is referred to (defstruct-description-section-page), for
more information.

.subsection "A Type Used As An Option"
.setq type-as-option-section-page section-page

	In addition to the options listed above, any currently defined
type (a legal argument to the 3:type* option) can be used as a
option.  This is mostly for compatibility with the old Lisp Machine
3defstruct*.  It allows you to say just 2type* when you should be
saying 3(:type 2type*)*.  Use of this feature in new code is
discouraged.  It is an error to give an argument to a type used as an
option in this manner.

.subsection "Other Options"
.setq other-options-section-page section-page

	Finally, if an option isn't found among those listed above,
3defstruct* checks the property list of the name of the option to
see if it has a non-null 3:defstruct-option* property.  If is does
have such a property, then if the option was of the form
3(2option-name* 2value*)*, it is treated just like 3(:property
2option-name* 2value*)*.  That is, the 3defstruct* is given an
2option-name* property of 2value*.  If such an option is used
without an argument, it is treated just like 3(:property
2option-name* t)*.  That is, it is treated as if the argument was
3t*.

	This provides a primitive way for the user to define his own
options to 3defstruct*.  Several of the options listed above are
actually implemented using this mechanism.

.section "The defstruct-description Structure"
.setq defstruct-description-section-page section-page

	This section discusses the internal structures used by
3defstruct* that might be useful to programs that want to interface
to 3defstruct* nicely.  The information in this section is also
necessary for anyone who is thinking of defining his own structure
types ((extension-section-page)).  Lisp Machine and lan{nil}
programmers
'cindex packages
will find that the symbols found only in this section are all interned
in the "systems-internals" package ("SI" for short).

	Whenever the user defines a new structure using 3defstruct*,
3defstruct* creates an instance of the 3defstruct-description*
structure.  This structure can be found as the
3defstruct-description* property of the name of the structure; it
contains such useful information as the name of the structure, the
number of slots in the structure, etc.

	The 3defstruct-description* structure is defined something
like this:  (This is a bowdlerized version of the real thing, I have
left out a lot of things you don't need to know unless you are
actually reading the code.)
.lisp
(defstruct (defstruct-description
	     (:default-pointer description)
	     (:conc-name defstruct-description-))
  name
  size
  property-alist
  slot-alist)
.end_lisp

	The 3name* slot contains the symbol supplied by the user to be
the name of his structure, something like 3spaceship* or
3phone-book-entry*.

	The 3size* slot contains the total number of slots in an
instance of this kind of structure.  This is 2not* the same number
as that obtained from the 3:size-symbol* or 3:size-macro* options
to 3defstruct*.  A named structure, for example, usually uses up an
extra location to store the name of the structure, so the 3:size-macro*
option will get a number one larger than that stored in the
3defstruct* description.

	The 3property-alist* slot contains an alist with pairs of
the form 3(2property-name* . 2property*)* containing properties
placed there by the 3:property* option to 3defstruct* or by
property names used as options to 3defstruct* (see
(property-section-page), and (other-options-section-page)).

	The 3slot-alist* slot contains an alist of pairs of the form
3(2slot-name* . 2slot-description*)*.  A 2slot-description* is
an instance of the 3defstruct-slot-description* structure.  The
3defstruct-slot-description* structure is defined something like
this: (another bowdlerized 3defstruct*)
.lisp
(defstruct (defstruct-slot-description
	     (:default-pointer slot-description)
	     (:conc-name defstruct-slot-description-))
  number
  ppss
  init-code
  ref-macro-name)
.end_lisp

	The 3number* slot contains the number of the location of this
slot in an instance of the structure.  Locations are numbered
starting with 0, and continuing up to one less than the size of the
structure.  The actual location of the slot is determined by the
reference consing code associated with the type of the structure.  See
(extension-section-page).

	The 3ppss* slot contains the byte specifier code for this slot if
this slot is a byte field of its location.  If this slot is the entire
location, then the 3ppss* slot contains 3nil*.

	The 3init-code* slot contains the initialization code supplied
for this slot by the user in his 3defstruct* form.  If there is no
initialization code for this slot then the 3init-code* slot contains the
symbol 3%%defstruct-empty%%*.

	The 3ref-macro-name* slot contains the symbol that is defined as
an accessor that references this slot.

.section "Extensions to defstruct"
.setq extension-section-page section-page

.defmac defstruct-define-type
The macro 3defstruct-define-type* can be used to teach
3defstruct* about new types it can use to implement structures.
.end_defmac

.subsection "A Simple Example"

	Let us start by examining a sample call to
3defstruct-define-type*.  This is how the 3:list* type of
structure might have been defined:
.lisp
(defstruct-define-type :list
  (:cons (initialization-list description keyword-options)
	 :list
	 (cons 'list initialization-list))
  (:ref (slot-number description argument)
	(list 'nth slot-number argument)))
.end_lisp

This is the minimal example.  We have provided 3defstruct* with two
pieces of code, one for consing up forms to construct instances of the
structure, the other to cons up forms to reference various elements of
the structure.  

	From the example we can see that the constructor consing code
is going to be run in an environment where the variable
3initialization-list* is bound to a list which is the
initializations to the slots of the structure arranged in order.  The
variable 3description* will be bound to the
3defstruct-description* structure for the structure we are consing a
constructor for.  (See (defstruct-description-section-page).)
The binding of the variable 3keyword-options* will be described later.
Also the symbol 3:list* appears after the argument list, this conveys
some information to 3defstruct* about how the constructor consing
code wants to get called.

	The reference consing code gets run with the variable
3slot-number* bound to the number of the slot that is to be
referenced and the variable 3argument* bound to the code that
appeared as the argument to the accessor macro.  The variable
3description* is again bound to the appropriate instance of the
3defstruct-description* structure.

	This simple example probably tells you enough to be able to go
ahead and implement other structure types, but more details follow.

.subsection "Syntax of defstruct-define-type"

	The syntax of defstruct-define-type is
.lisp
(defstruct-define-type 2type*
  2option-1*
  ...
  2option-n*)
.end_lisp
where each 2option-i* is either the symbolic name of an option or a
list of the form 3(2option-i* . 2rest*)*.  (Actually
2option-i* is the same as 3(2option-i*)*.)  Different options
interpret 2rest* in different ways.

	The symbol 2type* is given a 3defstruct-type-description*
property of a structure that describes the type completely.

.subsection "Options to defstruct-define-type"

	This section is a catalog of all the options currently known
about by 3defstruct-define-type*.

.subsubsection ":cons"
.setq cons-option-section-page section-page

	The 3:cons* option to 3defstruct-define-type* is how the user
supplies 3defstruct* with the necessary code that it needs to cons up a
form that will construct an instance of a structure of this type.

	The 3:cons* option has the syntax:
.lisp
(:cons (2inits* 2description* 2keywords*) 2kind*
       2body*)
.end_lisp

	2body* is some code that should construct and return a piece
of code that will construct, initialize and return an instance of a
structure of this type.

	The symbol 2inits* will be bound to the code that the
constructor conser should use to initialize the slots of the
structure.  The exact form of this argument is determined by the
symbol 2kind*.  There are currently two kinds of initialization.
There is the 3:list* kind, where 2inits* is bound to a list of
initializations, in the correct order, with 3nil*s in uninitialized
slots.  And there is the 3:alist* kind, where 2inits* is bound to an
alist with pairs of the form 3(2slot-number* .
2init-code*)*.

	The symbol 2description* will be bound to the instance of
the 3defstruct-description* structure
((defstruct-description-section-page)) that 3defstruct* maintains
for this particular structure.  This is so that the constructor conser
can find out such things as the total size of the structure it is supposed
to create.

	The symbol 2keywords* will be bound to a alist with pairs of
the form 3(2keyword* . 2value*)*, where each 2keyword* was a
keyword supplied to the constructor macro that wasn't the name of a
slot, and 2value* was the "code" that followed the keyword.  (See
(keywords-section-page), and (constructor-section-page).)

	It is an error not to supply the 3:cons* option to
3defstruct-define-type*.

.subsubsection ":ref"

	The 3:ref* option to 3defstruct-define-type* is how the user
supplies 3defstruct* with the necessary code that it needs to cons up a
form that will reference an instance of a structure of this type.

	The 3:ref* option has the syntax:
.lisp
(:ref (2number* 2description* 2arg-1* ... 2arg-n*)
      2body*)
.end_lisp

	2body* is some code that should construct and return a piece
of code that will reference an instance of a structure of this type.
	The symbol 2number* will be bound to the location of the slot
that the is to be referenced.  This is the same number that is found
in the 3number* slot of the 3defstruct-slot-description* structure
((defstruct-description-section-page)).

	The symbol 2description* will be bound to the instance of the
3defstruct-description* structure that 3defstruct* maintains for this
particular structure.

	The symbols 2arg-i* are bound to the forms supplied to the
accessor as arguments.  Normally there should be only one of these.  
'setq multi-arg-accessors-section-page section-page
The 2last* argument is the one that will be defaulted by the
3:default-pointer* option ((default-pointer-section-page)).
3defstruct* will check that the user has supplied exactly n
arguments to the accessor macro before calling the reference consing
code.

	It is an error not to supply the 3:ref* option to
3defstruct-define-type*. 

.subsubsection ":predicate"

	The 3:predicate* option to 3defstruct-define-type* is how
3defstruct* is told how to produce predicates for a particular type
when the 3:predicate* option to 3defstruct* is used
((predicate-section-page)).  Its syntax is:
.lisp
(:predicate (2description* 2name*)
	    2body*)
.end_lisp

	The variable 2description* will be bound to the
3defstruct-description* structure maintained for the structure we
are to generate a predicate for.  The variable 2name* is bound to
the symbol that is to be defined as a predicate.  2body* is a piece
of code to evaluate to return the defining form for the predicate.  A
typical use of this option might look like:
.lisp
(:predicate (description name)
	    `(defun ,name (x)
	       (and (frobbozp x)
		    (eq (frobbozref x 0)
			',(defstruct-description-name)))))
.end_lisp

.subsubsection ":overhead"

	The 3:overhead* option to 3defstruct-define-type* is how
the user declares to 3defstruct* that the implementation of this
particular type of structure "uses up" some number of slots locations
in the object actually constructed.  This option is used by various
"named" types of structures that store the name of the structure in
one location.

	The syntax of 3:overhead* is:
.lisp
(:overhead 2n*)
.end_lisp
where 2n* is a
fixnum that says how many locations of overhead this type needs.

	This number is only used by the 3:size-macro* and
3:size-symbol* options to 3defstruct*.  (See
(size-macro-section-page), and (size-symbol-section-page).)

.subsubsection ":named"

	The 3:named* option to 3defstruct-define-type* controls
the use of the 3:named* option to 3defstruct*.  With no argument
the 3:named* option means that this type is an acceptable "named
structure".  With an argument, as in 3(:named 2type-name*)*, the
symbol 2type-name* should be that name of some other structure type
that 3defstruct* should use if someone asks for the named version of
this type.  (For example, in the definition of the 3:list* type the
3:named* option is used like this: 3(:named :named-list)*.)

.subsubsection ":keywords"
.setq keywords-section-page section-page

	The 3:keywords* option to 3defstruct-define-type* allows
the user to define constructor keywords
((constructor-section-page)) for this type of structure.
(For example the 3:make-array* constructor keyword for structures of
type 3:array* on Lisp Machines.)  The syntax is:
.lisp
(:keywords 2keyword-1* ... 2keyword-n*)
.end_lisp
where each 2keyword-i* is a
symbol that the constructor conser expects to find in the 2keywords*
alist ((cons-option-section-page)).

.subsubsection ":defstruct-options"

	The 3:defstruct-options* option to 3defstruct-define-type*
is similar to the 3:keywords* option.  It is used to define new
options that may appear in the options part of a 3defstruct* for a
structure of this type.  Its syntax is:
.lisp
(:defstruct-options 2option-1* ... 2option-n*)
.end_lisp
This defines each 2option-i* to be a option to 3defstruct*
that can be used with structures of this type.  For example, the
3:array* 3defstruct* type for the Lisp Machine uses the 
3:defstruct-options* option as follows:
.lisp
(:defstruct-options :make-array)
.end_lisp

	Currently this just works by giving each 2option-i* a
non-null 3:defstruct-option* property (see
(other-options-section-page)), but soon it will check to be sure that
each 2option-i* is 2only* used as an option with structures of
this type.

.subsubsection ":defstruct"

	The 3:defstruct* option to 3defstruct-define-type* allows
the user to run some code and return some forms as part of the
expansion of the 3defstruct* macro.

	The 3:defstruct* option has the syntax:
.lisp
(:defstruct (2description*)
	    2body*)
.end_lisp

	2body* is a piece of code that will be run whenever 3defstruct*
is expanding a 3defstruct* form that defines a structure of this type.
The symbol 2description* will be bound to the instance of the
3defstruct-description* structure that 3defstruct* maintains for this
particular structure.

	The value returned by the 3:defstruct* option should be a
2list* of forms to be included with those that the 3defstruct*
expands into.  Thus, if you only want to run some code at
3defstruct* expand time, and you don't want to actually output any
additional code, then you should be careful to return 3nil* from the
code in this option.

.subsubsection ":copier"

	The 3:copier* option to 3defstruct-define-type* allows the
user to tell 3defstruct* how to generate the copier functions
required by the 3:copier* option to 3defstruct*
((copier-section-page)).  This option is entirely optional, because
3defstruct* already has enough information to write an adequate
copier function for any given type given the information supplied to
the 3:ref* and 3:cons* options to 3defstruct-define-type*.
However, it is sometimes desirable to teach 3defstruct* a 2better*
way to copy a particular type of structure.

	The 3:copier* option has the syntax:
.lisp
(:copier (2description* 2name*)
	 2body*)
.end_lisp

	Similar to the 3:predicate* option, 2description* is bound
to the instance of the 3defstruct-description* structure maintained
for this structure, 2name* is bound to the symbol to be defined, and
2body* is some code to evaluate to get the defining form.  For
example:
.lisp
(:copier (description name)
	 `(defmacro ,name (x)
	    `(copy-frobboz ,x)))
.end_lisp

.subsubsection ":implementations"

	The 3:implementations* option to 3defstruct-define-type*
is primarily useful to the maintainers of 3defstruct* in keeping
control of the variations in 3defstruct* types available in
different implementations.  Its syntax is:
.lisp
(:implementations 2arg-1* ... 2arg-n*)
.end_lisp

This makes the 3defstruct-define-type* in which it appears only take
effect in those implementations of lan{lisp} in which 3(status feature
2arg-i*)* is true for at least one of the 2arg-i*.

