title: Can I overload a type-bound procedure based on the number of arguments?
body: <p>I'm working on an aerodynamics code (source code <a href="https://github.com/usuaero/MFTran" rel="nofollow noreferrer">here</a>) using good old Fortran. Part of the initialization is reading in a file which contains information on a surface mesh, basically a set of triangular or quadrilateral panels making up the surface. I'd like to describe both quadrilateral and triangular panels using a single type <code>panel</code>. To do that, I've written two initialization functions <code>panel_init_3</code> and <code>panel_init_4</code> which will load the data into the type based on how many vertices the panel has. I'd like to bind these to my <code>panel</code> type and overload them based on the number of arguments (i.e. if it gets passed an integer and 3 vertex objects, then <code>panel_init_3</code> gets called and similarly for 4 vertex objects.</p>
  <p>Here is the source code for the type:</p>
  <pre><code>module panel_mod
  
      use linked_list_mod
      use vertex_mod
  
      implicit none
  
  
      type panel
          ! A panel with an arbitrary number of sides
  
          integer :: N ! Number of sides/vertices
          type(vertex_pointer),dimension(:),allocatable :: vertices
          real,dimension(3) :: n_hat ! Normal vector
          real :: A ! Surface area
  
          contains
  
              procedure :: init =&gt; panel_init_3, panel_init_4
              procedure :: calc_area =&gt; panel_calc_area
              procedure :: calc_normal =&gt; panel_calc_area
  
      end type panel
  
      
  contains
  
  
      subroutine panel_init_3(this, v1, v2, v3)
          ! Initializes a 3-panel
  
          implicit none
  
          class(panel),intent(inout) :: this
          type(vertex),intent(in),target :: v1, v2, v3
  
          ! Set number of sides
          this%N = 3
  
          ! Allocate vertex array
          allocate(this%vertices(this%N))
  
          ! Store info
          this%vertices(1)%ptr =&gt; v1
          this%vertices(2)%ptr =&gt; v2
          this%vertices(3)%ptr =&gt; v3
  
          ! Calculate normal vec
  
          ! Calculate area
  
      end subroutine panel_init_3
  
  
      subroutine panel_init_4(this, v1, v2, v3, v4)
          ! Initializes a panel with 4 sides
  
          implicit none
  
          class(panel),intent(inout) :: this
          type(vertex),intent(in),target :: v1, v2, v3, v4
          
          ! Set number of sides
          this%N = 4
  
          ! Allocate vertex array
          allocate(this%vertices(this%N))
  
          ! Store info
          this%vertices(1)%ptr =&gt; v1
          this%vertices(2)%ptr =&gt; v2
          this%vertices(3)%ptr =&gt; v3
          this%vertices(4)%ptr =&gt; v4
  
          ! Calculate normal vector
  
          ! Calculate area
  
      end subroutine panel_init_4
  
  
      subroutine panel_calc_area(this)
  
          implicit none
  
          class(panel),intent(inout) :: this
  
      end subroutine panel_calc_area
  
  
      subroutine panel_calc_normal(this)
  
          implicit none
  
          class(panel),intent(inout) :: this
  
      end subroutine panel_calc_normal
  
      
  end module panel_mod
  </code></pre>
  <p>This module compiles fine. But, when it gets used here</p>
  <pre><code>...
  ! Initialize triangular panel
  if (N == 3) then
     call panels(i)%init(vertices(i1+1), vertices(i2+1), vertices(i3+1)) ! Need +1 because VTK is 0-indexed
  
  ! Initialize quadrilateral panel
  else
     call panels(i)%init(vertices(i1+1), vertices(i2+1), vertices(i3+1), vertices(i4+1))
  end if
  ...
  </code></pre>
  <p>I get the compiler message</p>
  <pre><code>   70 |                     call panels(i)%init(vertices(i1+1), vertices(i2+1), vertices(i3+1), vertices(i4+1))
        |                                                                                                       1
  Error: More actual than formal arguments in procedure call at (1)
  </code></pre>
  <p>Am I reaching beyond the capabilities of Fortran, or is there a way to do this? I realize I could do this all without binding and overloading, but I like how clean it'd be. I am using gfortran 9.3.0.</p>