In order to discuss this topic we need some definitions. In logical
terms,
an executable program consists of one
From an organizational point of view, however,
a complete program consists of
An internal subprogram is one
SUBROUTINE outer REAL x, y : CONTAINS SUBROUTINE inner REAL y y = x + 1. : END SUBROUTINE inner ! SUBROUTINE mandatory END SUBROUTINE outerWe say that outer is the
The
The names of program units and external procedures are
Modules are used to package
MODULE interval_arithmetic TYPE interval REAL lower, upper END TYPE interval INTERFACE OPERATOR(+) MODULE PROCEDURE add_intervals END INTERFACE : CONTAINS FUNCTION add_intervals(a,b) TYPE(interval), INTENT(IN) :: a, b TYPE(interval) add_intervals add_intervals%lower = a%lower + b%lower add_intervals%upper = a%upper + b%upper END FUNCTION add_intervals ! FUNCTION mandatory : END MODULE interval_arithmeticand the simple statement
USE interval_arithmeticprovides
SUBROUTINE shuffle (ncards, cards) INTEGER, INTENT(IN) :: ncards INTEGER, INTENT(OUT), DIMENSION(ncards) :: cardsAlso, INOUT is possible: here the actual argument must be a variable (unlike the default case where it may be a constant).
Arguments may be optional:
SUBROUTINE mincon(n, f, x, upper, lower, equalities, & inequalities, convex, xstart) REAL, OPTIONAL, DIMENSION :: upper, lower :allows us to call mincon by
CALL mincon (n, f, x, upper) : IF (PRESENT(lower)) THEN ! test for presence of actual argument :Arguments may be keyword rather than positional (which come first):
CALL mincon(n, f, x, equalities=0, xstart=x0)Optional and keyword arguments are handled by explicit interfaces, that is with internal or module procedures or with interface blocks.
REAL FUNCTION minimum(a, b, func) ! returns the minimum value of the function func(x) ! in the interval (a,b) REAL, INTENT(in) :: a, b INTERFACE REAL FUNCTION func(x) REAL, INTENT(IN) :: x END FUNCTION func END INTERFACE REAL f,x : f = func(x) ! invocation of the user function. : END FUNCTION minimumAn explicit interface is obligatory for:
INTERFACE gamma ! generic name FUNCTION sgamma(X) ! specific name REAL (SELECTED_REAL_KIND( 6)) sgamma, x END FUNCTION dgamma(X) ! specific name REAL (SELECTED_REAL_KIND(12)) dgamma, x END END INTERFACEwhere a given set of specific names corresponding to a generic name must all be of functions or all of subroutines. If this interface is within a module, then it is simply
INTERFACE gamma MODULE PROCEDURE sgamma, dgamma END INTERFACEWe can use existing names, e.g. SIN, and the compiler sorts out the correct association.
We have already seen the use of interface blocks for defined operators and assignment (see Part 3).
volume = integrate(fy, ybounds)We might have
RECURSIVE FUNCTION integrate(f, bounds) ! Integrate f(x) from bounds(1) to bounds(2) REAL integrate INTERFACE FUNCTION f(x) REAL f, x END FUNCTION f END INTERFACE REAL, DIMENSION(2), INTENT(IN) :: bounds : END FUNCTION integrateand to integrate f(x, y) over a rectangle:
FUNCTION fy(y) USE func ! module func contains function f REAL fy, y yval = y fy = integrate(f, xbounds) ENDDirect recursion is when a procedure calls itself, as in
RECURSIVE FUNCTION factorial(n) RESULT(res) INTEGER res, n IF(n.EQ.1) THEN res = 1 ELSE res = n*factorial(n-1) END IF ENDHere, we note the RESULT clause and termination test.