Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
97 Views

Using an abstract interface for a module procedure

I am not quite sure how to achieve this:

  • I have a module A that declares an abstract interface (let's call it P).
  • I would like to create a module B which uses A, and which declares a separate module procedure S using the abstract interface P.
  • I would like to create a submodule BB (of module B) that contains the actual implementation of S.

Is this possible? The above is trivially achievable by (re)defining explicitly the interface of S in an INTERFACE block of module B... but this defeats the purpose of having the abstract interface P in the first place.

0 Kudos
7 Replies
Highlighted
Black Belt
97 Views

When you say that "procedure S using the abstract interface P", I presume that you mean that procedure S has the same interface as P.

If so, no - it is not possible.  A procedure defined by a subprogram needs to have the interface written out completely at some stage.

The abstract interface allows module A to have an explicit interface for procedure pointers or dummy arguments, prior to compilation of modules, such as B, that define procedures with that interface.  Otherwise you may have a circular module dependency issue between A and B.

0 Kudos
Highlighted
Beginner
97 Views

Thanks - this is what I feared, unfortunately. I am indeed using the abstract interface in declarations of procedure pointers or dummy arguments; I was wondering if it was possible to avoid having to redefine explicitly all arguments for each procedure which interface must be identical to P.

0 Kudos
Highlighted
Valued Contributor III
97 Views

nn n. wrote:

Thanks - this is what I feared, unfortunately. I am indeed using the abstract interface in declarations of procedure pointers or dummy arguments; I was wondering if it was possible to avoid having to redefine explicitly all arguments for each procedure which interface must be identical to P.

See the following.  Given the Fortran standard where a procedure pointer or dummy argument can take an existing interface, what you indicate in the original post with abstract interface appears unnecessary.  So if you can show an example of what you're trying to achieve, perhaps readers can provide suggestions.

module m
   implicit none
   interface
      module subroutine def_handler( s )
         implicit none
         character(len=*), intent(in) :: s
      end subroutine
   end interface
end module
submodule(m) sm
contains
   module procedure def_handler
      print *, "def_handler: s = ", s
   end procedure
end submodule
   use m, only : def_handler
   procedure(def_handler), pointer :: phandler !<-- Note the interface in procedure declaration 
   phandler => def_handler
   call phandler( "Hello World!")
   phandler => my_handler
   call phandler("Hello World!")
contains
   subroutine my_handler( s )
      character(len=*), intent(in) :: s
      print *, "my_handler: s = ", s
      return
   end subroutine
end

Upon execution of above code,

 def_handler: s = Hello World!
 my_handler: s = Hello World!

 

0 Kudos
Highlighted
Beginner
97 Views

The following 'code' is wrong obviously but it illustrates what I had in mind. The idea was to declare the prototype interface (abstract interface) only once, and reuse it for all procedures that must comply with this interface.

MODULE A
ABSTRACT INTERFACE
    SUBROUTINE P(...long list of args...)
    ...
    END SUBROUTINE P
END INTERFACE
END MODULE A

MODULE B
USE MODULE A
INTERFACE
     PROCEDURE(P) :: MYSUB  ! This is obviously not valid Fortran in this context.
END INTERFACE
END MODULE B

SUBMODULE (B) B1
... some variables accessed by MYSUB ...
END SUBMODULE B1

SUBMODULE (B:B1) B2
IMPLICIT NONE
CONTAINS
     MODULE PROCEDURE MYSUB
     END PROCEDURE MYSUB
END SUBMODULE B2

 

0 Kudos
Highlighted
Valued Contributor III
97 Views

OP wrote:

The following 'code' is wrong obviously but it illustrates what I had in mind. The idea was to declare the prototype interface (abstract interface) only once, and reuse it for all procedures that must comply with this interface ..

..
INTERFACE
     PROCEDURE(P) :: MYSUB  ! This is obviously not valid Fortran in this context.
END INTERFACE
..

Indeed, this is not allowed by the Fortran standard and which effectively appears to be indicate your ABSTRACT INTERFACE in MODULE A is entirely superfluous given the facility the standard provides as shown in Quote #4 above.

But if you think you have a valid use case to have an ABSTRACT INTERFACE as opposed to an INTERFACE with MODULE SUBROUTINE/FUNCTION toward implementations in SUBMODULEs, you may want to present it here and in other online forums and your need may gain traction.

0 Kudos
Highlighted
Beginner
97 Views

The ABSTRACT INTERFACE is required to allow the (customer-defined) procedures to be passed as arguments to other (provided-to-customer) procedures. One ugly workaround may be to use INCLUDEd snippets that define the interface in all these (customer-defined) procedures.

Anyway, IanH provided the answer to this question, thanks!

0 Kudos
Highlighted
Valued Contributor III
97 Views

OP wrote:

The ABSTRACT INTERFACE is required to allow the (customer-defined) procedures to be passed as arguments to other (provided-to-customer) procedures. One ugly workaround may be to use INCLUDEd snippets that define the interface in all these (customer-defined) procedures. ..

Re: "The ABSTRACT INTERFACE is required to allow the (customer-defined) procedures to be passed as arguments to other (provided-to-customer) procedures," first there is no thing as "required" in such situations c.f. FORTRAN was used for decades with the EXTERNAL statement and the concept still applies albeit not as a 'good coding practice'.

Anyways if your code does NOT already include your own (default?) implementations of such "(customer-defined) procedures," then it is useful to put together the ABSTRACT INTERFACE.  But if one's code already has an implementation, then customers can grab its interface for use in their overriding procedures, as shown in Quote #4.  Now in situations involving 'customer-defined procedures' it's better to have rather short argument lists which can then alleviate most of any concerns with 'interface repetition'.

0 Kudos