Tuesday, September 25, 2012

AdaTutor - Advanced Topics (5)

Subprogram Parameters with Generics

The generic part of a subprogram or package can specify a dummy subprogram as well as a dummy type or object.  This is similar to using subprograms as parameters in Algol and Pascal, and to using the little-known keyword EXTERNAL in Fortran.  In Ada, we simply precede the dummy subprogram specification with the keyword with in the generic part.  This use of the word with has nothing to do with context clauses.  Here's the specification of a generic function that has one dummy function specification in the generic part:

generic
   with function Dummy(X : in Float) return Float;
function Definite_Integral(Lower_Limit, Upper_Limit : in Float)
   return Float;

If we instantiate Ada.Numerics.Generic_Elementary_Functions for type Float, and use that instantiation, we get functions like Cos for type Float.  We could then instantiate Definite_Integral for Cos, and make use of it as follows:

 Answer : Float;
 function Definite_Integral_Of_Cos is new Definite_Integral(Cos);
 ...
 Answer := Definite_Integral_Of_Cos(Lower_Limit => 0.0,
                                    Upper_Limit => 1.5708);

generic
   with function Dummy(X : in Float) return Float;
function Definite_Integral(Lower_Limit, Upper_Limit : in Float)
   return Float;

function Definite_Integral(Lower_Limit, Upper_Limit : in Float)
   return Float is
   Mult : array(0 .. 6) of Float := (1.0, 4.0, 2.0, 4.0,
                                     2.0, 4.0, 1.0);
   Sum  : Float := 0.0;
   X    : Float;  -- the independent variable
begin
   for I in 0 .. 6 loop
      X   := Lower_Limit
             + (Float(I) / 6.0) * (Upper_Limit - Lower_Limit);
      Sum := Sum + Mult(I) * Dummy(X);
   end loop;
   return Sum * (Upper_Limit - Lower_Limit) / 18.0;
end Definite_Integral;
This is one possible body for the generic function Definite_Integral.  (We've repeated the specification above the body for reference.)  This function integrates the function Dummy between the two limits by evaluating Dummy at seven points and using Simpson's rule.  (Definite_Integral could be improved by making the number of points a generic parameter, instead of fixing it at seven.)

< prev   next >

No comments: