Wywołania zwrotne (callbacks)#
Wywołanie zwrotne to funkcja przekazywana innej funkcji jako argument.
Preferowanym sposobem tworzenia wywołań zwrotnych jest zapewnienie abstrakcyjnego interfejsu deklarującego sygnaturę wywołania zwrotnego. Pozwala to na użycie kontroli czasu kompilacji dla przekazanego wywołania zwrotnego.
module integrals
  use types, only: dp
  implicit none
  private
  public :: simpson, integrable_function
  abstract interface
    function integrable_function(x) result(func)
      import :: dp
      real(dp), intent(in) :: x
      real(dp) :: func
    end function
  end interface
contains
  function simpson(f, a, b) result(s)
    real(dp), intent(in) :: a, b
    procedure(integrable_function) :: f
    real(dp) :: s
    s = (b-a) / 6 * (f(a) + 4*f((a+b)/2) + f(b))
  end function simpson
end module integrals
Funkcja może być następnie użyta z wywołaniem zwrotnym przez zaimportowanie modułu, tak jak pokazano w następującym przykładzie
module demo_functions
  use types, only: dp
  implicit none
  private
  public :: test_integral
contains
  subroutine test_integral(a, k)
    real(dp), intent(in) :: a, k
    print *, simpson(f, 0._dp, pi)
    print *, simpson(f, 0._dp, 2*pi)
  contains
    function f(x) result(y)
      real(dp), intent(in) :: x
      real(dp) :: y
      y = a*sin(k*x)
    end function f
  end subroutine test_integral
end module demo_functions
Eksportowanie abstrakcyjnego interfejsu pozwala na tworzenie wskaźników procedur z poprawną sygnaturą oraz na dalsze wydłużenie wywołania zwrotnego, tak jak pokazano poniżej
module demo_integrals
  use types, only: dp
  use integrals, only: simpson, integrable_function
  implicit none
  private
  public :: simpson2, integrable_function
contains
  function simpson2(f, a, b) result(s)
    real(dp), intent(in) :: a, b
    procedure(integrable_function) :: f
    real(dp) :: s
    real(dp) :: mid
    mid = (a + b)/2
    s = simpson(f, a, mid) + simpson(f, mid, b)
  end function simpson2
end module demo_integrals
