DEFSTRUCT-COPIER: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.
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.
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.
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.
:COPIER option to DEFSTRUCT.
Rationale for proposal REMOVE: The feature is so poorly specified it's already useless.
(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.
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.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).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? -------