J3/99-197 Date: 06 August 1999 To: J3 From: Malcolm Cohen Subject: Interface Scoping Problem This paper is basically a revision of ISO/IEC JTC1/SC22/WG5/N1365. 1. The problem in F90/F95 MODULE M TYPE T PRIVATE ... END TYPE CONTAINS SUBROUTINE SUB(X,F) TYPE(T) X(10) INTERFACE TYPE(T) FUNCTION F() ! Oops DIMENSION F(10) END END INTERFACE X = F() END SUBROUTINE END i.e. A module procedure inside the module that defines an "opaque" type cannot have a dummy procedure that has an argument of that type (assuming that an explicit interface is required for the dummy function). 2. The problem in F200x ... obstructs the use of certain O.O. constructs. MODULE M TYPE T PROCEDURE(xyz),PASS_OBJ,POINTER :: p ! (Alpha) CONTAINS PROCEDURE,PASS_OBJ :: x => mpx PROCEDURE(xyz),PASS_OBJ :: y => NULL() ! (Beta) END TYPE ... INTERFACE PROCEDURE() SUBROUTINE xyz(obj) CLASS(T) obj ! Oops END SUBROUTINE END INTERFACE ... CONTAINS SUBROUTINE mpx(obj) CLASS(T) obj ! ok ... END SUBROUTINE END The problem is that the "PROCEDURE(xyz)" requires the abstract interface to be defined in the same module, but the interface cannot access the type T which it needs to declare the dummy arguments. This applies to any procedure pointer (or deferred type-bound procedure) that has a dummy argument of the type, not only to PASS_OBJ procedures. "Beta" can be simulated by the user - by providing a stub procedure instead of a NULL() - but "Alpha" cannot be done in that way. 3. The Proposal: Specification There should be a means of accessing host entities from an interface body. Only explicitly named entities are to be accessed, from the enclosing scoping unit. In particular, the IMPLICIT mapping is not accessed. If there are no IMPLICIT statements in the interface body then the implicit mappings in use will continue to be the normal Fortran default mappings. 4. The Proposal: Syntax 4.1 Option 1: The IMPORT statement. Syntax: IMPORT [::] Constraint: shall be a derived-type name or a named constant. e.g. IMPORT mytype,yourtype Thus to fix up the example in section 2 above, the user would put "IMPORT T" immediately before the line containing "Oops". Details: The named entities must be entities in the enclosing scope. No further declaration of such entities is permissable. Imported PARAMETERs and TYPEs must have been defined prior to the interface body. Note that importing anything other than a TYPE or PARAMETER would not provide any useful functionality. The IMPORT statement would only be allowed in interface bodies and would appear after any USE statements and before any IMPLICIT statement. It is not considered to be useful to be able to rename entities in this limited context, so a simple is thought to be adequate. 4.2 Option 2: Extend the USE statement. Syntax: USE *, ONLY: [] e.g. USE *,ONLY:mytype,yourtype Thus to fix up the example in section 2 above, the user would put "USE *,ONLY:T" immediately before the line containing "Oops". Details: As per the IMPORT statement, but for consistency we would allow renaming. 4.3 Option 3: Allow some recursive USE statements. Syntax: Allow an interface body in a module to contain a USE statement for that module. Thus to fix up the example in section 2 above, the user would put "USE M,ONLY:T" immediately before the line containing "Oops". Details: To prevent the possibility of recursive definitions the ONLY clause must be present. Otherwise the details are the same as in option 2. 4.4 Straw Vote: Prefer the syntax in option (1)/(2)/(3)/undecided?