Fortran/Fortran procedures and functions

Functions and Subroutines
In most programs, a block of code is often re-used at several places. In order to minimize duplicating code and facilitate maintaining the code, such blocks of code should be placed within a function or subroutine. A Fortran  is similar to a mathematical function, which takes one or many parameters as inputs and returns a single output value. A Fortran  is a block of code that performs some operation on the input variables, and as a result of calling the subroutine, the input variables are modified.

An expression containing a function call:

A call to a subroutine:

Many programming languages do not distinguish between functions and subroutines (e.g. C/C++, Python, Java). Pure functional programming languages (e.g. Haskell) only allow functions, because subroutines can, in some case, modify input variables as side-effects, which can complicate the code.

Functions are simpler than subroutines. A function must return a single value, and can be invoked from within expressions, like a  statement, inside an if declaration , etc. A subroutine does not return a value, but can return many values via its arguments and can only be used as a stand-alone command (using the keyword  ).

Function
In Fortran, one can use a  to return a value or an array of values. The following program calls a function to compute the sum of the square and the cube of an integer. The  attribute of argument   means that   cannot be changed inside the function and in contrast, the return value   has automatic. Note that the return type of  needs to be declared. If this is omitted, some compilers will not compile. Open64 will compile the resulting code with warning, but the behavior is ill-defined.

An alternative formulation (F77 compatible) is The return type of the  still needs to be declared, as above. The only difference is how the return type of  is referenced within. In this case, the return variable has the same name as the function itself.

Recursion
Recursive functions can be declared, in a way such as the one shown below, in order for the code to compile.

Subroutine
A  can be used to return several values through its arguments. It is invoked with a  statement. Here is an example.

Intent
When declaring variables inside functions and subroutines that need to be passed in or out, intent may be added to the declaration. The default is no intent checking - which can allow erroneous coding to be undetected by the compiler.

- the value of the dummy argument may be used, but not modified, within the procedure.

- the dummy argument may be set and then modified within the procedure, and the values returned to the caller.

- initial values of the dummy argument may be both used and modified within the procedure, and then returned to the caller.

Different function result definitions
Functions can define the data type of their result in different forms: either as a separate variable or by the function name.

See the examples below

External
Procedures must be included by module  or by specifying them as   procedures. supplies only an implicit interface which is inferior as the compiler doesn't know the number of arguments and neither their data types. Thus, it cannot yield warnings at compile time (in contrast to an explicit interface given from a module, c.f. Fortran/OOP in Fortran).

Pure procedures
Both functions and subroutines can modify their input variables. By necessity, subroutines modify input variables, since they do not return any output value. Functions do not have to, but are allowed, by default, to modify input variables. A function can be turned into a pure function, which does not have any side-effects through the use of the  attribute on all input variables, and further enforced through the keyword. The  keyword imposes additional restrictions, which essentially prevents the function from having any side-effects.

An example of a  function.

Keyword arguments
One can use any order of the input arguments if one specifies them by their dummy name. That is possible as long as the calling procedure has an interface block of the intended procedure (which is automatically created if one includes the function by  usage uses modules).

There is also a hybrid method where one specifies some parameters by position and the rest by their dummy name.

An example is given

Optional arguments
Arguments can be set. The intrinsic function  can be used to check if a specific parameter is set.

An example is given below.

Interface block
If a procedure has another procedure as dummy argument then one has to specify its type, just as the type of other parameters. An  block is used for this case. It consists of the procedure statement with the definitions of its arguments.

Note, that each interface block has its own scope. Thus, if one needs to access outside values one needs to explicitly load them. This can be achieved by the, or   statements.

An example is given below.

Save attribute
The value of a variable can be saved in-between procedure calls by explicitly giving the  attribute.

An example is given below.

Generic
It is possible to create generic functions with the same name for different input arguments, similar to the  function which works for integer, real, and complex data types.

The following example illustrates how to create a function  which adds either two integers or character strings.

Deferred
One can set type-bound procedures of an abstract type as  such that it needs to be reimplemented in derived types. For more information see the section on abstract types.

Elemental
One can create procedures that operate parameters of arbitrary dimension. The keyword  is used where one defines the operation on a single object (e.g. integer) and the general case is automatically handled.

An example for the addition of arbitrary long integer dimension is given.