To: J3 J3/25-153r1 From: Malcolm Cohen Subject: US08 Polymorphic PURE function results, edits Date: 2025-June-24 Reference: 23-186, 25-116r1 1. Introduction This paper contains the edits for Fortran 2028 proposal US08, allowing pure functions to have polymorphic results. Requirements, Specifications, and Syntax are all in 25-116r1. 2. Edits to 25-007 [xv] Introduction, Data declaration bullet, insert sentence: "A derived type can be given the PURE or SIMPLE attribute; such a type has restrictions that ensure it is usable in pure or simple procedures, respectively." {NOTE to J3: This "enforced usability" effect applies equally to non- polymorphic entities, so is slightly different from the main effect of the feature. That said, it is pretty minor, so we could omit this edit without great loss.} [xv] Introduction, Program units and procedures bullet, insert sentence: "A polymorphic entity whose declared type has the PURE or SIMPLE attribute can be used within, or as the function result of, a pure or simple procedure, respectively." {NOTE to J3: Explain the main feature.} [79:22+] 7.5.2.1 Syntax of a derived-type definition, R728 type-attr-spec, append two new productions: "or PURE or SIMPLE" Index both these keywords as attribute definitions, but not as hyperlink targets - existing hyperlinks for PURE and SIMPLE should continue to be the ones in Clause 15 Procedures. If no other paper adds a new type-attr-spec, that makes the whole rule: type-attr-spec is ABSTRACT or access-spec or BIND (C) or EXTENDS ( parent-type-name ) or PURE or SIMPLE [79:25+] Same subclause, after C735 "The same type-attr-spec...", insert new constraints: "C735a If the \si{type-attr-spec} PURE or SIMPLE appears in a \si{derived-type-stmt}, BIND(C) shall not appear in the statement. If PURE appears, SIMPLE shall not appear." {NOTE to J3: I might just do "PURE or SIMPLE attribute" instead of using the BNF term. That would probably be easier to read.} Edit continues: "C735b If EXTENDS appears in a \si{derived-type-stmt} and the parent type is a \ref*{pure type}, the PURE or SIMPLE \si{type-attr-spec} shall appear in the statement." {NOTE to J3: The wording "has the PURE attribute" might be better than "is a pure type"?} Edit continues: "C735c If EXTENDS appears in a \si{derived-type-stmt} and the parent type is a \ref*{simple type}, the SIMPLE \si{type-attr-spec} shall appear in the statement. C735d If the \si{type-attr-spec} PURE or SIMPLE appears in a \si{derived-type-stmt}, the SEQUENCE statement shall not appear in that type definition." [82:1-] Just before 7.5.3 Derived-type parameters, insert new subclause "7.5.2.5 Pure and simple types The PURE \si{type-attr-spec} specifies that the type is a \defn*{pure type}. The SIMPLE \si{type-attr-spec} specifies that the type is a \defn*{simple type}; a simple type is also a pure type. C745a A final subroutine of a \ref*{pure type} shall be pure. A final subroutine of a potential subobject component of a pure type shall be pure. C745b The declared type of a polymorphic potential subobject component of a pure type shall be pure. C745c A potential subobject component of a pure type shall not be a coarray. C745d A type-bound defined assignment procedure of a pure type shall be pure. A type-bound defined assignment procedure of a nonpointer component of a pure type shall be pure." {NOTE to J3: The second sentence of C745d did not appear in the syntax paper, but seems necessary for this to work.} Edit continues: "C745e An ancestor type of a pure type that is not itself pure shall satisfy constraints C745a-C745d as if it were pure." C745f A final subroutine of a \ref*{simple type} shall be simple. A final subroutine of a potential subobject component of a simple type shall be simple. C745g The declared type of a polymorphic potential subobject component of a simple type shall be simple. C745h A potential subobject component of a simple type shall not be a coarray. C745i A type-bound defined assignment procedure of a simple type shall be simple. A type-bound defined assignment procedure of a nonpointer component of a simple type shall be simple. C745j An ancestor type of a simple type that is not itself simple shall satisfy constraints C745f-C745i as if it were simple." {Note to the editor: the usages in these constraints of pure and simple referring to a procedure being pure or simple should be hyperlinked to our usual pure/simple terms.} Edit continues: "NOTE 1 A nonpolymorphic component of a pure or simple type can be of a type that is not pure or simple, as long as that type does not have impure (or nonsimple when the containing type is simple) type-bound defined assignment. An intrinsic type is not considered to be pure or simple, even though it satisfies the requirements re final and assignment. That is because cannot be the declared type of a polymorphic entity, so calling an intrinsic type pure or simple would have no effect. NOTE 2 Here is an example of a pure type definition. A useful definition would have a lot more type-bound operators. TYPE, PURE :: rational INTEGER numerator, denominator CONTAINS PROCEDURE :: rat_asgn_i GENERIC :: ASSIGNMENT(=) => rat_asgn_i END TYPE ... PURE SUBROUTINE rat_asgn_i(a, b) CLASS(rational), INTENT(OUT) :: a INTEGER, INTENT(IN) :: b a%numerator = b a%denominator = 1 END SUBROUTINE Given this example, the following pure function can be defined. PURE FUNCTION new_rational(num, dem, mold) RESULT(new) CLASS(rational), ALLOCATABLE :: new INTEGER, INTENT(IN) :: num, dem CLASS(rational), OPTIONAL :: mold IF (PRESENT(mold)) THEN new = mold ELSE ALLOCATE(new) END IF new%numerator = num new%denominator = dem END FUNCTION " {NOTES to J3: - The macro \defn* creates a new definition, indexed in bold. - The macro \ref* indexes it (not bold) and hyperlinks to the definition. - Both of them put the argument into the standard as is. - If anyone has a better (not any longer, please) example, please suggest it. - If someone has a long example which they think is useful, we could put that in Annex C, with a sentence in NOTE 2 linking to it.} {NOTE to the editor: in Clause 15, hyperlink pure/simple for types to our new Pure and simple types subclause.} [370:19-20] 15.7 Pure procedures, constraint C1594 which begins "The function result... polymorphic..." Replace whole constraint with "C1594 If the function result of a pure function is both polymorphic and allocatable, it shall have a declared type that is pure. If it has a polymorphic potential subobject component, the component shall have a declared type that is pure." {NOTE: "declared type with the PURE or SIMPLE attribute" also works, and would avoid using "pure type" outside of 7.2.5.2. NOTE: The existing constraint used "polymorphic allocatable ultimate", and this is *WRONG*, as an intervening allocatable component would deactivate the constraint while still permitting side-effects.} [370:25-26] Same subclause, constraint C1597 which begins "An INTENT (OUT) dummy argument... polymorphic..." Replace whole constraint with two constraints: "C1594 If an INTENT (OUT) dummy argument of a pure procedure is polymorphic, it shall have a declared type that is pure. C1594a If an INTENT (OUT) dummy argument of a pure procedure has a polymorphic potential subobject component, the component shall have a declared type that is pure." {NOTE: Separating into two because C1594a operates when the argument is not polymorphic, i.e. the situations are mutually exclusive. That's because when it is polymorphic, C1594 already requires polymorphic subobjects to be have a pure declared type. NOTE: The original constraint also suffered from the polymorphic allocatable ultimate defect. NOTE: Could use "type with the PURE or SIMPLE attribute" here too. I won't say this again for the following edits.} [371:20-21] Same subclause, constraint C15106 "A statement that might...", Replace whole constraint with "C15106 If a statement that might result in the deallocation of a polymorphic entity appears in a pure procedure, the entity shall have a declared type that is pure." [373:5+] 15.8 Simple procedures, after C15117 "A simple... ENTRY...", insert new constraints: "C15117a If the function result of a simple function is both polymorphic and allocatable, it shall have a declared type that is simple. C15117b If the function result of a simple function has a polymorphic potential subobject component, the component shall have a declared type that is pure. C15117c If an INTENT (OUT) dummy argument of a simple procedure is polymorphic, it shall have a declared type that is simple. C15117d If an INTENT (OUT) dummy argument of a simple procedure has a polymorphic potential subobject component, the component shall have a declared type that is simple. C15117e If a statement that might result in the deallocation of a polymorphic entity appears in a simple procedure, the entity shall have a declared type that is simple." ===END===