Common Lisp the Language, 2nd Edition

Next: Defstruct Slot-Options Up: Structures Previous: How to Use

# 19.3. Using the Automatically Defined Constructor Function

After you have defined a new structure with `defstruct`, you can create instances of this structure by using the constructor function. By default, `defstruct` defines this function automatically. For a structure named `foo`, the constructor function is normally named `make-foo`; you can specify a different name by giving it as the argument to the `:constructor` option, or specify that you don't want a normal constructor function at all by using `nil` as the argument (in which case one or more ``by-position'' constructors should be requested; see section 19.6).

A call to a constructor function, in general, has the form

    (name-of-constructor-function
            slot-keyword-1 form-1
            slot-keyword-2 form-2
            ...)

All arguments are keyword arguments. Each slot-keyword should be a keyword whose name matches the name of a slot of the structure (`defstruct` determines the possible keywords simply by interning each slot-name in the keyword package). All the keywords and forms are evaluated. In short, it is just as if the constructor function took all its arguments as `&key` parameters. For example, the `ship` structure shown in section 19.1 has a constructor function that takes arguments roughly as if its definition were

    (defun make-ship (&key x-position y-position
                           x-velocity y-velocity mass)
      ...)

If slot-keyword-j names a slot, then that element of the created structure will be initialized to the value of form-j. If no pair slot-keyword-j and form-j is present for a given slot, then the slot will be initialized by evaluating the default-init form specified for that slot in the call to `defstruct`. (In other words, the initialization specified in the `defstruct` defers to any specified in a call to the constructor function.) If the default initialization form is used, it is evaluated at construction time, but in the lexical environment of the `defstruct` form in which it appeared. If the `defstruct` itself also did not specify any initialization, the element's initial value is undefined. You should always specify the initialization, either in the `defstruct` or in the call to the constructor function, if you care about the initial value of the slot.

Each initialization form specified for a `defstruct` component, when used by the constructor function for an otherwise unspecified component, is re-evaluated on every call to the constructor function. It is as if the initialization forms were used as init forms for the keyword parameters of the constructor function. For example, if the form `(gensym)` were used as an initialization form, either in the constructor-function call or as the default initialization form in the `defstruct` form, then every call to the constructor function would call `gensym` once to generate a new symbol.

X3J13 voted in October 1988 (DEFSTRUCT-DEFAULT-VALUE-EVALUATION) to clarify that the default value in a defstruct slot is not evaluated unless it is needed in the creation of a particular structure instance. If it is never needed, there can be no type-mismatch error, even if the type of the slot is specified, and no warning should be issued.

For example, in the following sequence only the last form is in error.

    (defstruct person (name .007 :type string))

    (make-person :name "James")

    (make-person)     ;Error to give name the value .007

Next: Defstruct Slot-Options Up: Structures Previous: How to Use