To: J3 J3/19-230r2 From: Van Snyder & Malcolm Cohen Subject: Formal Requirements for True Enumeration types Date: 2019-October-15 Reference: 18-114r1 18-256r1 19-216r1 0. Changes as a result of straw votes 2019-10-15: B. Are enumeration types extensible? Yes, no, indifferent: 4-7-5. D. May a default initial value be provided for variables of an enumeration type, there is no way to provide an initial value, an initial value must be specified, indifferent: 13-0-1-2. 1. Introduction This paper contains the proposed formal requirements for enumeration types (proposal US21). These have been extracted from 19-216r1, which mixes together requirements and specifications, and reworded. It is not necessary to read any of the referenced papers. To this end, this paper contains also a Background section and a Use cases section. 2. Background Many programming languages have enumeration types because they are perceived to be useful. C has "fake" enumeration types; an enumeration type is merely an alias for a processor-dependent integer type. Enumerator names are class one names, i.e. clash with variable/function/type names etc. However, even though the type is merely an integer type, it is not uncommon for a C compiler to treat it specially, in particular, producing warning messages for anomalous usages. ENUM,BIND(C) provides enumerators that interoperate with a C enumeration type. As Fortran does not have type aliasing, the consequent type specifier is the rather clunky INTEGER(KIND(one of the enumerators)). This clunkiness makes it harder for a Fortran compiler to produce a warning message for an anomalous usage. Multiple other languages, such as Pascal, Modula-2, and Ada, have "proper" enumeration types; these act like independent types and generally do not allow assignment between each other or from integers. This approach is believed to be safer than the "fake" approach, without losing significant functionality or performance. 3. Some use cases (a) A true enumeration type can be emulated with, for example, TYPE enum INTEGER,PRIVATE :: value END TYPE TYPE(enum),PUBLIC,PARAMETER :: a = enum(1), b = enum(2), c = enum(3) however this is rather tedious to set up, and fragile if additional enumerators are required. However, the resultant type does provide the same functionality (and type safety) of a true enumeration type. (b) Fake enumeration types are provided by ENUM,BIND(C). Apart from the general clunkiness, the implication of the syntax that the program is interoperating with C is inappropriate for a pure Fortran program (or where the enumerator is only for use on the Fortran side of a mixed-language program). True enumeration types reduce errors in the following cases: (i) In argument association, e.g. SUBROUTINE s(a,b,c) if a, b, and c are of fake enumeration type, there is no protection against getting the actual argument order wrong. (ii) Type-safe expressions avoid doing silly things like multiplying an enumeration type by a complex value. (iii) Type-safe assignment avoids assigning the wrong enumeration type to another. Finally, true enumeration types provide (iv) generic resolution. 4. Formal requirements A. Named enumeration types shall be provided. An enumeration type shall not be an alias for any other type, but is (and defines) an ordered set of named enumerators. B. [removed extensibility] C. To the greatest extent reasonably possible, a variable of enumeration type should not become undefined, or indeed become defined with an out of range (impossible) value. (This is partly a meta-requirement, as it inspires requirement D.) D. An enumeration type may specify a default value, so that a variable or component of that enumeration type will not be initially undefined (and will not be undefined on allocation, INTENT(OUT) association, etc). This default value shall operate following the same rules as default initialisation for components. E. The type of an enumerator is the enumeration type that defines it. F. The name of an enumerator must be unique within the enumeration type, but may be the same as the name of an enumerator of another type. Some mechanism shall allow access to both enumerators from a scope. G. It shall be possible, under suitable circumstances, to denote an enumerator without needing to qualify it by the enumeration type name. H. Variables, named constants, structure components, and functions may be of an enumeration type. I. Intrinsic assignment shall be defined for enumeration type. J. All intrinsic relational operations shall be defined for an enumeration type, with both operands being the same enumeration type and the result as if comparing the ordinal values. No other intrinsic operations shall be defined for an enumeration type. K. Some mechanism must provide for conversion from an enumeration value to the integer value corresponding to its ordinal number (the first enumerator corresponds to integer value one). Some mechanism must provide for conversion from an integer value to the enumeration value with that ordinal number. L. Given an enumeration type (or possibly an entity of that type), some mechanism(s) shall provide the first and last enumerator values of the type. The mechanism for providing the first enumerator value shall not require conversion from integer value one. M. Given an enumerator value (which may be a variable), some mechanism shall be provided to produce the "next" or "previous" value. This mechanism shall not require manual conversion to/from integer. N. Input and output of enumeration types shall be provided. O. Enumeration types shall be usable as a SELECT CASE selector. P. DO loop control shall be able to use enumerations. ===END===