Closures in Co-array Fortran
Co-array 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_mod
implicit none
private
public :: int_seq
contains
function int_seq() result(next_int)
integer :: i[*]
procedure(int_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_mod
program main
use closures_mod
implicit none
procedure(int_func), pointer :: next_int
procedure(int_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 integer function
abstract interface
function int_func() result(res)
integer :: res
end function int_func
end interface
In this Co-array Fortran version, we’ve implemented a similar concept of closures using a module and function pointers. The int_seq
function returns a pointer to an internal function increment
, which acts as our closure.
To run the program, save it as closures.f90
and compile it with a Co-array Fortran-compatible compiler:
$ caf closures.f90 -o closures
$ ./closures
1
2
3
1
The output demonstrates that the closure maintains its state between calls, and a new closure starts with a fresh state.
Note that Co-array Fortran doesn’t have built-in support for anonymous functions or closures in the same way as some other languages. This implementation uses function pointers and internal procedures to achieve similar functionality.
The last feature of functions we’ll look at for now is recursion, which is fully supported in Co-array Fortran.