Cleanup Issue TAGBODY-CONTENTS

Category
CLARIFICATION
References
TAGBODY (pp 130-131 of CLtL)

Problem Description

CLtL specifies that symbols and integers are valid tags in a TAGBODY and that lists are valid forms in a TAGBODY but is silent about other data types.

Also, NIL is both a symbol and a list. Some implementations might permit (GO NIL) because they treat NIL as a tag, while others might not permit because they treat NIL as a form.

Proposal (FORBID-EXTENSION)

A TAGBODY's body may contain arbitrary data elements; no constraints are placed on duplication of those elements. duplications. Elements that are lists (CONSP) are evaluated in left-to-right order. Any other elements are ignored by TAGBODY. However, GO is only legal when the given a tag that is a symbol or integer. The results of executing GO when there is more than one instance of the same (EQL) tag at the top level of the innermost TAGBODY containing that tag are unspecified.

In particular it is an error to use a character, floating point number, ratio or other data element as a tag to GO.

The same restrictions apply to all forms which implicitly use TAGBODY, such as PROG and DO.

Examples

;; legal, but useless
     (TAGBODY 3.4 4.5 (print "hi there"))

;; not legal
(tagbody
        (ecase char (#\a (go #\a)) (#\b (go #\b)))
        #\a (print "Apple")
        #\b (print "Ball"))

;;legal, even when args are NIL:
     (defmacro foo1 (&rest args)
       `(do () ((test-fn))
          ,(when (member :bar args) '(do-bar-thing))
          ,(when (member :baz args) '(do-baz-things))
          (do-regular-things)))

;; legal, but bad style
     (do (...)
         (...)
         -----
         (...)
         (...)
         -----
         (...))

Rationale

The proposed set of tags is expressionally adequate.

Other candidate types have lurking problems that could lead to subtle program bugs if permitted as tags. For example,

- Characters make bad tags because, for example, (TAGBODY ... #\Return ... #\Newline ...) will be an error in some implementations due to (EQL #\Return #\Newline).

- Floats make bad tags because round-off error will vary between implementations.

- Rationals have problems with reduction to lowest terms. eg, (EQL 1/2 2/4). This doesn't vary between implementations but may still cause surprises.

Duplicated tags are permitted in situations where no GO is done to them; it is not our intent particularly to encourage the practice. . But current practice is to permit such uses in many implementations, and there was no driving reason to force such code to break.

Current Practice

Symbolics Genera documents that only symbols or integers are permitted. The restriction is enforced by the compiler, but not the interpreter.

The TI Explorer permits using NIL as a GO tag, but as a special case, does not warn about multiple appearances of NIL.

Many implementations allow duplicate tags if there is no GO to them.

Cost to Implementors

A few simple checks are probably all that's needed. Probably most implementations (both interpreters and compilers) already perform them. Implementations that disallow duplicate tags (generally in the compiler but not the interpreter) will have to remove the error checks.

Cost to Users

Unlikely to affect any portable code.

If there are implementations which support other objects as tags (floats, for example), other (likely minor) changes will be necessary.

Benefits

One less place for portability problems to occur.

Aesthetics

Makes the language description more precise.

Discussion

This issue was first included in in ">GLS>clarifications.text" of 12/06/85.

Historical Note (JonL, Steele):

The reason pdp10 MacLisp allowed numbers, including flonums, as tags was that Ira Goldstein's LLOGO (a LOGO system written entirely in Lisp) just used READ for the statement numbers, and they looked like floats; e.g., 1.1, 1.2, ... etc.

Edit History