#

## Issue DEFSTRUCT-COPIER Writeup

    Issue:               DEFSTRUCT-COPIER
    References:          DEFSTRUCT
    Related issues:
    Category:            CLARIFICATION, CHANGE
    Edit history:        V1, 10 May 90, Sandra Loosemore
                         V2, 13 May 90, Sandra Loosemore (update discussion)
    		     V3, 29 May 90, Sandra Loosemore (more comments)

    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 (DEFSTRUCT-COPIER: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 (DEFSTRUCT-COPIER: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 (DEFSTRUCT-COPIER: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 (DEFSTRUCT-COPIER: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.

    Esthetics:

      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?
    -------

Copyright 1996-2005, LispWorks Ltd. All rights reserved.