Common Lisp the Language, 2nd Edition

next up previous contents index
Next: Using the Automatically Up: Structures Previous: Introduction to Structures

19.2. How to Use Defstruct

All structures are defined through the defstruct construct. A call to defstruct defines a new data type whose instances have named slots.



defstruct name-and-options [doc-string] {slot-description}+

X3J13 voted in June 1988 (DEFSTRUCT-SLOTS-CONSTRAINTS-NUMBER)   to allow a defstruct definition to have no slot-description at all; in other words, the occurrence of slot-description in the preceding header line would be replaced by slot-description.

Such structure definitions are particularly useful if the :include option is used, perhaps with other options; for example, one can have two structures that are exactly alike except that they print differently (having different :print-function options).

Implementors are encouraged to permit this simple extension as soon as convenient. Users, however, may wish to maximize portability of their code by avoiding the use of this extension unless and until it is adopted as part of the ANSI standard.

This defines a record-structure data type. A general call to defstruct looks like the following example.

(defstruct (name option-1 option-2 ... option-m) 

The name must be a symbol; it becomes the name of a new data type consisting of all instances of the structure. The function typep will accept and use this name as appropriate. The name is returned as the value of the defstruct form.

Usually no options are needed at all. If no options are specified, then one may write simply name instead of (name) after the word defstruct. The syntax of options and the options provided are discussed in section 19.5.

If the optional documentation string doc-string is present, then it is attached to the name as a documentation string of type structure; see documentation.

Each slot-description-j is of the form

(slot-name default-init slot-option-name-1 slot-option-value-1 slot-option-name-2 slot-option-value-2 ... slot-option-name-kj slot-option-value-kj)

Each slot-name must be a symbol; an access function is defined for each slot. If no options and no default-init are specified, then one may write simply slot-name instead of (slot-name) as the slot description.

The default-init is a form that is evaluated each time a structure is to be constructed; the value is used as the initial value of the slot.

X3J13 voted in October 1988 (DEFSTRUCT-DEFAULT-VALUE-EVALUATION)   to clarify that a default-init form is evaluated only if the corresponding argument is not supplied to the constructor function. The preceding sentence should therefore read as follows:

The default-init is a form that is evaluated each time its value is to be used as the initial value of the slot.

If no default-init is specified, then the initial contents of the slot are undefined and implementation-dependent. The available slot-options are described in section 19.4.

Compatibility note: Slot-options are not currently provided in Lisp Machine Lisp, but this is an upward-compatible extension.

X3J13 voted in January 1989 (DEFSTRUCT-SLOTS-CONSTRAINTS-NAME)   to specify that it is an error for two slots to have the same name; more precisely, no two slots may have names for whose print names string= would be true. Under this interpretation

(defstruct lotsa-slots slot slot)

obviously is incorrect but the following one is also in error, even assuming that the symbols coin:slot and blot:slot really are distinct (non-eql) symbols:

(defstruct no-dice coin:slot blot:slot)

To illustrate another case, the first defstruct form below is correct, but the second one is in error.

(defstruct one-slot slot) (defstruct (two-slots (:include one-slot)) slot)

Rationale: Print names are the criterion for slot-names being the same, rather than the symbols themselves, because defstruct constructs names of accessor functions from the print names and interns the resulting new names in the current package.

X3J13 recommended that expanding a defstruct form violating this restriction should signal an error and noted, with an eye to the Common Lisp Object System (CLOS)   , that the restriction applies only to the operation of the defstruct macro as such and not to the structure-class or structures defined with defclass.

X3J13 voted in March 1989 (DEFINING-MACROS-NON-TOP-LEVEL)   to clarify that, while defining forms normally appear at top level, it is meaningful to place them in non-top-level contexts; defstruct must treat slot default-init forms and any initialization forms within the specification of a by-position constructor function as occurring within the enclosing lexical environment, not within the global environment.

defstruct not only defines an access function for each slot, but also arranges for setf to work properly on such access functions, defines a predicate named name-p, defines a constructor function named make-name, and defines a copier function named copy-name. All names of automatically created functions are interned in whatever package is current at the time the defstruct form is processed (see *package*). Also, all such functions may be declared inline at the discretion of the implementation to improve efficiency; if you do not want some function declared inline, follow the defstruct form with a notinline declaration to override any automatic inline declaration.

X3J13 voted in January 1989 (DEFSTRUCT-REDEFINITION)   to specify that the results of redefining a defstruct structure (that is, evaluating more than one defstruct structure for the same name) are undefined.

The problem is that if instances have been created under the old definition and then remain accessible after the new definition has been evaluated, the accessors and other functions for the new definition may be incompatible with the old instances. Conversely, functions associated with the old definition may have been declared inline and compiled into code that remains accessible after the new definition has been evaluated; such code may be incompatible with the new instances.

In practice this restriction affects the development and debugging process rather than production runs of fully developed code. The defstruct feature is intended to provide ``the most efficient'' structure class. CLOS classes defined by defclass allow much more flexible structures to be defined and redefined.

Programming environments are allowed and encouraged to permit defstruct redefinition, perhaps with warning messages about possible interactions with other parts of the programming environment or memory state. It is beyond the scope of the Common Lisp language standard to define those interactions except to note that they are not portable.

next up previous contents index
Next: Using the Automatically Up: Structures Previous: Introduction to Structures