That makes sense, since the module subprograms might be used elsewhere, but one can think of the CONTAINed ones as statement functions but proper.
When it comes to submodules, though, gfortran has the flaw of propagating the access (public|private) to the object files. So even if your generic is not intended to be used by the outside world, you have to either make it public or place the submodule alongside the module:
! gf_generic_mod.f90
module mod1
implicit none
private
interface g
module procedure p1
module procedure p2
end interface
interface
module subroutine do_print()
end subroutine
end interface
! #ifdef __GFORTRAN__
! public g
! #endif
public do_print
contains
subroutine p1()
print *, 'Hello world!'
end subroutine
subroutine p2(name)
character(*), intent(in) :: name
print *, 'Hello '//name//'!'
end subroutine
end module
! gf_generic_smod.f90
submodule (mod1) sm_generic
implicit none
contains
module procedure do_print
call g()
call g('John')
end procedure
end submodule
! gf_generic_main.f90
use mod1
implicit none
call do_print()
end
$ ifx gf_generic_mod.f90 gf_generic_smod.f90 gf_generic_main.f90 && ./a.out
Hello world!
Hello John!
$ gfortran gf_generic_mod.f90 gf_generic_smod.f90 gf_generic_main.f90 && ./a.out
/usr/bin/ld: /tmp/ccTwqsI7.o: in function `__mod1_MOD_do_print':
gf_generic_smod.f90:(.text+0x5): undefined reference to `__mod1_MOD_p1'
/usr/bin/ld: gf_generic_smod.f90:(.text+0x19): undefined reference to `__mod1_MOD_p2'
collect2: error: ld returned 1 exit status
@jwmwalrus
Exactly right!
Last year we replaced over 200 statement functions in fpt (which is written in Fortran) with internal functions with no change in performance. We tried module functions but the performances was dire. Now the code is slightly more respectable.
That makes me think: how will the current generic feature blend in with PDTs?
module myarray_m
type :: myarray(arr_k, sz)
integer, kind :: arr_k = 4
integer, len :: sz
real(kind=arr_k) :: data(sz)
contains
procedure :: sum => arr_sum
end type
contains
function arr_sum(arr)
type(myarray(sz=*, arr_k=*)) :: arr
real(kind=kind(arr%data)) :: arr_sum
arr_sum = sum(arr%data, kind=kind(arr%data))
end function
end module
@everythingfunctional How would the above pseudocode be implemented using the future generics feature?
Length type parameters can be assumed, so that is what the * still means for the parameter in this case. Since the compiler can not predict all of the valid kind type parameters for derived types, * cannot be used for that parameter. A list of the desired kind type parameters must be provided instead. In this case you at least have a convenient one that can be used. I.e.
generic function arr_sum(arr)
type(myarray(sz=*, arr_k=real_kinds)) :: arr
real(kind=kind(arr%data)) :: arr_sum
arr_sum = sum(arr%data, kind=kind(arr%data))
end function
@hkvzjal I suspect that the lack of templates is one of the reasons that the two are often the same. It wasnât until I started writing libraries intended for use by others that I began to see the need for better support for generic programming. To put it differently, generic programming will make it easier to write libraries for others to use, which could make it more likely that library developers and application developers wonât necessarily be the same person.
I would shed the light from a different angle: I hope that whatever is decided and implemented at the end will make life easier for everyone, especially those who start their Fortran development journey as âapplication developerâ and when realizing that they need to start working on a library to generalize their work would feel confident with a robust and simple-to-use syntax. As it is more likely that for a long time, this person will be the provider and consumer of his/hers codes, having the idea that eventually someone else will use his/her codes to develop on top of it, once proven useful and easy to use.
Iâm just trying to say that this reasoning of âtwo (clear cut) personasâ feels to me dangerous if placed at the heart of the design process for this specific feature; maybe as a happy consequence?
Apologies for digging up an old topic, but I think this one deserves at least a pinned status. So we have discussed the âgenericsâ part of the proposal. Is there somewhere that the final (working) version of the âtemplatesâ can be seen? Is it much different to what was implemented currently in LFortran?