# Type bound generic procedures

**URL:** <https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604>\
**Category:** Help\
**Created:** [March 13, 2024, 8:19am UTC](https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604 "2024-03-13T08:19:18Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shahid](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/shahid/32/3672_2.png) [@Shahid](https://fortran-lang.discourse.group/u/Shahid)\
**Post date:** [March 13, 2024, 8:19am UTC](https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604/1 "2024-03-13T08:19:18Z")

</div>

I wish to understand how does type bound generic procedures work. Here, it seems to be working fine with the subroutine but not with the function.

1. Below is the module containing subroutine for type bound generic procedure

```auto
module genmod
    
    type:: gen
        real:: x,y
        contains
        
        generic :: g=>p1,p2
        procedure, pass :: p1, p2
    end type
    
    contains
    
    subroutine p1(a,b)
        class(gen), intent(in):: a
        real, intent(out) :: b
        b=a%x **2+a%y** 2
    end subroutine
    
    subroutine p2(a,b)
        class(gen), intent(in)::a
        integer,intent(out) ::b
        b=a%x+a%y
    end subroutine
    
end module genmod

```

with the main program

```auto
program generic_test
    use genmod
    type(gen) :: x=gen(2.0,3)
    integer :: c
    real :: d
    
    call x%g(d) 
    print *, d
    
    call x%g(c) 
    print *,c
    
end program

```

1. Here is the module containing function. It shows the error

> Error: ‘p1’ and ‘p2’ for GENERIC ‘g’ at (1) are ambiguous

```auto
module genmod
    
    type:: gen
        real:: x,y
        contains
        
        generic :: g=>p1,p2
        procedure, pass :: p1, p2
    end type
    
    contains
    
    function p1(a)
        class(gen), intent(in):: a
        real :: p1
        p1=a%x **2+a%y** 2
    end function
    
    function p2(a)
        class(gen), intent(in)::a
        integer ::p2
        p2=a%x+a%y
    end function
    
end module genmod

```

The function type is different here; one is integer and the other is real. So I was expecting it to be working due to different data types. This raises the question, does it work only with different number of arguments in case of functions? For example, if I change the number of arguments - shown below, there is no compilation error !

```auto
    function p2(a,b)
        class(gen), intent(in)::a,b
        integer ::p2
        p2=a%x+a%y
    end function

```

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [March 13, 2024, 9:15am UTC](https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604/2 "2024-03-13T09:15:40Z")

</div>

That’s expected. When you call the generic function, how can the compiler know which actual function you really want? The type of the result does not help, because a function result is evaluated on its own, independently of the expression where it appears.

---

<div class="post-metadata">

**Author:** ![themos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/themos/32/521_2.png) [@themos](https://fortran-lang.discourse.group/u/themos)\
**Post date:** [March 13, 2024, 9:47am UTC](https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604/3 "2024-03-13T09:47:21Z")

</div>

Some languages that offer overloading (and strong typing) also offer syntax to select a function based on the type of result, for example:

> a = g(x)@Integer

Fortran does not.

---

<div class="post-metadata">

**Author:** ![kimala](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/kimala/32/2707_2.png) [@kimala](https://fortran-lang.discourse.group/u/kimala)\
**Post date:** [December 3, 2024, 10:45am UTC](https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604/4 "2024-12-03T10:45:00Z")

</div>

If you allow me to hijack this thread, I have a related question. I am writing a module that wraps the NetCDF procedures to make them a little less verbose and I am stuck at the design of the `read` routine. What I would like to achieve is to have a single `read` routine that handles under the hood all the possible cases. And if I were designing this as a generic procedure, all would be simple and easy, write the routines for all the cases you need (in the following example, single and double precision for both one and two dimensional arrays), wrap them around an interface and everything is done. Moreover, if I understood correctly the procedure check is done at compile time so it should be as fast in execution as calling the actual procedure.

However, how can I achieve a similar result for a derived data type? The following MWE should illustrate the structure I would like to follow.

```fortran
module test
    !! This module contains...
   use, intrinsic :: iso_fortran_env, only: real32, real64
   implicit none
   private

   integer, parameter :: sp = real32
   integer, parameter :: dp = real64

   type, public :: grid
      integer :: file_id
   contains
      procedure :: read_1D_sp
      procedure :: read_2D_sp
      procedure :: read_1D_dp
      procedure :: read_2D_dp
   end type grid

   ! This is how generics work for non type-bound procedures
   public :: read
   interface read
      module procedure read_1D_sp
      module procedure read_2D_sp
      module procedure read_1D_dp
      module procedure read_2D_dp
   end interface

contains

   subroutine read_1D_sp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(sp), allocatable, intent(inout) :: arrayOut(:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10))
   end subroutine read_1D_sp

   subroutine read_2D_sp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(sp), allocatable, intent(inout) :: arrayOut(:,:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10,10))
   end subroutine read_2D_sp

   subroutine read_1D_dp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(dp), allocatable, intent(inout) :: arrayOut(:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10))
   end subroutine read_1D_dp

   subroutine read_2D_dp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(dp), allocatable, intent(inout) :: arrayOut(:,:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10,10))
   end subroutine read_2D_dp

end module test

program testgrid
   use, intrinsic :: iso_fortran_env, only: real32, real64
   use test
   implicit none
   type(grid) :: ggrid
   real(real32), allocatable :: single_1D(:)
   real(real32), allocatable :: single_2D(:,:)
   real(real64), allocatable :: double_1D(:)
   real(real64), allocatable :: double_2D(:,:)

   print *, allocated(single_1D)
   call read(ggrid, single_1D) ! This is good!
   print *, allocated(single_1D)

   print *, allocated(single_2D)
   call ggrid%read_2D_sp(single_2D) ! This is less good
   print *, allocated(single_2D)   

   ! What I desire is to have something like
   !call ggrid%read(single_2D)
end program

```

I don’t understand how tho structure the code to arrive at something like

```fortran
call ggrid%read(single_1D)

```

instead of having to call the specific routine `read_1D_sp` and what would be the rationale for that structuring. Thanks

---

<div class="post-metadata">

**Author:** ![mEm](https://avatars.discourse-cdn.com/v4/letter/m/90ced4/32.png) [@mEm](https://fortran-lang.discourse.group/u/mEm)\
**Post date:** [December 3, 2024, 12:06pm UTC](https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604/5 "2024-12-03T12:06:33Z")

</div>

I guess you are looking for generic type-bound procedures:

```fortran
module test
    !! This module contains...
   use, intrinsic :: iso_fortran_env, only: real32, real64
   implicit none
   private

   integer, parameter :: sp = real32
   integer, parameter :: dp = real64

   type, public :: grid
      integer :: file_id
   contains
      generic, public :: read => read_1D_sp, read_2D_sp, read_1D_dp, read_2D_dp
      procedure, private :: read_1D_sp
      procedure, private :: read_2D_sp
      procedure, private :: read_1D_dp
      procedure, private :: read_2D_dp
   end type grid

contains

   subroutine read_1D_sp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(sp), allocatable, intent(inout) :: arrayOut(:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10))
   end subroutine read_1D_sp

   subroutine read_2D_sp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(sp), allocatable, intent(inout) :: arrayOut(:,:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10,10))
   end subroutine read_2D_sp

   subroutine read_1D_dp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(dp), allocatable, intent(inout) :: arrayOut(:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10))
   end subroutine read_1D_dp

   subroutine read_2D_dp(self, arrayOut)
      class(grid) , intent(in ) :: self
      real(dp), allocatable, intent(inout) :: arrayOut(:,:)
      !
      if (.not.allocated(arrayOut)) allocate(arrayOut(10,10))
   end subroutine read_2D_dp

end module test

program testgrid
   use, intrinsic :: iso_fortran_env, only: real32, real64
   use test
   implicit none
   type(grid) :: ggrid
   real(real32), allocatable :: single_1D(:)
   real(real32), allocatable :: single_2D(:,:)
   real(real64), allocatable :: double_1D(:)
   real(real64), allocatable :: double_2D(:,:)

   ! What I desire is to have something like
   call ggrid%read(single_2D)
end program

```

---

<div class="post-metadata">

**Author:** ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)\
**Post date:** [December 3, 2024, 1:14pm UTC](https://fortran-lang.discourse.group/t/type-bound-generic-procedures/7604/6 "2024-12-03T13:14:10Z")

</div>

There are a couple of implementations using this design pattern in stdlib that I’m aware of, you might draw some inspiration out of them:

> <https://github.com/fortran-lang/stdlib/blob/662ad1a1e80a69a0cb65838bedf0b7a50989c30a/src/stdlib_codata_type.fypp#L25>

> <https://github.com/fortran-lang/stdlib/blob/662ad1a1e80a69a0cb65838bedf0b7a50989c30a/src/stdlib_sparse_kinds.fypp#L43>
