TAGBODY-CONTENTSTAGBODY 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.
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.
;; 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 (...)
(...)
-----
(...)
(...)
-----
(...))
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.
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.
If there are implementations which support other objects as tags (floats, for example), other (likely minor) changes will be necessary.
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.