@certik @tom_clune @everythingfunctional thanks again for your work on the generics, and forgive me for tagging (the benefits of a clarification outweighed the risks of bugging you with explicit tags).
Consider the trivial scenario where an addition procedure should accept all possible real
kinds. To achieve the goal, I need to write five separate procedures under a generic interface name. Every time this problem appears, I wish I could write,
function add(a,b) result(sum)
real(*), intent(in) :: a
real(kind(a)), intent(in) :: b
real(kind(a)) :: sum
sum = a + b
end
where (*)
implies any real
kind supported by the compiler. If only certain kinds must be supported (e.g., real32, real64), then I wish to be able to write,
function add(a,b) result(sum)
use, iso_fortran_env, only: real32, real64
real({real32, real64}), intent(in) :: a
real(kind(a)), intent(in) :: b
real(kind(a)) :: sum
sum = a + b
end
where {}
implies the collection of specified kinds (from the set theory notation).
Should the function work for all numeric types and kinds, then I wish to write,
function add(a,b) result(sum)
use, iso_fortran_env, only: real32, real64
numeric(*), intent(in) :: a
numeric(kind(a)), intent(in) :: b
numeric(kind(a)) :: sum
sum = a + b
end
where numeric
would be a new intrinsic type that implies all intrinsic numeric types in the language (integer
, complex
, real
).
Should this functionality be extended to the character and logical kinds, I wish to be able to write something like,
function add(a,b) result(sum)
use, iso_fortran_env, only: real32, real64
type({numeric(*), character(*,*), logical(*)}), intent(in) :: a
type(typeof(a)), intent(in) :: b
type(typeof(a)) :: sum
select type a
type is (numeric(*))
sum = a + b
type is (logical(*))
sum = a .or. b
type is (character(*,*))
sum = a//b
end select
end
This would still be a compile-time resolution and provide a fast custom implementation of sum for all supported types and kinds under a single generic function name.
If such a simplex syntax were possible, the size of our codebase would reduce by more than 5 fold (there are currently five kinds supported by most compilers). I can reduce it to half with the help of preprocessing, but the interfaces within a generic interface name cannot be reduced via the preprocessor (unless some more advanced preprocessing tool is used).
I improvised these examples within the past 5 minutes. I am pretty sure there are holes in this simplistic syntax proposal. But the such concise syntax is what I have longed for several years.