To: J3 J3/25-107 From: generics Subject: Edits for TEMPLATES: Introduction and deferred arguments Date: 2025-February-03 References: 24-125r5, 24-126r4, 24-127r4 Introduction: ============= This is the 1st of 6 papers that provide edits for the approved syntax for templates. Papers 1-5 introduce a new clause titled "Templates" to the standard. Paper 6 includes all other edits outside the new clause. Note that the clause numbering is merely suggestive. The overall ordering of template subclauses will change in future papers. For example, the final order is likely to start with the TEMPLATE construct introduced in the 3rd paper. Section 1: ========== * Insert the following text as a new clause. tt Templates tt.1 Template semantics A template is a scoping unit that is parameterized by deferred arguments and can contain declarations, specifications, and definitions. Instantiation of a template occurs via association of instantiation arguments with deferred arguments and defines non-parameterized instances of entities defined within the template. tt.2 Deferred arguments tt.2.1 Declarations of deferred arguments tt.2.1.1 General A deferred argument is an entity whose identifier appears in a in a template, requirement, or templated procedure. A deferred argument can be a constant, procedure, or type. A deferred argument becomes associated with an instantiation argument through instantiation of a template, requirement, or templated procedure as described in tt.6. A deferred argument declaration statement is used to declare deferred arguments. Rtt02 <> <> <> <> NOTE Deferred arguments are local identifiers and are not externally accessible. tt.2.1.2 Deferred types A deferred type is a deferred argument that can appear in a type specifier within a REQUIREMENT construct, TEMPLATE construct, or templated procedure. Rtt04 <> DEFERRED TYPE[, ] :: Ctt04 (Rtt04) Each shall be the name of a deferred argument of the scoping unit in which the declaration appears. Rtt05 <> ABSTRACT <> EXTENSIBLE Ctt05 (Rtt05) Only one of ABSTRACT or EXTENSIBLE shall appear. Ctt06 (Rtt05) The same shall not appear more than once in a given . Ctt07 The name of a deferred type shall not appear as a in a . Ctt08 A variable of deferred type shall not be a coarray. A deferred type with the EXTENSIBLE attribute is an extensible derived type. A deferred type with the ABSTRACT attribute is an abstract derived type. A deferred type with the ABSTRACT attribute implicitly has the EXTENSIBLE attribute. {UTI: Perhaps we should avoid ever calling deferred arguments "derived types".} NOTE 1 A deferred type cannot be extended. The use of the term "extensible" is to imply a restriction on the associated instantiation argument. NOTE 2 Even with the EXTENSIBLE attribute, a deferred type cannot be constructed because it has unspecified components and type parameters within the template. NOTE 3 Examples of deferred type declarations are: DEFERRED TYPE :: T1 DEFERRED TYPE, EXTENSIBLE :: T2 DEFERRED TYPE, ABSTRACT :: T3 NOTE 4 The distinction between deferred types that are extensible or not, and deferred types that are abstract or not, helps to ensure a processor can verify a template is internally consistent. For example, a deferred type cannot be used in a CLASS declaration if it might be instantiated as INTEGER. Likewise, a deferred type cannot be used in a TYPE declaration if it might be instantiated with an abstract derived type. Using the deferred type declarations from NOTE 3, the following examples of type declaration statements are valid or invalid as marked: TYPE(T1) :: A1 ! Valid CLASS(T1) :: A2 ! Invalid TYPE(T2) :: B1 ! Valid CLASS(T2) :: B2 ! Valid TYPE(T3) :: C1 ! Invalid CLASS(T3) :: C2 ! Valid NOTE 5 Variables of deferred type are not permitted to be coarrays because it is invalid to coindex a variable that has polymorphic ultimate components, and instantiation arguments are permitted to have polymorphic ultimate components. Straightforward workarounds are possible using deferred procedures. { Future work could relax Ctt08 while introducing a "intrinsic requirement" that specifies that the type does not have allocatable components. And this would be checked at instantiate. } tt.2.1.3 Deferred constants A deferred constant is a deferred argument that can appear in constant expressions within a REQUIREMENT construct, TEMPLATE construct, or templated procedure. Rtt06 <> DEFERRED , :: Rtt07 <> DIMENSION() <> PARAMETER <> Rtt08 <> [ ( ) ] Ctt09 (Rtt06) The shall include PARAMETER. Ctt10 (Rtt07) An entity declared in shall be INTEGER, LOGICAL, or assumed-length CHARACTER. Ctt11 (Rtt08) Each shall be the name of a deferred argument of the scoping unit in which the declaration appears. Ctt12 (Rtt06) If appears in , it shall be , , , or . Ctt13 (Rtt06) If , or appears in , then shall not be specified. Ctt14 (Rtt06) If appears in , then shall not appear as a lower bound. NOTE 1 Deferred constant arrays always have default lower bounds. This restriction ensures consistency of lower-bounds when reusing requirements. { Subgroup prefers to disallow explicit confirmation of default lower bounds because we envision that there may be a useful distinction to be made in the future between specified lower bounds and default lower bounds. } NOTE 2 Examples of deferred constant declarations are: ! explicit shape DEFERRED INTEGER, PARAMETER :: x1 DEFERRED INTEGER, PARAMETER :: x2(3) DEFERRED INTEGER, PARAMETER :: v1(2) = [5,15] ! not a deferred constant DEFERRED INTEGER, PARAMETER :: x3(v1) ! implied shape DEFERRED INTEGER, PARAMETER :: x4(*) DEFERRED INTEGER, PARAMETER :: x5(*,*) DEFERRED INTEGER, PARAMETER, RANK(2) :: x6 ! assumed-or-implied-rank-spec DEFERRED INTEGER, PARAMETER :: x7(..) tt.2.1.4 Deferred procedures A deferred procedure is a deferred argument that can appear as the procedure designator of a procedure reference within a REQUIREMENT construct, TEMPLATE construct, or templated procedure. A deferred procedure's interface is established in that construct by its appearance in a or as the or of an that appears in a deferred interface block. Rtt09 <> DEFERRED PROCEDURE() [ :: ] Ctt15 (Rtt09) Each shall be the name of a deferred argument of the scoping unit in which the declaration appears. Ctt16 Each or of an that appears in a deferred interface block shall be the name of a deferred argument of the scoping unit in which the appears. NOTE 1 The interface of a deferred procedure may be defined in terms of other deferred arguments. NOTE 2 The following example declares deferred procedures F, S, and G. The declaration of G is in terms of an interface F_I. DEFERRED TYPE :: T DEFERRED INTERFACE FUNCTION F(X) TYPE(T), INTENT(IN) :: X TYPE(T) :: F END FUNCTION SUBROUTINE S(Y) TYPE(T), INTENT(INOUT) :: Y END SUBROUTINE END INTERFACE DEFERRED PROCEDURE(F_I) :: G ===END=== { Further work: We should come up with and use an "association" term. Malcolm's preferred term was "instantiation association" or "template association". I like "instantiation association". "deferred argument association" is also an option. Malcolm said it was okay but a mouthful. }