Overloaded Subprograms in Ada

125 Views Asked by At

Our Programming Languages professor told us that:

"In Ada, the return type of an overloaded function can be used to disambiguate calls (thus two overloaded functions can have the same parameters)"

So this implies that in Ada, we could do something like this:

function Func (Var : Integer) return Integer;
function Func (Var : Integer) return Float;

And then create different implementations of these two functions, therefore overloading them.

This does not make much sense to me, how can the return type alone be sufficient to distinguish between overloaded subprograms? How would we even go about deciding which one of these functions we meant to call when we do decide to use them?

1

There are 1 best solutions below

0
Jere On

Your professor is correct. Ada is able to use where you are storing the result as a clue to which version of the function to call. For example, if you are saving or passing the result into a variable of Integer type, it will call the integer version. If you are saving or passing the result into a variable of Float type, it will call the float version. See for example:

with Ada.Text_IO; use Ada.Text_IO;
procedure jdoodle is
    function Func (Var : Integer) return Integer is (Var*2);
    function Func (Var : Integer) return Float   is (Float(Var) * 4.0);
    
    v1 : Integer := Func(2);
    v2 : Float   := Func(2);
begin
    Put_Line(v1'Image);
    Put_Line(v2'Image);
end jdoodle;

Now there are still instances where you can run into ambiguity. Say for example the following procedures also exist:

procedure Print_Image(Value : Integer);
procedure Print_Image(Value : Float);

if you try to call them like this:

procedure Print_Image(Func(2));

You'll get ambiguity because the place you are saving the result has two different options and there is no clue for the compiler to know which to pick. However, Ada also has "qualified expressions" to help solve this problem. Consider this updated example:

with Ada.Text_IO; use Ada.Text_IO;
procedure jdoodle is
    function Func (Var : Integer) return Integer is (Var*2);
    function Func (Var : Integer) return Float   is (Float(Var) * 4.0);
    
    procedure Print_Image(Value : Integer) is
    begin
        Put_Line("Integer:" & Value'Image);
    end Print_Image;
    
    procedure Print_Image(Value : Float) is
    begin
        Put_Line("Float:" & Value'Image);
    end Print_Image;
    
begin
    -- Notice the Integer'() wrapped around the function call
    -- This is a qualified expression that tells the compiler 
    -- which return type it expects.  It is different from
    -- a cast which transforms the value.  A qualified expression
    -- is a hint to the compiler.  They use an apostrophe between
    -- the type and the parenthesis
    Print_Image(Integer'(Func(2)));  
    Print_Image(Float'(Func(2)));
end jdoodle;