Search code examples
functioninterfacefortranoverloadingsubroutine

Fortran and interface blocks in functions or subroutines


I would like to write a module which will perform some action based on function type provided by "user" in different file. This function will be passed as an argument of "execute(...)" subroutine of that module. This is basically what I want to obtain, but I don't know if this is possible and how should I do it correctly.

module mod1
contains
subroutine execute(func)
 interface func
 real function func1(a,b)
    real a,b
 end function 
 real function func2(a,b,c)
    real a,b,c
 end function 
 ! more similar functions here
 end interface func

   ! -------------------
   ! here some how choose between func1 or func2
   ! and do the calculations
   if(func1) then ...
   else if(func2) ...
   ! -------------------
endsubroutine execute 
endmodule mod1
------------------------------------------
program
use mod1
call execute(test) 
contains
real function test(a,b)
real a,b
test = a + b
end function
end program

I know that this code wont compile, but this is just a sketch how it would look like. For now, the only ugly solution for that problem for me is to write many alternatives for execute subroutine i.e execute_1, execute_2 and depending on the test function user will have to choose proper execute_X function.

Is there any better solution for that problem?

Thanks in advance. KK


Solution

  • You can also put the interfaces in the module header, and use the procedure attribute for func1 and func2 like so. This is useful if you want to use them elsewhere, since you are only defining them in one place.

    module mod1
    
    abstract interface
      real function f1(a,b)
        real,intent(in) :: a,b
      end function f1
      real function f2(a,b,c)
        real,intent(in) :: a,b,c
      end function f2  
    end interface
    
    contains
    
      subroutine execute(func1, func2)
      procedure(f1),optional :: func1
      procedure(f2),optional :: func2
    
      !...
    
      if (present(func1)) x = func1(a, b)
      if (present(func2)) x = func2(a, b, c)
      end subroutine execute
    
    end module mod1