It’s nice that in Fortran 2018, a function can have an assumed-rank array argument that can be a scalar or an array of any rank, so that the program
module m_mod implicit none contains function mean(x) result(y) real, intent(in) :: x(..) ! assumed-rank array real :: y select rank(x) rank(0) ; y = x rank(1) ; y = sum(x)/size(x) rank(2) ; y = sum(x)/size(x) rank default ; y = -huge(x) ! signal that rank not handled end select end function mean end module m_mod program main use m_mod, only: mean implicit none real :: x,xvec(3),xmat(3,3),xtens(3,3,3) x = 5.0 xvec = 5.0 xmat = 5.0 xtens = 5.0 print*,mean(x),mean(xvec),mean(xmat),mean(xtens) end program main
5.00000000 5.00000000 5.00000000 -3.40282347E+38
To handle the case above where the same code is used for different ranks, the alternatives to manual copying would be to use INCLUDE or have a preprocessor generate the code? Analogous with SELECT CASE, it would be ideal if one could write
rank(1:7); y = sum(x)/size(x)
but using the assumed-rank feature is still more concise than having to define separate mean_scalar, mean_vector, mean_matrix functions as MODULE PROCEDUREs for the INTERFACE mean, as one would do in Fortran 95. Is there a way to have the program fail at compile time when an array of rank 3 or higher is passed to mean?