From d6fa4be81a42098a0f4ab5f934cbad9374b7431e Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Mon, 7 May 2018 07:20:01 +0200 Subject: [PATCH] Move documentation files to doc. --- {src => doc}/_mail_/*msg.exp | 0 {src => doc}/_mail_/-read-.-this- | 0 {src => doc}/_mail_/bboard.info | 0 {src => doc}/_mail_/names.info | 0 {src => doc}/acount/-read-.-this- | 0 {src => doc}/channa/-read-.-this- | 0 {src => doc}/graphs/graphs.usage | 0 {src => doc}/libdoc/fasdmp.info | 0 {src => doc}/libdoc/faslre.info | 0 {src => doc}/libdoc/for.info | 0 {src => doc}/libdoc/graphs.usage | 0 {src => doc}/libdoc/save.notes | 0 {src => doc}/libdoc/stack.info | 0 {src => doc}/libdoc/struct.news | 0 {src => doc}/libdoc/window.info | 0 {src => doc}/lisp/-read-.-this- | 0 {src => doc}/quux/-read-.-this- | 0 src/alan/struct.doc | 1422 ----------------------------- 18 files changed, 1422 deletions(-) rename {src => doc}/_mail_/*msg.exp (100%) rename {src => doc}/_mail_/-read-.-this- (100%) rename {src => doc}/_mail_/bboard.info (100%) rename {src => doc}/_mail_/names.info (100%) rename {src => doc}/acount/-read-.-this- (100%) rename {src => doc}/channa/-read-.-this- (100%) rename {src => doc}/graphs/graphs.usage (100%) rename {src => doc}/libdoc/fasdmp.info (100%) rename {src => doc}/libdoc/faslre.info (100%) rename {src => doc}/libdoc/for.info (100%) rename {src => doc}/libdoc/graphs.usage (100%) rename {src => doc}/libdoc/save.notes (100%) rename {src => doc}/libdoc/stack.info (100%) rename {src => doc}/libdoc/struct.news (100%) rename {src => doc}/libdoc/window.info (100%) rename {src => doc}/lisp/-read-.-this- (100%) rename {src => doc}/quux/-read-.-this- (100%) delete mode 100755 src/alan/struct.doc diff --git a/src/_mail_/*msg.exp b/doc/_mail_/*msg.exp similarity index 100% rename from src/_mail_/*msg.exp rename to doc/_mail_/*msg.exp diff --git a/src/_mail_/-read-.-this- b/doc/_mail_/-read-.-this- similarity index 100% rename from src/_mail_/-read-.-this- rename to doc/_mail_/-read-.-this- diff --git a/src/_mail_/bboard.info b/doc/_mail_/bboard.info similarity index 100% rename from src/_mail_/bboard.info rename to doc/_mail_/bboard.info diff --git a/src/_mail_/names.info b/doc/_mail_/names.info similarity index 100% rename from src/_mail_/names.info rename to doc/_mail_/names.info diff --git a/src/acount/-read-.-this- b/doc/acount/-read-.-this- similarity index 100% rename from src/acount/-read-.-this- rename to doc/acount/-read-.-this- diff --git a/src/channa/-read-.-this- b/doc/channa/-read-.-this- similarity index 100% rename from src/channa/-read-.-this- rename to doc/channa/-read-.-this- diff --git a/src/graphs/graphs.usage b/doc/graphs/graphs.usage similarity index 100% rename from src/graphs/graphs.usage rename to doc/graphs/graphs.usage diff --git a/src/libdoc/fasdmp.info b/doc/libdoc/fasdmp.info similarity index 100% rename from src/libdoc/fasdmp.info rename to doc/libdoc/fasdmp.info diff --git a/src/libdoc/faslre.info b/doc/libdoc/faslre.info similarity index 100% rename from src/libdoc/faslre.info rename to doc/libdoc/faslre.info diff --git a/src/libdoc/for.info b/doc/libdoc/for.info similarity index 100% rename from src/libdoc/for.info rename to doc/libdoc/for.info diff --git a/src/libdoc/graphs.usage b/doc/libdoc/graphs.usage similarity index 100% rename from src/libdoc/graphs.usage rename to doc/libdoc/graphs.usage diff --git a/src/libdoc/save.notes b/doc/libdoc/save.notes similarity index 100% rename from src/libdoc/save.notes rename to doc/libdoc/save.notes diff --git a/src/libdoc/stack.info b/doc/libdoc/stack.info similarity index 100% rename from src/libdoc/stack.info rename to doc/libdoc/stack.info diff --git a/src/libdoc/struct.news b/doc/libdoc/struct.news similarity index 100% rename from src/libdoc/struct.news rename to doc/libdoc/struct.news diff --git a/src/libdoc/window.info b/doc/libdoc/window.info similarity index 100% rename from src/libdoc/window.info rename to doc/libdoc/window.info diff --git a/src/lisp/-read-.-this- b/doc/lisp/-read-.-this- similarity index 100% rename from src/lisp/-read-.-this- rename to doc/lisp/-read-.-this- diff --git a/src/quux/-read-.-this- b/doc/quux/-read-.-this- similarity index 100% rename from src/quux/-read-.-this- rename to doc/quux/-read-.-this- diff --git a/src/alan/struct.doc b/src/alan/struct.doc deleted file mode 100755 index e263c242..00000000 --- a/src/alan/struct.doc +++ /dev/null @@ -1,1422 +0,0 @@ -.c -*-Bolio-*- - -.chapter "Defstruct" -.setq defstruct-page page - -.section "Introduction" - - The features of 3defstruct* differ slightly from one Lisp -implementation to another. However, 3defstruct* makes it fairly -easy to write compatible code if the user doesn't try to exercise any -of the more esoteric features of his particular Lisp implementation. -The differences will be pointed out as they occur. - - One difference that we must deal with immediately is the -'cindex packages -question of packages. 3defstruct* makes use of a large number of -keywords, and on the Lisp Machine and in NIL those keywords are all -interned on the keyword package and thus should be typed with a leading -colon. However, in PDP-10 and Multics MacLisp these keywords are just -ordinary symbols and no colon is necessary. For the purposes of -compatibility, in Lisp Machine Lisp and in NIL 3defstruct* will allow the -keywords to appear in any package, while in PDP-10 and Multics MacLisp, -3defstruct* will also check for symbols that have a leading ":" in their -names. Users should probably stick to the accepted style of their -own Lisp dialect, and thus MacLisp users are invited to pretend that -the rest of the colons in this document are invisible and Lisp Machine and -NIL users are invited to ignore this paragraph. - -.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: 3color*, 3size*, 3name*, 3make-elephant* -and 3alter-elephant*. Note that there were no symbols 3make-elephant* or -3alter-elephant* in the original form, they were created by -3defstruct*. The definitions of 3color*, 3size* and 3name* -are easy, they expand as follows: -.lisp -(color x) ==> (car x) -(size x) ==> (cadr x) -(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*. 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* -2ppss*)* or 3(2field-name* 2ppss* 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* is -explained in detail in (byte-field-section-page). - -.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 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 (hunks in PDP-10 MacLisp, arrays on Lisp Machines and lists on -Multics). 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 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 on Multics. -.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. Lisp Machine users may want to see -the 3:make-array* option documented in (make-array-section-page). -.end_defstruct_type - -.defstruct_type :fixnum-array "All implementations" -Like 3:array*, except it uses a fixnum array and thus your structure -can only contain fixnums. On Lisp Machines 3defstruct* uses an -3art-32b* type array for this type. -.end_defstruct_type - -.defstruct_type :flonum-array "All implementations" -Analogous to 3:fixnum-array*. On Lisp Machines 3defstruct* -uses an 3art-float* type array for this type. -.end_defstruct_type - -.defstruct_type :un-gc-array "PDP-10 MacLisp only" -Uses a 3nil* type array instead of a 3t* type. -Note that this type does not exist on Lisp Machines or Multics, -because un-garbage-collected arrays do not work in those implementations. -.end_defstruct_type - -.defstruct_type :hunk "PDP-10 MacLisp only" -Uses a hunk. This is the default in -PDP-10 MacLisp. -.end_defstruct_type - -.defstruct_type :named-hunk "PDP-10 MacLisp only" -Like 3hunk*, except the car of each instance of this structure will -be the name symbol of the structure. This is the default named -type in PDP-10 MacLisp. This 2can* be used with the -3(status usrhunk)* feature of PDP-10 Maclisp to give the user -Lisp Machine-like named structures. (See the 3:named* option -documented in (named-section-page).) -.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 NIL for -compatibility with PDP-10 MacLisp.) -.end_defstruct_type - -.defstruct_type :vector "PDP-10 MacLisp and NIL" -Uses an vector. This is the default type in NIL. -Since PDP-10 MacLisp doesn't really have vectors, using type -vector there will simply use whatever vector package the user has loaded. -.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 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 NIL. It -uses the NIL flavor system to define the structure. The effect of -this is that the structure will have a type name of the name symbol, -which will work with 3typep*, and can otherwise be treated as a -flavor defined with 3defflavor*, except that the existence of -instance variables is not defined: one may use 3defmethod* to -define methods, and access the slots with the 3defstruct*-defined -accessor macros. The type defined by 3defstruct* will inherit -methods for printing, 3describe*, and 3inspect*. -.c Someday also the name will be changed do something more -.c meaningful, and perhaps it 2should* define instance variables. -.c @@@ Glenn wrote something here. -See also the 3:class-symbol* -option ((class-symbol-section-page)). -.end_defstruct_type - -.defstruct_type :named-array "Lisp Machine only" -Uses an array with the named structure bit set and stores the name -symbol of the structure in the first element. This is the default named -type on the Lisp Machine. (See the 3:make-array* -option documented in (make-array-section-page).) -.end_defstruct_type - -.defstruct_type :array-leader "Lisp Machine only" -Uses an array with a leader. (See the 3:make-array* -option documented in (make-array-section-page).) -.end_defstruct_type - -.defstruct_type :named-array-leader "Lisp Machine only" -Uses an array with a leader, sets the named structure bit, and stores -the name symbol in element 1 of the leader. (See the 3:make-array* -option documented in (make-array-section-page).) -.end_defstruct_type - -.defstruct_type :fixnum "All implementations" -This type allows one to use the byte field feature of 3defstruct* to -deal symbolically with fixnums that aren't actually stored in any -structure at all. Essenti vector, except element number 0 always contains the name symbol of the -structure. Note that this is 2not* the default 2named* type in 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 NIL. It -uses the NIL flavor system to define the structure. The effect of -this is that the structure will have a type name of the name symbol, -which will work with 3typep*, and can otherwise be treated as a -flavor defined with 3defflavor*, except that the existence of -instance variables is not defined: one may use 3defmethod* to -define methods, and access the slots with the 3defstruct*-defined -accessor macros. The type defined by 3defstruct* will inherit -methods for printing, 3describe*, and 3inspect*. -.c Someday also the name will be changed do something more -.c meaningful, and perhaps it 2should* define instance variables. -.c @@@ Glenn wrote something here. -See also the 3:class-symbol* -option ((class-symbol-section-page)). -.end_defstruct_type - -.defstruct_type :named-array "Lisp Machine only" -Uses an array with the named structure bit set and stores the name -symbol of the structure in the first element. This is the default named -type on the Lisp Machine. (See the 3:make-array* -option documented in (make-array-section-page).) -.end_defstruct_type - -.defstruct_type :array-leader "Lisp Machine only" -Uses an array with a leader. (See the 3:make-array* -option documented in (make-array-section-page).) -.end_defstruct_type - -.defstruct_type :named-array-leader "Lisp Machine only" -Uses an array with a leader, sets the named structure bit, and stores -the name symbol in element 1 of the leader. (See the 3:make-array* -option documented in (make-array-section-page).) -.end_defstruct_type - -.defstruct_type :fixnum "All implementations" -This type allows one to use the byte field feature of 3defstruct* to -deal symbolically with fixnums that aren't actually stored in any -structure at all. Essentially, a structure of type 3:fixnum* has exactly -one slot. This allows the operation of retrieving the contents of -that slot to be optimized away into the identity operation. See -(byte-field-section-page) for more information about byte -fields. -.end_defstruct_type - -.defstruct_type :external "Multics only" -Uses an array of type 3external* (only Multics MacLisp has these). -Constructor macros for structures of this kind take the -3:external-ptr* keyword to tell them where the array is to be -allocated. (See (constructor-section-page), for an explanation of -constructor macro keywords.) See also the 3:external-ptr* option -described in (external-ptr-section-page). -.end_defstruct_type - -.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 -(not necessarily the name of an accessor macro; see the 3:conc-name* -option, (conc-name-section-page)), or one of the special -keywords allowed for the particular type of structure being -constructed. 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. See, -for example, the 3:make-array* option ((make-array-section-page)), -the 3:sfa-function* option ((sfa-function-section-page), or -the 3:external-ptr* option ((external-ptr-section-page)). - - On the Lisp Machine and in NIL all such constructor macro keywords -(those that are 2not* the names of slots) are interned on the keyword -'cindex packages -package. - - 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.) -.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 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 NIL this -indicates that you desire an 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. - - 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* (PDP-10 MacLisp and NIL -only) and 3:extend* (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 NIL, -using the 3defstruct* types 3:named-array* and 3:extend* -respectively. We hope to make it work in PDP-10 MacLisp for the -3:named-hunk* type soon. In 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. If the -3:conc-name* option is not present, then no prefix is 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) - :conc-name) - name - age - sex) - -(defstruct (spaceman (:include person) - :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 ":make-array" -.setq make-array-section-page section-page - - Available only on Lisp Machines, this option allows the user to -control those aspects of the array used to implement the structure -that are not otherwise constrained by 3defstruct* (such as the area it -is to be allocated in). - - The argument to the 3:make-array* option should be a list of -alternating keyword symbols to the Lisp Machine 3make-array* function -(see the Lisp Machine manual), and forms whose values are to be the -arguments to those keywords. For example, 3(:make-array (:type -'art-4b))* would request that the type of the array be 3art-4b*. -Note that the keyword symbols are 2not* evaluated. - - Constructor macros for structures implemented as -arrays all allow the keyword 3:make-array* to be supplied. -Its argument is of the same form as the 3:make-array* -option, and attributes specified there (in the constructor -form) will override those given in the 3defstruct* form. - - Since it is sometimes necessary to be able to specify the -dimensions of the array that 3defstruct* is going to construct (for -structures of type 3:array-leader* for example), the 3:make-array* -option or constructor keyword accepts the additional keywords -3:length* and 3:dimension* (they mean the same thing). The -argument to this pseudo 3make-array* keyword will be supplied as the -first argument to the 3make-array* function when the constructor is -expanded. - - 3defstruct* chooses appropriate defaults for those attributes -not specified in the 3defstruct* form or in the constructor form, -and 3defstruct* overrides any specified attributes that it has to. - -.subsection ":class-symbol" -.setq class-symbol-section-page section-page - - For use with the 3:extend* 3defstruct* type available -only in 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 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. -.c @@@ Glenn wrote this! - -.subsection ":sfa-function" -.setq sfa-function-section-page section-page - - Available in PDP-10 MacLisp and in 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 PDP-10 MacLisp, 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 ":external-ptr" -.setq external-ptr-section-page section-page - - Available only in Multics MacLisp, this option is used with -structures of type 3:external*. Its argument should be a piece of code -that evaluates to a fixnum "packed pointer" pointing to the first word of -the external array that 3defstruct* is allocate as a structure. -Constructor macros for this type of structure will take 3:external-ptr* as -a keyword whose argument overrides any supplied in the original -3defstruct* form. - - If 3:external-ptr* is not present anywhere, then the -constructor signals an error when it expands. - -.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) - (: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 NIL accessors are callable by -default, but in 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. - - 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 "Byte Fields" -.setq byte-field-section-page section-page - - On Multics, the byte field feature will not work unless the -user has arranged to define the functions 3ldb* and 3dpb* -((byte-hacking-section-page)). They are not yet present in the -default environment, but they are available as part of the extension -library ((multics-library-section-page)). - - The byte field feature of 3defstruct* allows the user to specify -that several slots of his structure are bytes in a fixed point number -stored in one element of the structure. For example, suppose we had -the following structure: -.lisp -(defstruct (phone-book-entry (:type :list)) - name - address - (area-code 617.) - exchange - line-number) -.end_lisp -This will work just fine. Except you notice that an 3area-code* and -an 3exchange* are both always less than 1000., and so both can -easily fit in 10. bits, and the 3line-number* is always less than -10000. and can thus fit in 14. bits. Thus you can pack all three -parts of a phone number in 34. bits. If you have a lisp with 36. bit -fixnums, then you should be able to put the entire phone number in one -fixnum in a structure. 3defstruct* allows you to do this as -follows: -.lisp -(defstruct (phone-book-entry (:type :list)) - name - address - ((area-code #o3012 617.) - (exchange #o1612) - (line-number #o0016))) -.end_lisp -The magic numbers 3#o3012*, 3#o1612* and 3#o0016* are byte specifiers -suitable for use with the functions 3ldb* and 3dpb* ((ldb-fun)). -Things will expand as follows: -.lisp -(area-code pbe) ==> (ldb #o3012 (caddr pbe)) -(exchange pbe) ==> (ldb #o1612 (caddr pbe)) - -(make-phone-book-entry - name '|Fred Derf| - address '|259 Octal St.| - exchange ex - line-number 7788.) - -==> (list '|Fred Derf| '|259 Octal St.| - (dpb ex #o1612 #o115100017154)) - -(alter-phone-book-entry pbe - exchange ex - line-number ln) - -==> ((lambda (G0003) - (setf (caddr G0003) - (dpb ex #o1612 (dpb ln #o0016 (caddr G0003))))) - pbe) -.end_lisp - -3defstruct* tries to be maximally clever about constructing and altering -structures with byte fields. - - The byte specifiers are actually pieces of code that are -expected to evaluate to byte specifiers, but 3defstruct* will try -and understand fixnums if you supply them. (In the -3make-phone-book* example, 3defstruct* was able to make use of its -knowledge of the 3line-number* and 3area-code* byte specifiers to -assemble the constant number 3#o115100017154* and produce code to just -deposit in the 3exchange*.) - - A 3nil* in the place of the byte specifier code means to define -an accessor for the entire word. So we could say: -.lisp -(defstruct (phone-book-entry (:type :list)) - name - address - ((phone-number nil) - (area-code #o3012 617.) - (exchange #o1612) - (line-number #o0016))) -.end_lisp -to enable us to do things like: -.lisp -(setf (phone-number pbe1) (phone-number pbe2)) -.end_lisp -to cause two entries to -have the same phone numbers. - - We could also have said just: 3((phone-number) ...)* in that -last 3defstruct*, but the feature of 3nil* byte specifiers allows -you to supply initial values for the entire slot by saying: -3((2name* nil 2init*) ...)*. - - Constructor macros initialize words divided into byte fields -as if they were deposited in the following order: - - 1) Initializations for the entire word given in the 3defstruct* form. - - 2) Initializations for the byte fields given in the 3defstruct* form. - - 3) Initializations for the entire word given in the constructor macro form. - - 4) Initializations for the byte fields given in the constructor macro form. - -Alterant macros operate in a similar manner. That is, as if the -entire word was modified first, and then the byte fields were -deposited. Results will be unpredictable in constructing and altering -if byte fields that overlap are given. - -.section "About Autoloading" -.setq autoloading-section-page section-page - - This section only applies to PDP-10 and Multics MacLisp. - - If you look at the property lists of the macros defined by -3defstruct*, you will find that they are all have macro properties of one -of four functions: 3defstruct-expand-ref-macro*, -3defstruct-expand-cons-macro*, 3defstruct-expand-alter-macro* and -3defstruct-expand-size-macro*. These functions figure out how to expand -the macro by examining the property list of the car of the form they -are asked to expand. 3defstruct-expand-ref-macro*, for example, looks -for a 3defstruct-slot* property, which should be a cons of the form -3(2structure-name* . 2slot-name*)*. - - Since the 3defstruct* form only expands into 3putprop*s of the -desired functions (instead of actually constructing a full-fledged -definition), loading a compiled file containing a 3defstruct* merely -adds a few properties to some symbols. The run time environment is -not needlessly cluttered with unwanted list structure or subr objects. -If the user thinks he may wish to use any of the macros defined by -3defstruct* after compiling his file, he need only give the four -expanding functions autoload properties of the name of the file -containing 3defstruct* itself. - - For purposes of using 3defstruct* interpreted, the two -symbols 3defstruct* and 3defstruct-define-type* should be given -similar autoload properties. Thus six symbols with autoload -properties suffice to make 3defstruct* appear loaded at all times. - -.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 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 insta \ No newline at end of file