Closures in Fortran
Fortran supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.
module closures
implicit none
private
public :: int_seq
contains
! This function int_seq returns another function, which
! we define anonymously in the body of int_seq. The
! returned function closes over the variable i to
! form a closure.
function int_seq() result(next_int)
integer :: i
procedure(integer_func), pointer :: next_int
i = 0
next_int => increment
contains
function increment() result(res)
integer :: res
i = i + 1
res = i
end function increment
end function int_seq
end module closures
program main
use closures
implicit none
procedure(integer_func), pointer :: next_int
procedure(integer_func), pointer :: new_ints
! We call int_seq, assigning the result (a function)
! to next_int. This function value captures its
! own i value, which will be updated each time
! we call next_int.
next_int => int_seq()
! See the effect of the closure by calling next_int
! a few times.
print *, next_int()
print *, next_int()
print *, next_int()
! To confirm that the state is unique to that
! particular function, create and test a new one.
new_ints => int_seq()
print *, new_ints()
end program main
! Interface for the function type
abstract interface
function integer_func() result(res)
integer :: res
end function integer_func
end interface
To compile and run this Fortran program:
$ gfortran -o closures closures.f90
$ ./closures
1
2
3
1
In Fortran, we use a module to encapsulate the closure-like behavior. The int_seq
function returns a pointer to a function, which is our way of implementing a closure. The internal function increment
acts as the anonymous function in the original example.
The contains
keyword in Fortran allows us to define internal procedures, which can access variables from their containing scope, similar to closures in other languages.
The abstract interface
at the end defines the function type we use for our function pointers.
While Fortran doesn’t have true anonymous functions or closures in the same way as some other languages, this approach provides similar functionality.
The last feature of functions we’ll look at for now is recursion, which Fortran fully supports.