Specific instance of passing a function to a function; not yet connecting all the dots

Hi;

Here’s a failed attempt to learn from the prior posting for help regarding passing function(s) to a procedure/function which I’m not getting some essential fundamental points…

Thanks for the prior help on this topic…

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics; use Ada.Numerics;
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;

procedure Test_Tanh_Sinh_Quadrature is

  function Tanh_Sinh_Quadrature (F : access function (X : Float) return Float;
    Lower, Upper : Float; Steps : Positive; Accuracy : Float) return Float is

    H  : Float := 0.1;
    H0 : Float := (Upper - Lower) / Float (2);
    H1 : Float := (Lower - Upper) / Float (2);
    RR : Float := Float (0);
    RO : Float;
    K  : Positive := 1;
    N  : Natural;
    SS : Float;
    T  : Float;
    SH, CH, TH, DX, XI, WT : Float;
  begin
    loop
      RO := RR;
      N := (2 ** K) - 1;
      SS := Float (0);
      for I in -N..N loop
        T  := Float (I) * H;
        SH := sinh (T);
        CH := cosh (T);
        TH := tanh (SH * Pi / Float (2));
        DX := (CH * Pi / Float (2)) / (cosh (SH * Pi / Float (2)) ** 2);
        XI := H1 + (h0 * TH);
        WT := H * DX;
        SS := SS + (F (XI) * WT);
      end loop;
      RR := H0 * SS;
      exit when abs (RR - RO) < Accuracy;    
      exit when K >= Steps;
    end loop;
    return RR;
  end Tanh_Sinh_Quadrature;

  function F_Sin (X : Float) return Float is
  begin
    return sin (X);
  end F_Sin;

  function F_Exp (X : Float) return Float is
  begin
    return exp (X);
  end F_Exp;

begin
  Put (F_Sin'Access, Tanh_Sinh_Quadrature (Float (0), Float (1), 5, 1.0e-8));
  Put (F_Exp'Access, Tanh_Sinh_Quadrature (Float (-3), Float (3), 5, 1.0e-8));
end Test_Tanh_Sinh_Quadrature;

gnatmake ./test_tanh_sinh_quadrature.adb
gcc -c -I./ -I- ./test_tanh_sinh_quadrature.adb
test_tanh_sinh_quadrature.adb:55:03: error: no candidate interpretations match the actuals:
test_tanh_sinh_quadrature.adb:55:03: error: too many arguments in call to “Put”
test_tanh_sinh_quadrature.adb:55:13: error: expected type “Standard.String”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-tiinio.ads:104, instance at a-inteio.ads:18
test_tanh_sinh_quadrature.adb:55:13: error: expected type “Standard.Integer”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-tiinio.ads:85, instance at a-inteio.ads:18
test_tanh_sinh_quadrature.adb:55:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-tiinio.ads:72, instance at a-inteio.ads:18
test_tanh_sinh_quadrature.adb:55:13: error: expected type “Standard.String”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-tiflio.ads:108, instance at a-flteio.ads:20
test_tanh_sinh_quadrature.adb:55:13: error: expected type “Standard.Float”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-tiflio.ads:88, instance at a-flteio.ads:20
test_tanh_sinh_quadrature.adb:55:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-tiflio.ads:74, instance at a-flteio.ads:20
test_tanh_sinh_quadrature.adb:55:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-textio.ads:508
test_tanh_sinh_quadrature.adb:55:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:55:13: error: found type access to function “F_Sin” defined at line 55
test_tanh_sinh_quadrature.adb:55:13: error: ==> in call to “Put” at a-textio.ads:426
test_tanh_sinh_quadrature.adb:55:22: error: missing argument for parameter “Accuracy” in call to “Tanh_Sinh_Quadrature” declared at line 9
test_tanh_sinh_quadrature.adb:56:03: error: no candidate interpretations match the actuals:
test_tanh_sinh_quadrature.adb:56:03: error: too many arguments in call to “Put”
test_tanh_sinh_quadrature.adb:56:13: error: expected type “Standard.String”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-tiinio.ads:104, instance at a-inteio.ads:18
test_tanh_sinh_quadrature.adb:56:13: error: expected type “Standard.Integer”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-tiinio.ads:85, instance at a-inteio.ads:18
test_tanh_sinh_quadrature.adb:56:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-tiinio.ads:72, instance at a-inteio.ads:18
test_tanh_sinh_quadrature.adb:56:13: error: expected type “Standard.String”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-tiflio.ads:108, instance at a-flteio.ads:20
test_tanh_sinh_quadrature.adb:56:13: error: expected type “Standard.Float”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-tiflio.ads:88, instance at a-flteio.ads:20
test_tanh_sinh_quadrature.adb:56:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-tiflio.ads:74, instance at a-flteio.ads:20
test_tanh_sinh_quadrature.adb:56:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-textio.ads:508
test_tanh_sinh_quadrature.adb:56:13: error: expected private type “Ada.Text_Io.File_Type”
test_tanh_sinh_quadrature.adb:56:13: error: found type access to function “F_Exp” defined at line 56
test_tanh_sinh_quadrature.adb:56:13: error: ==> in call to “Put” at a-textio.ads:426
test_tanh_sinh_quadrature.adb:56:22: error: missing argument for parameter “Accuracy” in call to “Tanh_Sinh_Quadrature” declared at line 9
gnatmake: “./test_tanh_sinh_quadrature.adb” compilation error


RBE

Ok, so what’s happening is you’re calling Put, but passing an access as the first argument, and passing the invocation of the function as the second parameter.

I think you are perhaps confusing yourself, try going in stages.

DEBUGGING:
Declare
  Something : Integer renames Some_Function_Call( Using, Parameters );
Begin
  Put( "Actual text:" & Something'Image );
End DEBUGGING;

The above sort of construct has the advantage of keeping things clearer and allowing the compiler to assist you with the types/error-messages. — Deconstruct your complexities into something simple, you can always reconstruct the complexity later if its needed.

Oh, how obvious a mistake. Thank you.

Here’s a diff from what I had previously to what I have now.

-  Put (F_Sin'Access, Tanh_Sinh_Quadrature (Float (0), Float (1), 5, 1.0e-8));
-  Put (F_Exp'Access, Tanh_Sinh_Quadrature (Float (-3), Float (3), 5, 1.0e-8));
+  Put (Tanh_Sinh_Quadrature (F_Sin'Access, Float (0), Float (1), 5, 1.0e-8));
+  Put (Tanh_Sinh_Quadrature (F_Exp'Access, Float (-3), Float (3), 5, 1.0e-8));

Now it compiles and runs, but I have to verify that I don’t have logic errors as the output doesn’t look quite right:

./test_tanh_sinh_quadrature
-1.11271E-01 7.46062E-02

Thanks,
RBE

I found a bug in my translation of the pseudocode! Now the Ada solution is correct when using locally defined functions and when passing the function as an access parameter! Now I am going to try to understand how to solve this problem using generics.

Thank you for the help! You guys are awesome!

RBE