-*-Text-*- 5/27/82 Alan New features in defstruct: There are three new defstruct options: 1) print This allows the user to control the printed representation of his structure in an implementation independent way: (defstruct (foo named (print "#" (foo-a foo) (foo-b foo))) foo-a foo-b) The arguments to the print option are arguments to the format function (except for the stream of course!). They are evaluated in an environment where the name symbol of the structure (foo in this case) is bound to the instance of the structure to be printed. Note, please, that this option presently only works on LispMachines and in NIL. We hope to make it work in PDP-10 MacLisp soon. In Multics MacLisp, this option is ignored. 2) predicate The predicate option causes defstruct to generate a predicate to recognize instances of the structure. Naturally it only works for some defstruct types. Currently it works for all the named types as well as the types sfa (MacLisp and NIL only) and extend (NIL only). The argument to the 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: (defstruct (foo named predicate) foo-a foo-b) defines a single argument function, foo-p, that is true only of instances of this structure. 3) copier This option causes defstruct to generate a single argument function that will copy instances of this structure. Its arguemnt is the name of the copying function. If the option is present without an argument, then the name is formed by concatenating "copy-" with the name of the structure. Example: (defstruct (foo (type list) copier) foo-a foo-b) Generates a function approximately like: (defun copy-foo (x) (list (car x) (cadr x))) Inprovements: It is now impossible (I believe) to confuse defstruct by typing or not typing colons in front of various defstruct options and keywords. defstruct, in Lisps without a package system, knows how to compensate for people who spell their keywords with a colon as the first character, and in Lisps with packages, it knows how to find the symbol the user meant to type in the keyword package. It is now possible to use alterant macros on defstruct types whose accessors require additional arguments (like the old grouped-array type). The additional arguments are given to the alterant macro in exactly the same order they are given to the accessors, before the "setq-style" list of slots and new values. Remnants removed: The old displace defstruct option has now been completely flushed. The current story on when defstruct-defined macros displace is that they NEVER displace. This is because there isn't even a remotely compatible theory on displacement between various dialects. Someday we'll figure one out, but until then defstruct just plays it safe. Multics MacLisp: It now works to have defstruct loaded into lcp without the rest of the Mathlab macrology. Previously it was necessary to load the Mathlab environment in order to ensure that macros defined by defstruct actually got defined in the object segment. No one seems to have noticed this except me, so I presume that you are all loading the Mathlab stuff, or you are always keeping your structure definitions in the same files that use them, or you are not compiling your defstructs. NIL: defstruct is now supported in the NIL dialect of Lisp. defstruct types specifically intended for NIL are: vector, named-vector, and extend. The extend type is a named type. Vectors are what you get by default (no type specified in the defstruct header), and if you ask for a named type (by just using the named option) you get an extend. The extend type is the one that knows how to print itself smartly. LispMachine: The new make-array keyword :initial-value is supported. Note that the slots of an array-type structure are initialized by the constructor code AFTER the array is initialized by make-array. Two new options to defstruct-define-type: 1) predicate The predicate option to defstruct-define-type is how defstruct is told how to produce predicates for a particular type. Its syntax is: (predicate ( ) ) The variable will be bound to the defstruct-description structure maintained for the structure we are to generate a predicate for. The variable is bound to the symbol that is to be defined as a predicate. is a piece of code to evaluate to return the defining form for the predicate. A typical use of this option might look like: (predicate (description name) `(defun ,name (x) (and (frobbozp x) (eq (frobbozref x 0) ',(defstruct-description-name))))) 2) copier defstruct knows how to use the constructor and reference macro code that must be provided with any new defstruct type to generate a copying function. Nevertheless it is sometimes desirable to specify a specific method of copying a particular defstruct type. The copier option to defstruct-define-type allow this to be done: (copier ( ) ) Similar to the predicate option, is bound to an instance of the defstruct-description structure, is bound to the symbol to be defined, and is some code to evaluate to get the defining form. For example: (copier (description name) `(fset-carefully ',name 'copy-frobboz))