************************************************** J3/04-247 Date: 15 February 2004 To: J3 From: Aleksandar Donev Subject: GENERIC program unit ************************************************** Title: Submitted by: J3 Status: For Consideration References: J3/03-260, "Extending Genericity in Fortran", by Aleksandar Donev, to appear in the Fortran Forum. Basic Functionality: The above references discuss in detail the issue of extending the facilities for generic programming in Fortran. I will not repeat the discussion here, but rather, simply summarize my proposal for how to allow code parameterized by a type in Fortran. For this purpose, I propose to introduce a new kind of programming unit, a GENERIC, henceforth called a generic package. The main characteristic of a generic package is that it can be parameterized by one or more types. A GENERIC package has similarities to both type-definitions and to modules. It is similar to a type definition in that one can declare instances of a given generic package, much like declaring variables of a given type (however, these are not variables, for example, no arrays, pointers, or other such things are allowed with instances). Also, I think the definitions of generic packages should be allowed to appear any place a type definition can and should have similar scoping rules (for example, different components can have different accessibilities, the whole package can have a default accessibility, etc.). A generic package is similar to a MODULE in that it can contain variable declarations, constant definitions, type definitions, and contain procedure bodies, and since it provides a host environment for its components. A generic package can be parameterized by a type, an operator, a procedure and a constant. To actually use a procedure or variable from a generic package in executable code, one must instantiate the generic package with specific parameters. In particular, a specific (i.e., complete, nonparameterized) type must be specified for each type parameter. The generic package itself is thus not executable code, and is not compiled to object code in the usual sense (though it can be parsed). Certain properties can be specified for the type parameters of a generic package. In particular, it can be specified that the type belong to a certain pre-specified (likely intrinsic) set of types, or that the type have certain components. Inside the generic package, only statements that are syntactically legal for any type that satisfies the specified properties are allowed. Rationale: Allowing code to be parameterized by a type gives great expressive capability and allows one to write code that can operate on a variety of types without duplicating code using preprocessors or other such tricks. At the same time, maximal efficiency is maintained as the actual executable code is generated for specific types only, so that full optimization and inlining is possible without complex global program analysis. Estimated Impact: Detailed Specification: Here is a snipplet from a generic package that contains a generic QuickSort procedure, i.e., one that can be used with any ordered type T. The ordering operator is another parameter of the generic package: GENERIC, PUBLIC :: Sorting(T,OPERATOR(<)) ! Sorting of data of any ordered type PUBLIC TYPE, PARAMETER :: T ! An ordered type as a parameter ABSTRACT INTERFACE OPERATOR(<) ! An operator parameter FUNCTION Comparison(A,B) RESULT(A_le_B) TYPE(T), INTENT(IN) :: A, B LOGICAL :: A_le_B END FUNCTION END INTERFACE CONTAINS SUBROUTINE QuickSort(array) ... TYPE(T), ... :: array ... IF(array(i)