Cleanup Issue DEFSTRUCT-COPIER

Category
CLARIFICATION, CHANGE
References
DEFSTRUCT

Problem Description

The description of the :COPIER option to DEFSTRUCT in CLtL states:

The automatically defined copier function simply makes a new structure and transfers all components verbatim from the argument into the newly created structure.

This description doesn't make it clear whether the type of the newly created structure is copied from the argument, or is determined by the copier function. This can make a difference in the case where a copier function defined for one structure type is passed an argument that belongs to a subtype of the original type. Does the result have the "name" of the subtype and any additional slots present in the subtype but not the parent type, or does it have the same "name" as the parent type and only the slots inherited from that type?

There are four proposals: ARGUMENT-TYPE, COPIER-TYPE, UNSPECIFIED, and REMOVE.

Proposal (ARGUMENT-TYPE)

Clarify that the type of the result returned by copier functions created by DEFSTRUCT is always exactly the same type as the argument to the copier. That is, if the argument is of a subtype of the structure type for which the copier was defined, then the result will also be of that subtype and include all the slots of the subtype.

Rationale for proposal ARGUMENT-TYPE: Some people expect this behavior.

Proposal (COPIER-TYPE)

Clarify that the type of the result returned by copier functions created by DEFSTRUCT is always exactly the structure type for which the copier was defined. That is, if the argument is of a subtype of the structure type for which the copier was defined, the result will be of the supertype only and include only those slots that are present in the supertype.

Rationale for proposal COPIER-TYPE: Some people expect this behavior.

Proposal (UNSPECIFIED)

Clarify that it is unspecified whether the type of the result returned by copier functions created by DEFSTRUCT is the type of the argument to the copier, or the structure type for which the copier function was defined. (In other words, the behavior of copier functions is well-defined only when they are passed arguments of the exact same type for which the copier was defined.)

Rationale for proposal UNSPECIFIED: Some people don't know what behavior to expect.

Proposal (REMOVE)

Remove the :COPIER option to DEFSTRUCT.

Rationale for proposal REMOVE: The feature is so poorly specified it's already useless.

Examples

    (defstruct foo a b)
    (defstruct (bar (:include foo)) c d)
    (setq result (copy-foo (make-bar)))

  Under proposal ARGUMENT-TYPE,
    (type-of result) => BAR

  Under proposal COPIER-TYPE,
    (type-of result) => FOO

  Under proposal UNSPECIFIED,
    (type-of result) => either FOO or BAR

Under proposal REMOVE, users would have to define their own copier functions to have whatever behavior they wanted.

Current Practice

Some Lisps now implement proposal ARGUMENT-TYPE and others implement proposal COPIER-TYPE. Some Lisps also provide a COPY-STRUCTURE function that can be used to make an exact duplicate of any structure object.

Cost to Implementors

Small.

Cost to Users

Code that relies on any particular behavior is probably not now portable anyway. It doesn't seem like copiers are used very much.

Cost of Non-Adoption

This part of the language specification remains vague.

Performance Impact

Proposal REMOVE would save space since there would be no normally useless copier functions generated by DEFSTRUCT. It may be that copier functions defined by hand would be considerably less efficient than a copier provided by the implementation (which might make use of knowledge about the internal layout of structures to do a block memory copy or the like).

Benefits

This part of the language specification becomes more precise.

Aesthetics

Leaving the behavior explicitly vague seems unnecessarily ugly.

Discussion

Loosemore's ranking of the proposals from most to least acceptable is: ARGUMENT-TYPE, REMOVE, COPIER-TYPE, UNSPECIFIED.

BarMar has said he thinks the behavior should be left unspecified.

Moon has said he favors flushing the :copier feature. Barrett also prefers flushing :copier.

Perhaps we should consider adding COPY-STRUCTURE to the standard? -------

Edit History