Channel Directions in Co-array Fortran
program channel_directions
use iso_fortran_env
implicit none
type :: string_channel
character(len=100) :: message
logical :: is_full = .false.
end type string_channel
type(string_channel) :: pings, pongs
call ping(pings, "passed message")
call pong(pings, pongs)
print *, pongs%message
contains
! This `ping` subroutine only accepts a channel for sending
! values. In Co-array Fortran, we simulate this by using
! the `intent(out)` attribute.
subroutine ping(pings, msg)
type(string_channel), intent(out) :: pings
character(len=*), intent(in) :: msg
pings%message = msg
pings%is_full = .true.
end subroutine ping
! The `pong` subroutine accepts one channel for receives
! (pings) and a second for sends (pongs).
subroutine pong(pings, pongs)
type(string_channel), intent(inout) :: pings
type(string_channel), intent(out) :: pongs
if (pings%is_full) then
pongs%message = pings%message
pongs%is_full = .true.
pings%is_full = .false.
end if
end subroutine pong
end program channel_directions
When using channels as function parameters in Co-array Fortran, we can specify if a channel is meant to only send or receive values. This specificity increases the type-safety of the program.
In this example, we’ve simulated channels using a custom type string_channel
. The ping
subroutine is designed to only send values, while the pong
subroutine both receives and sends.
To run the program:
$ gfortran -coarray=single channel_directions.f90 -o channel_directions
$ ./channel_directions
passed message
Note that Co-array Fortran doesn’t have built-in channel semantics like Go. Instead, we’ve used a simple struct-like type to simulate channel behavior. The intent
attributes in Fortran help enforce the directionality of our simulated channels.
In a real Co-array Fortran program, you might use co-arrays for inter-image communication, which would be more idiomatic for the language. However, this example focuses on simulating Go’s channel directions concept.