comp.lang.ada
 help / color / mirror / Atom feed
From: "Jeffrey R. Carter" <spam.not.jrcarter@acm.not.spam.org>
Subject: Re: Why is Function Defined Twice?
Date: Sun, 14 May 2006 19:25:19 GMT
Date: 2006-05-14T19:25:19+00:00	[thread overview]
Message-ID: <zuL9g.148784$oL.125364@attbi_s71> (raw)
In-Reply-To: <126erl3o7kb1p1a@corp.supernews.com>

Jason C. Wells wrote:
> 
> I don't understand why the function ASUM is defined twice in the
> following example.  Which version gets called when I use ASUM?  How does
> Ada determine precedence on which gets called?  What is the big concept
> that I need to associate with this practice so I can go do more studying?
> 
> These both look like they do the mostly same thing but with different
> sets of input parameters.
> 
>    function ASUM (
>      N    : Natural;
>      X    : Vector_Type;
>      INCX : Natural
>    ) return Float_Type'Base is
>    begin
>       if N > 0 and (N - 1) * INCX >= X'Length then
>          raise Argument_Error;
>       end if;
> 
>       case Precision is
>          when Single =>
>             return SCASUM (Fortran_Integer (N), X, Fortran_Integer (INCX));
>          when Double =>
>             return DZASUM (Fortran_Integer (N), X, Fortran_Integer (INCX));
>          when Unsupported =>
>             raise Unsupported_Precision_Error;
>       end case;
>    end ASUM;
> 
>    function ASUM (X : Vector_Type) return Float_Type'Base is
>    begin
>       case Precision is
>          when Single =>
>             return SCASUM (X'Length, X, 1);
>          when Double =>
>             return DZASUM (X'Length, X, 1);
>          when Unsupported =>
>             raise Unsupported_Precision_Error;
>       end case;
>    end ASUM;

Generally, you shouldn't be looking at the bodies; you should be looking 
at the specifications. In the specification of this package you should 
find something like

    function ASUM (
      N    : Natural;
      X    : Vector_Type;
      INCX : Natural
    ) return Float_Type'Base;
    -- Some comments explaining what this function does and how to
    -- use it.

    function ASUM (X : Vector_Type) return Float_Type'Base;
    -- Some comments explaining what this function does and how to
    -- use it.

This should be enough information for you to use the package; if it's 
not, the package is probably poorly implemented.

What you are encountering is overloading, and it's a basic Ada concept. 
Multiple subprograms can have the same name if the compiler can tell 
which one is being called. You're already familiar with overloading; 
there's a function "+" for Integer and another function "+" for Float, 
for example. The compiler calls the first when the actual parameters are 
of type Integer and the latter when they're Float.

A procedure has a "parameter profile" based primarily on the types of 
its parameters; a function has a "parameter and result profile" based 
primarily on the types of the parameters and the return type. At the 
point of a call, the types of the actual parameters are compared to the 
types of the formal parameters for all possible subprograms; for 
functions the expected type of the value is compared to the return type 
as well.

For example, you could define

function "+" (Left : Integer; Right : Integer) return Float;
-- Returns Float (Left) + Float (Right).

if you need to convert the sum of 2 Integers to Float frequently.

A : Integer := 1;
B : Integer := 2;
I : Integer := A + B;
F : Float   := A + B; -- 3.0

In this case, the compiler sees that an Integer result is needed for I, 
but a Float for F, and chooses the appropriate "+" for each.

It's not hard to write cases in which the compiler can't tell which 
subprogram to call. You can give the compiler hints, such as using 
actual parameter names in named parameter association. For example

type IA is array (Integer range <>) of Integer;

function F (I : Integer) return Integer;
function F return IA;

X : Integer := F (5); -- ambiguous

This could be a call to the 1st F with a parameter of 5, or a call to 
the 2nd F, followed by indexing the returned array with 5.

Y : Integer := F (I => 5);

This has to be a call to the 1st F.

Z : Integer := (F) (5);

This has to be a call to the 2nd F, followed by indexing.

(In Ada 80, there would be no ambiguity. F (5) has to be a call to the 
1st F; to call the 2nd F you have to write F () (5). However, the empty 
parentheses were soundly denounced during review, and were eliminated 
from Ada 83.)

Perhaps more useful is something like

function F (A : Integer; B : Boolean := True) return Integer;
function F (B : Integer; C : Integer :=    7) return Integer;

X : Integer := F (5); -- ambiguous
Y : Integer := F (A => 5); -- 1st F
Z : Integer := F (B => 5); -- 2nd F

-- 
Jeff Carter
"Perfidious English mouse-dropping hoarders."
Monty Python & the Holy Grail
10



  reply	other threads:[~2006-05-14 19:25 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-14 17:55 Why is Function Defined Twice? Jason C. Wells
2006-05-14 19:25 ` Jeffrey R. Carter [this message]
2006-05-14 19:51 ` Simon Wright
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox