Skip to main content

Procedures

There are two types of procedures in Fortran: subroutines and functions. All procedures should be placed in a module or after the contains keyword in a main program.

Subroutine

First we write the subroutines in a module:

src/12_add_module.f90
MODULE add_module
IMPLICIT none
PRIVATE

REAL :: input1, input2, total

PUBLIC :: read_inputs, add_numbers, print_result

CONTAINS

SUBROUTINE read_inputs()
PRINT "(a,$)", "Input1 = "
READ *, input1

PRINT "(a,$)", "Input2 = "
READ *, input2
END SUBROUTINE read_inputs

SUBROUTINE add_numbers()
total = input1 + input2
END SUBROUTINE add_numbers

SUBROUTINE print_result
PRINT *, input1, " + ", input2, " = ", total
END SUBROUTINE print_result
END MODULE add_module

Now write our program:

src/12_add.f90
PROGRAM add
USE add_module
IMPLICIT none

CALL read_inputs()
CALL add_numbers()
CALL print_result()
END PROGRAM add

Compile and execute:

gfortran -c 12_add_module.f90
gfortran 12_add.f90 12_add_module.o
./a.out

Function

We want to print a table of xx vs f(x)f(x) where:

f(x)=(1+1x)xf(x) = \left(1 + \frac{1}{x}\right)^x
src/13_function_module.f90
MODULE function_module
IMPLICIT NONE
PRIVATE

INTEGER, PARAMETER, PUBLIC :: power = 5
PUBLIC :: f

CONTAINS

FUNCTION f(x) RESULT(f_result)
REAL, INTENT(IN) :: x
REAL :: f_result

! SELECTED_REAL_KIND(precision [, range])
INTEGER, PARAMETER :: kind_needed = selected_real_kind(power + 1)

f_result = (1 + 1 / REAL(x, kind_needed)) ** x
END FUNCTION f
END MODULE function_module
src/13_function_table.f90
PROGRAM function_table

USE function_module
IMPLICIT NONE
REAL :: x
INTEGER :: i

DO i = 0, power
x = 10**i
PRINT "(f8.1, f8.4)", x, f(x)
END DO
END PROGRAM function_table

Sample output:

     1.0  2.0000
10.0 2.5937
100.0 2.7048
1000.0 2.7171
10000.0 2.7186
100000.0 2.7220

In contrast to subroutines, functions must provide a return value.

Pure procedures and side effects

Side effects are the change in status of a program when a procedure is executed other than computing a value to return, such as changing a variable declared in the program or module above the contains statement.

One can indicate whether a function or subroutine is pure or has side effects by using the keywords pure and impure, respectively.

Interface blocks

Interface block is used to provide necessary information to the calling program whether the call is correct. It basically consists of the procedure without the executable code, and declaration of local variables.