To: J3 J3/25-194r1 From: Malcolm Cohen Subject: US08 Polymorphic PURE function results, edits Date: 2025-October-27 Reference: 23-186, 25-116r1, 25-178 1. Introduction This paper contains the edits for US08, Polymorphic PURE function results. The specifications and syntax are from 25-116r1 and 25-178. 3. Edits to 25-007r1. [xv] Introduction, p2, Data declaration bullet, insert: "A type can be declared to have the PURE attribute; such a type can be used for the result of a polymorphic pure function, for a polymorphic allocatable component in the result of a pure function, or for a polymorphic INTENT (OUT) argument of a pure procedure. Similarly, a type can be declared to have the SIMPLE attribute, with corresponding usages in simple procedures." [30:4+] 3 Terms and definitions, after 3.144.10 parent type, insert new definitions: "3.144.10a pure type type with the PURE attribute Note 1 to entry: The PURE attribute for types is described in \ref{D4:Pure and simple types}. 3.144.10b simple type type with the SIMPLE attribute Note 1 to entry: The SIMPLE attribute for types is described in \ref{D4: Pure and simple types}." {Index "PURE attribute" and "SIMPLE attribute", hyperlinked to the subclause \ref{D4: Pure and simple types}, which will be 7.5.2.4.} COMMENT: I was unconvinced that we needed these to be terms, but it is how we did "abstract type" so consistent in style. [80:22+] 7.5.2.1 Syntax of a derived-type definition, R728 type-attr-spec, append new productions: "or PURE or SIMPLE". {Index keywords PURE and SIMPLE here as definitions.} [81:8+] Same subclause, immediately before R729 private-or-sequence, insert new constraints: "C742a If the PURE or SIMPLE type-attr-spec appears in a derived-type-stmt, BIND(C) shall not appear. If the PURE type-attr-spec appears, SIMPLE shall not appear. C742b If EXTENDS appears in a derived-type-stmt and parent-type-name denotes a \ref*{pure type}, the PURE or SIMPLE type-attr-spec shall appear in that statement. C742c If EXTENDS appears in a derived-type-stmt and parent-type-name denotes a \ref*{simple type}, the SIMPLE type-attr-spec shall appear in that statement. C742d The SEQUENCE statement shall not appear in the definition of a \ref*{pure type} or \ref*{simple type}." {Hyperlink and index keywords that appear in the constraints. "\ref*" means reference and link to the definition (of "pure type" or "simple type"); the editor should make new macros for these links.} [81:22-] Immediately before 7.5.2.3 Sequence type, insert new subclause at the same level (renumbering the existing 7.5.2.3 and 7.5.2.4): "7.5.2.3 Pure and simple types The PURE type-attr-spec specifies that the type is a \defn*{pure type}. The SIMPLE type-attr-spec specifies that the type is a \defn*{simple type}. A simple type is also a pure type. C744a A \termi{final subroutine} of a pure type shall be a \termii{pure}{procedure}. A \termi{final subroutine} of a \termi{potential subobject component} of a pure type shall be a \termii{pure}{procedure}." {All the "\term" macros hyperlink to and index the term in Clause 3. As we are within the subclause for pure types, "pure type" itself will not be hyperlinked or further indexed.} "C744b The \termii{declared}{type} of a \termi{polymorphic} \termi{potential subobject component} of a pure type shall be pure. C744c A \termi{potential subobject component} of a pure type shall not be a \termi{coarray}. C744d A *1{type-bound} \termi{defined assignment} procedure of a pure type, or a potential subobject component thereof, shall be a \termii{pure}{procedure}." {Here, "*1{type-bound}" actually means to produce the text and to index as "type-bound procedure" and "procedure!type-bound", which is achieved by \termiix{type-bound}{procedure}{type-bound}.} "C744e If a pure type has a \termii{parent}{type} that is not pure, the \termii{parent}{type} shall satisfy constraints C744a-C744e as if it were a pure type." {Requiring a non-pure parent type to satisfy C744e recursively requires every ancestor type to satisfy C744a-C744e.} C744f A \termi{final subroutine} of a simple type shall be a \termii{simple}{procedure}. A \termi{final subroutine} of a \termi{potential subobject component} of a simple type shall be a \termii{simple}{procedure}. C744g The \termii{declared}{type} of a \termi{polymorphic} \termi{potential subobject component} of a simple type shall be simple. C744h A \termi{potential subobject component} of a simple type shall not be a \termi{coarray}. C744i A *1{type-bound} \termi{defined assignment} procedure of a simple type, or a potential subobject component thereof, shall be a \termii{simple}{procedure}." {See C744d for what *1 signifies.} "C744j If a simple type has a \termii{parent}{type} that is not simple, the \termii{parent}{type} shall satisfy constraints C744f-C744j as if it were a simple type." {Requiring a non-simple parent type to satisfy C744j recursively requires every ancestor type to satisfy C744f-C744j.} "NOTE 1 There is no constraint on a pointer component of a pure or simple type, as those are not potential subobject components. NOTE 2 A nonpolymorphic component of a pure or simple type can be of any type whose usage does not cause execution of an impure or non-simple final subroutine or defined assignment. For example, using the derived type defined in 7.5.2.1, NOTE: TYPE, PURE :: GROUP TYPE(PERSON), ALLOCATABLE :: MEMBERS(:) END TYPE" {This follows directly from the lack of constraint, but it is good to have the consequence explicitly stated rather than relying on the reader to notice the dog that didn't bark in the night. Continuing with NOTE 2...} "Such a component cannot be directly polymorphic, but by defining a pure extension of the type, polymorphism can be enabled: TYPE, SIMPLE, EXTENDS(PERSON) :: SIMPLE_PERSON END TYPE TYPE, PURE :: EXTENDED_GROUP CLASS(SIMPLE_PERSON),ALLOCATABLE :: MEMBERS END TYPE" [371:19-20] 15.7 Pure procedures, C1594, Replace the entirety of C1594, which is "C1594 The function result of a pure function shall not be both polymorphic and allocatable, or have a polymorphic allocatable ultimate component." with the following two constraints "C1594 If the function result of a pure function is both polymorphic and allocatable, its declared type shall be pure. C1594a If the function result of a pure function has a polymorphic allocatable ultimate component, the declared type of the function result shall be pure." {Maintain indexing and hyperlinking that already exists here. In "shall be pure", index "pure" as if it were "pure type".} COMMENT: These constraints could be combined into one long sentence, but I think it is clearer this way. [371:25-26] Same subclause, replace the entirety of constraint C1597, which begins "An INTENT (OUT) dummy argument of a pure procedure shall not be polymorphic...", with "C1597 If an INTENT (OUT) dummy argument of a pure procedure is polymorphic, or has a polymorphic allocatable ultimate component, the declared type of the dummy argument shall be pure." {Same indexing instructions as before.} [373:1-] Same subclause, after NOTE 5, viz immediately before 15.8, insert "NOTE 6 This is a simple example of a pure procedure. MODULE threshold_test REAL :: tolerance = 1.0E-4 CONTAINS PURE LOGICAL FUNCTION within_tolerance(expected, received) REAL, INTENT (IN) :: expected, received IF (received>expected) THEN within_tolerance = (received/(1+tolerance))<=expected ELSE within_tolerance = (expected/(1+tolerance))<=received END IF END FUNCTION END MODULE NOTE 7 A pure function can have a polymorphic result if the declared type is pure or simple. For example, TYPE, PURE :: extensible_rational ... CONTAINS PROCEDURE er_add_er GENERIC :: OPERATOR(+) => er_add_er END TYPE ... PURE FUNCTION er_add_er(a, b) RESULT(r) CLASS(extensible_rational), INTENT (IN) :: a, b CLASS(extensible_rational), ALLOCATABLE :: r IF (EXTENDS_TYPE_OF(a, b)) THEN r = b ... \textit{code to add the value of a to r} ELSE r = a ... \textit{code to add the value of b to a} END IF END FUNCTION" {The first NOTE here is an editorial change, as there was no example in this subclause.} [373:14+] 15.8 Simple procedures, immediately before the first constraint C15111, insert new constraints: "C15110a If the function result of a simple function is both polymorphic and allocatable, its declared type shall be simple. C15110b If the function result of a simple function has a polymorphic allocatable ultimate component, the declared type of the function result shall be simple. C15110c If an INTENT (OUT) dummy argument of a simple procedure is polymorphic, or has a polymorphic allocatable ultimate component, the declared type of the dummy argument shall be simple." {Index and hyperlink everything in sight.} [374:5+] Insert NOTEs. "NOTE 1 A value returned by a simple function, or assigned to an argument by a simple subroutine, can depend on other argument or global state such as the current IEEE rounding mode (\ref{D14:The rounding modes}), but it cannot depend on the value of a data object that is not accessible via the argument list. This can help to create parallelization and optimization opportunities. NOTE 2 This is a simple example of a simple function. REAL SIMPLE FUNCTION F (A, B, C) REAL, INTENT (IN) :: A, B, C F = SQRT(A**2 + B**2 + C**2) END FUNCTION" {Editorial change: this subclause was missing rationale and examples. These are not correlated with the feature this paper adds.} ===