CLHS: Issue TAGBODY-TAG-EXPANSION Writeup

#

## Issue TAGBODY-TAG-EXPANSION Writeup

    Issue:             TAGBODY-TAG-EXPANSION
    References:        TAGBODY (CLtL-II p 173-175)
    Related issues:
    Category:          CLARIFICATION
    Edit history:      v1, 27 Feb 91, Sandra Loosemore
                       v2, 11 Mar 91, Sandra Loosemore (update discussion)
                       v3, 14 Mar 91, Sandra Loosemore (fix bug in example)
    Status:            v3 (proposal NO) accepted by X3J13, Mar 1991

    Problem description:

      It's not clear whether items in the body of a TAGBODY are
      macroexpanded before determining whether they are "tags" or
      "statements".  The (original) text on p. 173 of CLtL-II seems to
      imply that they are not, but the (new) commentary on p. 175
      hints that some implementations might expand macros.  This ambiguity
      can lead to different behavior in different implementations.

    Proposal (TAGBODY-TAG-EXPANSION:NO):

      Clarify items in the body of a TAGBODY are not macroexpanded in
      determining whether they are "tags" or "statements".

    Examples:

      #1: (macrolet ((foo-macro () 'foo))
            (let ((count 0) (foo nil))
              (tagbody
                (foo-macro)
                (when (< count 5) (incf count) (go foo)))))

          This example is in error because (FOO-MACRO) is treated as a "statement"
          rather than as a "tag".  Therefore there is no tag FOO as a target
          of the GO.

      #2: (symbol-macrolet ((foo  (print 'loses)))
            (let ((count 0))
              (tagbody
                foo
                (when (< count 5) (incf count) (go foo)))))

          This example returns NIL without printing anything, because FOO is
          treated as a "tag" rather than as a "statement".

    Rationale:

      This seems to be consistent with current practice.

    Current Practice:

      Lucid CL version 4.0, Allegro CL version 3.1, Chestnut's Lisp-to-C
      translator, and Symbolics Genera all signal an error for test case #1.

    Cost to Implementors:

      Small.

    Cost to Users:

      Probably the only class of programs that would be affected are
      codewalkers.  Codewalkers that produce code in which macro calls are
      replaced with macro expansions need to be careful that things that
      are initially parsed as tagbody "statements" still appear to be
      "statements" in the output of the codewalker.

    Cost of non-adoption:

      Unnecessary confusion in the language standard.  Implementations might
      differ for no good reason.  Without an explicit clarification, people
      writing codewalkers might not realize that this is something they need
      to watch out for.

    Performance impact:

      Probably none.

    Benefits:

      The cost of non-adoption is avoided.

    Esthetics:

      I think the alternatives are worse.

    Discussion:

      This issue doesn't address the questions of whether duplicate tags are
      permitted or whether items that are not symbols, integers, or lists are
      permitted.  It is probably acceptable to leave these unspecified in
      the standard on the assumption that syntax that isn't explicitly
      documented as being meaningful, isn't.

      Kent Pitman says:

        Ugh.  Yes, please count me as a supporter of TAGBODY-TAG-EXPANSION:NO.

      Barry Margolin says:

        I've always been satisfied to treat this as implicitly vague, and I
        tell people to make sure their macros expand into a PROGN form if they
        want to be able to expand into an atom (e.g. expand into (PROGN)
        rather than NIL to do nothing).

      Loosemore notes:

        I think the idea of forcing *every* user-defined macro to deal with
        this lossage is pretty disgusting.  The "right" place to deal with
        this is in the code-walkers that do the parsing of TAGBODY forms.

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