To: J3 J3/23-102r1 From: T. Clune & subgroup generics Subject: Formal syntax for generics Date: 2023-February-21 Reference: 22-120r5, 22-151r3, 22-154r5 UTI: Is existing BNF for subprograms sufficient for template subprograms and variables/expressions that depend on deferred entities. 1. Introduction =============== This paper contains the syntax for generic programming features. Section 2 contains a succinct, non-pedagogical example that exercises most of the proposed syntax. Section 3 provides the formal syntax and is further broken into the following subsections: 3.1 Deferred entities 3.1.1 Syntax for deferred arguments 3.1.2 Deferred argument association 3.2 Syntax for the REQUIREMENT construct 3.2.1 Requirement interface body 3.3 Syntax for the REQUIRES statement 3.4 Syntax for the TEMPLATE construct 3.4.1 Template specification part 3.4.2 Template subprogram part 3.4.3 Additional constraint 3.5 Syntax for the INSTANTIATE statement 2. Example ========== MODULE A REQUIREMENT R(T,F) TYPE, DEFERRED :: T FUNCTION F(x, i) RESULT(y) TYPE(T) :: y TYPE(T), INTENT(IN) :: x INTEGER, INTENT(IN) :: i END FUNCTION END REQUIREMENT TEMPLATE B(T,F,C) REQUIRES R(T,F) ! provides interface for deferred F TYPE, DEFERRED :: T ! redundant confirmation of T INTEGER, CONSTANT :: C(..) ! deferred rank constant CONTAINS SUBROUTINE SUB(x, i) TYPE(T), INTENT(INOUT) :: x INTEGER, INTENT(IN) :: x x = F(x, SUM(C)) END SUBROUTINE SUB END TEMPLATE B END MODULE A MODULE B USE MODULE A TYPE :: MY_TYPE REAL :: val END TYPE INSTANTIATE B(MY_TYPE, POWER, [3,4]), ONLY: my_sub => sub CONTAINS FUNCTION POWER(x, i) RESULT(y) TYPE(MY_TYPE) :: y TYPE(MY_TYPE), INTENT(IN) :: x INTEGER, INTENT(IN) :: i y%val = x%val ** i END FUNCTION SUBROUTINE DO_SOMETHING(x, n) TYPE(MY_TYPE), INTENT(INOUT) :: x INTEGER, INTENT(IN) :: n INTEGER :: i DO i = 1, n CALL my_sub(x, i) END DO END SUBROUTINE END MODULE B 3. Formal Syntax ================ 3.1 Deferred entities -------------------- A deferred entity is an entity, some aspects of which are deferred. A deferred entity may appear in a REQUIREMENT or TEMPLATE construct (3.2, 3.3). Association with non-deferred entities occurs in the INSTANTIATE and REQUIRES statements. A deferred constant is a deferred entity that can appear in constant expressions with a REQUIREMENT or TEMPLATE construct. A deferred type is a deferred entity that can appear as a type-spec within a REQUIREMENT or TEMPLATE construct. A deferred procedure (3.4.3) is a deferred entity that can appear in procedure references within a REQUIREMENT or TEMPLATE construct. A deferred procedure's interface shall be defined by that REQUIREMENT or TEMPLATE construct, possibly in terms of deferred types and constants. 3.1.1 Syntax for deferred arguments ----------------------------------- A deferred argument declaration construct is used to declare REQUIREMENT or TEMPLATE arguments. <> <> <> <> <> <> , :: <> [,]... CONSTANT [,]... <> CONTIGUOUS <> <> Constraint: An entity declared in shall be INTEGER, LOGICAL, or assumed-length character. <> Constraint: Each shall appear in a . <> PROCEDURE[()] :: <> Constraint: Each that appears in a shall appear in . Constraint: Each must appear in a or as a or within an or a . Constraint: shall not apper in within a . <> TYPE, DEFERRED :: <> Constraint: Each shall appear in . Constraint: A declaration shall not have an nor shall it appear in a PUBLIC statement. Note: Deferred arguments are local identifiers and are not externally accessible. 3.1.2 Deferred argument association ----------------------------------- Actual deferred arguments are specified by either an INSTANTIATE or a REQUIRES statement. <> [ = ] Constraint: Each shall be the name of a in the referenced requirement or template. In the absence of an argument keyword, an actual deferred argument corresponds to the dummy deferred argument occupying the corresponding position in ; that is, the first actual deferred argument corresponds to the first dummy deferred argument in the reduced list, the second actual deferred argument corresponds to the second dummy deferred argument in the reduced list, etc. <> <> <> <> Constraint: must be type INTEGER, LOGICAL or CHARACTER. Constraint: An that is a shall correspond to a that is declared as a in the referenced template or requirement. Constraint: The type and kind of an that is a shall have the same type and kind of the declaration of the corresponding in the referenced template or requirement. Constraint: If the shape of the corresponding in the referenced template or requirement is not assumed, then shall have the same shape. Constraint: If the rank of the corresponding in the referenced template or requirement is not assumed, then shall have the same rank. Constraint: An that is a shall correspond to a that is declared as a in the referenced template or requirement. Constraint: If an is a , its shall support intrinsic assignment. Constraint: An that is a or shall correspond to a that is declared as a in the referenced template or requirement. Constraint: An that is a shall be consisntent with the characteristics of the corresponding in the referenced template or requirement. Constraint: An that is a shall have one specific procedure that is consistent with the characteristics of the corresponding in the referenced template or requirement. Note: The previous two constraints constitute what is referred to as "weak constraints" in other languages. The shall be associated with the specific procedure that is consistent with the characteristics. 3.2 Syntax for the REQUIREMENT construct ---------------------------------------- A REQUIREMENT is a named collection of deferred argument declarations intended to facilitate reuse of common patterns within templates and other requirements. <> REQUIREMENT ( [] ) [ ] ... ... END [REQUIREMENT []] Note: is defined in section 3.1.1, and requirement declaration statements are define in section 3.1.2. <> <> Constraint: Each shall appear in a . Note: If a appears in the it can only be used to define a . Note: A is a scoping unit that allows use and host association. Each is local to the REQUIREMENT construct. 3.2.1 Requirement interface body -------------------------------- A declares a as a deferred procedure and defines its interface. <> [ ] <> [ ] Constraint: Each and in a shall be a . <> [ ] ... [ ] ... <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> [ [ , ] ... :: ] <> ALLOCATABLE <> ASYNCHRONOUS <> CODIMENSION <> CONTIGUOUS <> DIMENSION ( ) <> INTENT ( ) <> OPTIONAL <> PARAMETER <> POINTER <> <> TARGET <> VALUE <> VOLATILE A is a scoping unit that has use and host association. Note: Unlike of the or , allows access to host scope entities by default, and does not allow using the IMPORT statement. 3.3 Syntax for the REQUIRES statement ------------------------------------- A REQUIRES statement provides declarations of deferred arguments by associating them with the deferred dummy arguments of a REQUIREMENT. <> REQUIRES [::] ( [] ) Constraint: shall be the name of a previously defined . <> [ = ] Constraint: Each shall be the name of a in the referenced requirement. 3.4 Syntax for the TEMPLATE construct ------------------------------------- A template is a set of declarations, specifications and definitions that are enabled by instantiation. A TEMPLATE construct defines a template. A template is a scoping unit to which use and host association and template argument association can be applied. A template can appear in the specification part of a program unit or internal subprogram, or in of another template.