To: J3 J3/18-256r1 From: Dan Nagle & Malcolm Cohen Subject: enums Date: 2018-October-18 Reference: 18-256, 18-114r1 1. Introduction This paper is a response from /DATA subgroup. A more concrete form of enumeration type is proposed. Several open questions remain. 2. Answers to question in 18-256 >Should enums provide n-way choice ? (n > 2) Subgroup did not understand what was meant by this question. The basic idea is that "enums" should be a facility that provides user-defined types, and each such type has a finite number (at least one) explicitly-named value. Subgroup considers that the "group of named integer constants" role is basically convered by the existing ENUM,BIND(C) facility. Although there are some minor improvements that could be made to that facility, subgroup considers that the greater need is for "proper" enumerations types. >If enums are case expressions, must all select case branches be covered ? No. We don't even require this for LOGICAL type, so of course we would not require such a thing in the standard. Producing annoying messages is a matter of Quality of Implementation. >Are enums inter-convertible with integers ? Yes, but not "magically inter-convertible". All conversions must be explicit. Subgroup proposes that: When there are N enumeration values in a particular enumeration type, INT(e) should return a value in the range 1 to N, and ENUMTYPE(i) should return the i^th enumeration value. It would be an error for ENUMTYPE to be called with an out of range value. Although INT(e) returns the order in which the enumeration names were specified, subgroup considers that they should not be considered to be "ordered" in the traditional sense, and that therefore equality operations (== and /=) should be available, but relational (< <= > >=) operators should not be. >What new formats will enums need ? > >Will integer formats be used for enums? Writing an enumeration value as an integer will be adequately provided by writing INT(e). Subgroup considers that the most usable form for i/o for an enumeration value is the name of the value. Being a name, the A edit descriptor would be suitable for explicit formatting. (That was the majority view. A minority view considered that this was too much machinery to require, and that the user should write their own i/o procedures, perhaps using defined i/o, or perhaps using the own "enum_to_string" procedure, if they wanted to do i/o.) Possible straw vote: Should i/o for enumeration values (a) use the name of the value, and A editing (b) not be allowed (c) something else (subgroup is all ears). >What integer intrinsic procedures will enums use ? None. INT will be available as a "conversion to integer" function, and ENUM_TYPE(i), which looks rather like a constructor, will be available as a "conversion from integer" function. That's it. >Should enums provide kind values (per type) ? No. >Should enums provide logical units ? No. >Should enums number the processor's error messages ? No. >Are enums allowed to subscript arrays ? No. If you want to use an enumeration value E as a subscript, use INT(E). >Must all enum values have a name ? By definition. >What new intrinsics will enums need ? Subgroup considers that providing intrinsics named NEXT, PREV, FIRST and LAST is a rather uncomfortable intrusion into the user namespace. It would be better if these were inherently-defined type-bound functions instead, e.g. given TYPE(enum_type) x then x%next() would return the next enumeration value from whatever the value of x is. etc. We could straw vote this now, but maybe better to wait until a more complete proposal is available. After all, changing the edits from doing type-bound functions into intrinsics with the same names would not be difficult, should that be the committee preference. >If I can make a mess of the enum values, can I check easily? The user cannot make a "mess" of the enum values, because a proper enumeration is not a group of named integer constants, but a set of named enumeration values. This set being ordered by the order of declaration in the few places where it matters. 3. Illustrative examples Note: This syntax is not being proposed at this time, but is merely one of the possible syntaxes under consideration. TYPE,ENUM :: e_type ENUMERATOR :: e_one, e_two ENUMERATOR :: e_fred END TYPE TYPE(e_type) x x = e_type(1) ! assigns e_one to x x = x%next() ! assigns e_two to x x = x%last() ! assigns e_fred to x x = x%first() ! assigns e_one to x PRINT *,INT(x) ! prints the value "1" PRINT *,x ? Maybe prints "e_one". ... DO x = x%first(),x%last() ! Loops over all the values of e_type. ... END DO ! x is undefined on loop exit. 4. Further witter (a) The form "ENUMERATOR :: whatever = integer" is simply not available. Such a form is suitable for C-style "bunch of integer constants", so we consider than BIND(C) enums satisfy such purposes. (b) It will be noted that the example proposes allowing DO loops to range over an enumeration, in order of declaration of the values. This is of course not essential, but does seem natural and useful. 5. Other open questions Some subgroup members preferred that enumeration values be accessible, or even only be accessible, when qualified by the type name. The reason is to reduce namespace collisions when multiple enumeration types with large sets of values are in use. Thus with the definition of TYPE(e_type) above, instead of the values of the type being available as e_one, e_two, and e_fred, they would be accessed as e_type%e_one, e_type%e_two, and e_type%e_fred. (Other subgroup members considered that the existing collision-handling method of USE renaming was adequate, as was also the good coding practice of prefixing such names with an informative prefix. We have never had the form "type_name % anything" before, so this form would be new.) Possible straw vote: enumeration value names should be used as (a) the bare names e.g. "e_fred", like C and Pascal, (b) the type-qualified names e.g. "e_type%e_fred", like C++, (c) both, (d) undecided. ===END===