Generics in Co-array Fortran
module generics_module
implicit none
! In Co-array Fortran, we don't have direct support for generics.
! We'll simulate some aspects using derived types and interfaces.
type :: list_node
class(*), allocatable :: value
type(list_node), pointer :: next => null()
end type list_node
type :: list
type(list_node), pointer :: head => null()
type(list_node), pointer :: tail => null()
contains
procedure :: push
procedure :: all_elements
end type list
contains
! This function simulates the generic SlicesIndex function
! It works only for character arrays
function slices_index(s, v) result(idx)
character(len=*), intent(in) :: s(:)
character(len=*), intent(in) :: v
integer :: idx
integer :: i
do i = 1, size(s)
if (s(i) == v) then
idx = i
return
end if
end do
idx = -1
end function slices_index
! Push method for the list type
subroutine push(this, v)
class(list), intent(inout) :: this
class(*), intent(in) :: v
type(list_node), pointer :: new_node
allocate(new_node)
allocate(new_node%value, source=v)
if (.not. associated(this%tail)) then
this%head => new_node
this%tail => new_node
else
this%tail%next => new_node
this%tail => new_node
end if
end subroutine push
! All_elements method for the list type
function all_elements(this) result(elems)
class(list), intent(in) :: this
class(*), allocatable :: elems(:)
type(list_node), pointer :: current
integer :: count, i
count = 0
current => this%head
do while (associated(current))
count = count + 1
current => current%next
end do
allocate(elems(count))
current => this%head
do i = 1, count
elems(i) = current%value
current => current%next
end do
end function all_elements
end module generics_module
program main
use generics_module
implicit none
character(len=3) :: s(3) = ["foo", "bar", "zoo"]
type(list) :: int_list
class(*), allocatable :: elements(:)
integer :: i
! Using the slices_index function
print *, "index of zoo:", slices_index(s, "zoo")
! Using the list type
call int_list%push(10)
call int_list%push(13)
call int_list%push(23)
elements = int_list%all_elements()
print *, "list:"
do i = 1, size(elements)
select type (elem => elements(i))
type is (integer)
print *, elem
end select
end do
end program main
This Co-array Fortran code attempts to replicate the functionality of the Go generics example. However, it’s important to note that Co-array Fortran doesn’t have built-in support for generics like Go does. Instead, we’ve used derived types and class(*) to simulate some aspects of generic programming.
The slices_index
function is implemented only for character arrays, as Co-array Fortran doesn’t support true generic functions. The list
type is implemented using class(*) to allow it to store any type of data, which is similar to how generics work, but with some limitations.
The main program demonstrates the usage of these “generic-like” implementations. It creates a list of integers, adds elements to it, and then prints all elements.
To compile and run this program, you would typically use a Co-array Fortran compiler. The exact commands may vary depending on your specific compiler and environment.
$ <compiler> generics.f90
$ ./a.out
index of zoo: 3
list:
10
13
23
This example showcases how we can implement some generic-like behavior in Co-array Fortran, even though the language doesn’t have native support for generics. The approach used here provides some flexibility, but it’s not as type-safe or as convenient as true generics in languages like Go.