From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,86d58622defcc2b3 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!wns14feed!worldnet.att.net!attbi_s71.POSTED!53ab2750!not-for-mail From: "Jeffrey R. Carter" Organization: jrcarter at acm dot org User-Agent: Thunderbird 1.5 (Windows/20051201) MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Why is Function Defined Twice? References: <126erl3o7kb1p1a@corp.supernews.com> In-Reply-To: <126erl3o7kb1p1a@corp.supernews.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Message-ID: NNTP-Posting-Host: 12.201.97.176 X-Complaints-To: abuse@mchsi.com X-Trace: attbi_s71 1147634719 12.201.97.176 (Sun, 14 May 2006 19:25:19 GMT) NNTP-Posting-Date: Sun, 14 May 2006 19:25:19 GMT Date: Sun, 14 May 2006 19:25:19 GMT Xref: g2news2.google.com comp.lang.ada:4254 Date: 2006-05-14T19:25:19+00:00 List-Id: 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