1

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

2 Answers 2

2

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
Sign up to request clarification or add additional context in comments.

Comments

1

Guessing a little at your intent based on the example source, your problem is that you want a dummy procedure that may vary in its characteristics - for example the number of arguments.

I don't recommend this, but Fortran permits a dummy procedure to have an implicit interface - you could just give the func dummy procedure the external attribute, and then it is on the programmer's head to make sure that the nature of the reference through the dummy procedure is consistent with the interface of the actual procedure. Language facilities that require an explicit interface may not be used with this approach.

subroutine execute(func)
  real, external :: func
  !...
  if (some_condition) then
    x = func(a, b)
  else
    x = func(a, b, c)
  end if

If you want the dummy procedure to have an explicit interface, then you might be able to use optional arguments.

module mod1
contains
  subroutine execute(func1, func2)
    interface
      real function func1(a,b)
        real a,b
      end function func1
      real function func2(a,b,c)
        real a,b,c
      end function func2
    end interface
    optional :: func1, func2

    !...

    if (present(func1)) x = func1(a, b)
    if (present(func2)) x = func2(a, b, c)
  end subroutine execute
end module mod1

program p
  use mod1
  call execute(func1=test) 
contains
  real function test(a,b)
    real a,b
    test = a + b
  end function
end program p

More general solutions to this problem may invoke the procedure through a a binding of a derived type - the invocation of the procedure always uses the same interface, but additional information can then be passed through to the procedure using components of the derived type.

1 Comment

Hi, thank you for the quick response. The solution with the optional arguments is really nice, simple to use and easy to implement, that is what I need. Thank you! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.