Prototype implementation of Fortran generics in LFortran

@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.

4 Likes