Procedures: Functions & Subroutines
Functions return a value and should be free of side effects; subroutines are called with call and return results through arguments.
13.1 Functions
module geometry
implicit none
integer, parameter :: dp = kind(1.0d0)
contains
function circle_area(r) result(area)
real(dp), intent(in) :: r
real(dp) :: area
area = acos(-1.0_dp) * r**2
end function circle_area
real(dp) function hypotenuse(a, b) ! alternative style: type before 'function'
real(dp), intent(in) :: a, b
hypotenuse = sqrt(a**2 + b**2)
end function hypotenuse
end module geometry
program main
use geometry
implicit none
print *, circle_area(2.0_dp), hypotenuse(3.0_dp, 4.0_dp)
end program main13.2 Subroutines
Functions return a value and should be free of side effects; subroutines are called with call and return results through arguments.
subroutine swap(a, b)
real, intent(inout) :: a, b
real :: tmp
tmp = a; a = b; b = tmp
end subroutine swap
subroutine stats(x, mean, stdev)
real, intent(in) :: x(:)
real, intent(out) :: mean, stdev
mean = sum(x) / size(x)
stdev = sqrt(sum((x - mean)**2) / (size(x) - 1))
end subroutine stats
call swap(p, q)
call stats(data, m, s)13.3 INTENT
read-only inside the procedure undefined on entry; must be set (allocatables are deallocated on entry) read and modified pass a copy (by value)
Always declare intent — it documents the interface and lets the compiler catch bugs.
13.4 Argument passing
Fortran passes arguments by reference (conceptually), so a procedure can modify actual arguments. Passing an expression or constant to an intent(out)/intent(inout) argument is an error.
13.5 Where procedures live
Module procedures (inside contains of a module) — get automatic explicit interfaces: argument checking, assumed-shape arrays, optional arguments. Preferred.
Internal procedures (inside contains of a program or procedure) — can access the host's variables.
External procedures (separate, legacy) — need an interface block for safety.
13.6 Interface blocks
Needed for external procedures and procedure arguments (or use procedure(...) with an abstract interface).
interface
function f(x) result(y)
real, intent(in) :: x
real :: y
end function f
end interface