To: J3 J3/22-129 From: Tom Clune & generics subgroup Subject: Response to Comments on Generics Formal Specs Date: 2022-February-26 Reference: 22-126, 22-124r0, 22-124r1 Generics subgroup has considered the comments on generics formal specs in presented in 22-126. 22-124r1 incorporates elements where subgroup agrees, and this paper responds to the individual comments. (Text from 22-123r1 is indicated by indentation and "|".) | E2. An INSTANTIATE statement must provide the name of an | accessible TEMPLATE and a list of TEMPLATE actual parameters | corresponding to the TEMPLATE dummy parameters of the | specified TEMPLATE. | E5. The INSTANTIATE feature must allow functionality analogous to | the ONLY and rename clauses of module USE statements to enable | disambiguation of provided entities. | An instantiation should be allowed to have a name. Instantiating a | template and getting entities from it could then be a two-step | process: | | In addition to | | INSTANTIATE :: T(param1, param2), ONLY: S_1 => S | | or allow | | INSTANTIATE :: MyT => T(param1, param2) | USE MyT, only: S_1 => S | | and then, in a different scoping unit, perhaps where MyT is | accessed by host or use association | | | USE MyT, only: S_2 => S, P | | Otherwise, one must re-instantiate the template to get the same | thing or something different from it where needed, perhaps with a | different name, in a different context. Subgroup disagrees with this approach, but the disagreement is largely about syntax, not substance. Why is "re-INSTANTIATE" bad? While "re-USE" is good? If re-instantiation is somehow undesirable, one can always place the instantiation within a module and then use existing rename mechanisms. The proposed syntax here has the unfortunate complication of allowing USE statements in locations that are currently not permitted. But if others are strongly in favor of this approach, subgroup could come around. We do recommend that only _one_ rename mechanism be provided, not both. | 22-120r1 specified that instantiations of the same template with | identical actual parameters produced identical entities. This | isn't mentioned in 22-124. This statement is true. | It's not obvious that this would require (or recommend) a | processor to "keep" only one copy of each entity, especially if | such an entity is accessed by more than one identifier. Subgroup welcomes further improvement to the statements. Hopefully the intent is at least clear. Clearly there will be some best practices that will minimize abuse/surprises. E.g., while we allow templates to define variables that can be accessed through instantiation, these will have many of the same characteristics that make global variables undesirable. | F. It's not obvious what RESTRICTION is used for. It's not obvious | that it provides anything that is not already provided by | interface blocks. If it's just a way to package parameterized | interface blocks, it's not obvious that it's different from a | template. The difference is that it provides (1) a _name_ and (2) it is parameterized. Existing (unnamed) interfaces cannot be reused, and existing (named) interfaces serve to define a generic name for the contained specific procedures. This new beast is a hybrid of these. Possibly (hopefully?) new syntax rules will obviate the need for something spelled "RESTRICTION" and "REQUIRES". For now these terms serve to highlight important differences. RESTRICTION could be eliminated by allowing named, parameterized INTERFACE blocks like: INTERFACE i_mine(T,U,F) SUBROUTINE F(x,y) RESULT(z) TYPE(T), INTENT(IN) :: x, y TYPE(U) :: z END SUBROUTINE END INTERFACE But the analog of REQUIRES is more difficult. Or at least, subgroup does not currently see a good way to achieve something like: TEMPLATE TMPL(T, U, F) REQUIRES i_mine(T,U,F) ... END TEMPLATE Fortran lacks any mechanism to _use_ an interface that could be repurposed here. | | The meaning of and within the interface block | in F4 is completely opaque. Section I only goes a little way toward | clarifying this. We agree. Comments have been added to the example to hopefully clarify. | | H. A RESTRICTION can only be referenced by host association or use | association. | | Can a RESTRICTION be declared within a template, and then used therein? Subgroup debated this on multiple occasions, as it is not essential. The paper was updated to indicate that this is permitted. | | M1. A TEMPLATE may only reference a dummy parameter that is a | SUBROUTINE, FUNCTION, or OPERATOR if the relevant interface is | defined in a REQUIRES statement within the TEMPLATE. | | The example does nothing to clarify what this means. We agree. A much more substantial example is now provided. | M3. A RESTRICTION dummy parameter that is a SUBROUTINE, FUNCTION | or OPERATOR must be given a single interface. | | This is prohibited by existing rules in Clause 19.3.1p3. Good point. For now we have left the statement in the paper for clarity. | Section C of the requirements paper 22-120r1 specified what entities | templates are allowed to define: | | - derived type | - variable | - procedure | - interface | | but there is no such specification in 22-124. 22-123r1 recommended | adding | | - enumeration types and their enumerators | - named constants We agree - this defect was prepared in 22-120r2. | Section D of the requirements paper 22-120r1 specified what | template dummy parameters are allowed to be: | | - type name | - value | - procedure | - operator | | but there is no such specification in 22-124. 22-123r1 recommended | adding | | - module | - template Subgroup disagrees, as explained in 22-128. | As discussed below concerning template dummy type parameters, it | would be necessary to declare minimum requirements of each to | preserve the possibility of a "strong constraint" model. As with | types, the syntax to declare those requirements would be identical | to the syntax to describe one of the entities that is not a | template dummy parameter. | | | ======================================================= | | Additional spec: | | It is necessary that template dummy parameter type definitions | include component and type-bound procedure declarations, and | generic bindings. Otherwise, procedures within the template | cannot access components and type-bound procedures of objects | whose types are dummy type parameters. | | Such declarations would require the template actual type | parameter to have components and type-bound procedures with the | same characteristics, but not necessarily in the same order, and | would not prohibit additional components or type-bound procedures. | | For example, procedures within a double-linked LIST template | would necessarily need to access PREV and NEXT components, but the | application using an instance would have additional components to | represent the value of the list element. | | Because declaration of components in dummy type parameter | definitions would not imply order, and would be minimum, not | exclusive requirements, this would not make it possible to weaken | specification M5. We believe that features in this direction will add complexity and are generally at odds with implementing clean, maximally useful templates. The use cases mentioned here can be addressed with simple wrappers. We do recognize that while there are some use cases that benefit from mixing object oriented and generic programming, those use cases can still be addressed with our more restricted approach. Subgroup feels that such such functionality could be introduced as an extension in a future revision if experience with the first generation of generics warrants the effort. ===END===