What does overloading with "module procedure" specifically do?

I’ve been coding Fortran professionally for about a year and a half now, but the legacy code doesn’t use any features of modern Fortran, so I’m very new in this regard. My experience is in languages like C#, Kotlin and TypeScript.

Advice on how to create “overloads” of functions on Stack Overflow and right here states I must write something like this

interface the_thing_callers_use
  module procedure foo, bar, baz
end interface

With the definitions of foo, bar, and baz in the contains portion of a module. My question is, what does this actually do? I’ve struggled to find documentation on the “module procedure” statement, and interfaces in general. I understand this allows someone to write

program main
  call the_thing_callers_use(1, 2, 3)
end program

But what actually goes on? How does it “match” the real function to the interface (if that’s even an appropriate description of what happens)? How do dummy arguments work? How type safe is it? Do foo, bar, and baz need to have the same return type? Are foo, bar, and baz now “private”?

I’m more looking for general information, but my specific use case involves me wanting to declare a second, double precision function with the same name and arguments as an existing single precision one in the library I’m working on. I thought I could change the actual name of the function and create an interface to not affect existing callers. (Most of the application is legacy and uses single precision, I’m using double precision in a specific portion and new code). Any help here is much appreciated.

2 Likes

The compiler matches the type, kind, and rank (TKR) of the argument list with the possible routines, and it selects the one that matches. This means that the TKR of the various possible routines must be distinct.

2 Likes

@adamyakes ,

Welcome to this forum.

Re: “I’ve been coding Fortran professionally for about a year and a half now, but the legacy code doesn’t use any features of modern Fortran, so I’m very new in this regard”, hopefully you will find the Learning section at the parent site of this forum, fortran-lang.org helpful:
Learn — Fortran Programming Language

Re: “I’ve struggled to find documentation on the “module procedure” statement, and interfaces in general” please note with Fortran, as things stand now, a good place to start for Fortran language semantics is the books (also as e-books), especially “Modern Fortran Explained”. Also for developing modern applications, consider the book by @milancurcic

Immediately for “module procedure” you can consider compiler vendor sites and their developer reference guides such as with Intel Fortran and IBM XL Fortran .

3 Likes

Hi @adamyakes, and welcome!

The three procedures in your example must be distinguishable somehow, so that the compiler will know which one to call depending on the caller’s arguments. For example the third argument in foo might be integer, while it’s real in bar, and an array of 2 integers in baz; In this case:
call the_thing_callers_use(1, 2, 3) will call foo,
call the_thing_callers_use(1, 2, 3.) will call bar,
call the_thing_callers_use(1, 2, [3, 4]) will call baz.
In other words, at least one argument must be different (or even absent). All module procedures must be either subroutines or functions (you can’t mix both as module procedures). Assuming the module is private, the procedures are also private, in the sense the calling program has no access to them, it just has access to the generic the_thing_callers_use (provided this one is public, of course.)
Also note not all of them must be module procedures. For example, baz might be declared in another module; in this case it will be included in the interface as procedure baz, not module procedure baz.

It is a very efficient mechanism to create generic procedures. In many cases, one can achieve the same functionality with just one procedure having optional arguments. However interfacing module procedures is often preferable.

4 Likes