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,1540032852ee6d61 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!wns13feed!worldnet.att.net!attbi_s72.POSTED!53ab2750!not-for-mail From: "Jeffrey R. Carter" User-Agent: Thunderbird 1.5.0.9 (Windows/20061207) MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Why does this work? (overloads) References: <1170823163.681564.186260@s48g2000cws.googlegroups.com> In-Reply-To: <1170823163.681564.186260@s48g2000cws.googlegroups.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Message-ID: NNTP-Posting-Host: 12.201.97.213 X-Complaints-To: abuse@mchsi.com X-Trace: attbi_s72 1170874963 12.201.97.213 (Wed, 07 Feb 2007 19:02:43 GMT) NNTP-Posting-Date: Wed, 07 Feb 2007 19:02:43 GMT Organization: AT&T ASP.att.net Date: Wed, 07 Feb 2007 19:02:44 GMT Xref: g2news2.google.com comp.lang.ada:9087 Date: 2007-02-07T19:02:44+00:00 List-Id: Jerry wrote: > (1) Why does the following work? Because Ada was designed so you can do this. > (2) Have I done something stupid or dangerous? No. > > -- From a-ngrear.ads (Ada 2005, Generic Real Arrays > -- instanciated with Long_Float)... > type Real_Vector is array (Integer range <>) of Real'Base; -- Vectors > function "*" (Left, Right : Real_Vector) return Real'Base; -- Inner > product > > -- From some of my own overloads... > function "*" (x, y : Real_Vector) return Real_Vector; -- element-by- > element > function "+" (a : Long_Float; x : Real_Vector) return Real_Vector; > > -- Some declarations... > f, x, H : Real_Vector(0 .. NN - 1); Note that in mathematics, matrices and vectors are indexed from 1. 1 .. NN also avoids the common error of forgetting the "- 1". > a : Long_Float; > > -- And finally, two lines of calculation... > H := 1.0 + f * x; -- Adds scalar, 1.0, to a vector using my overload > above. > a := 1.0 + f * x; -- Adds scalar, 1.0, to another scalar, an inner > product. > > Why when calculating H doesn't the compiler interpret f * x as an > inner > product then generate an error, after adding 1.0, when trying to make > the > assignment to H which is a vector? Because the context of overload resolution for "+" (ARM 8.6) doesn't allow this if there is another interpretation that isn't an error. The expected type of the result of "+" is a Vector for H, so the result of "+" must be a Vector. The only "+" that takes a real left operand and returns a Vector takes a Vector right operand. Therefore, the expected type of F * X is a Vector, and the only candidate for that is your "*". Similar resolution takes place for A. The expected type of "+" is Long_Float. The only "+" that takes a real left operand and returns a Long_Float is the predefined "+" for Long_Float. Therefore, the expected type of F * X is Long_Float, and the only candidate for that is the inner product. > Obviously the compiler figures out which of the * operators to use > depending on the assigned-to variable. Is this reliable for more > complicated > calculations? I wonder if it is possible to create an ambiguity that > would > be resolved "in the wrong way" and I would get incorrect results. No. You can create an ambiguity, but then the compiler must reject it. An example: procedure Ambiguous is type T is array (Integer range <>) of Integer; function F return T; -- F1 function F (I : Integer) return Integer; -- F2 function F return T is -- null; begin -- F return T'(5 => 7); end F; function F (I : Integer) return Integer is -- null; begin -- F return I + 2; end F; V : Integer := F (5); --??? begin -- Ambiguous null; end Ambiguous; Is the call to F a call to F1, with the result indexed by 5, or a call to F2 with a parameter of 5? I can't tell, and neither can the compiler. GNAT says ambiguous.adb:19:19: ambiguous expression (cannot resolve "F") ambiguous.adb:19:19: possible interpretation at line 5 ambiguous.adb:19:19: possible interpretation at line 4 You should be able to say V := T'(F) (5); to indicate a call to F1, but GNAT complains, saying a binary operator is expected between ')' and '('. This seems to be a compiler error. T'(F) should be a value of type T, which can then be indexed. After all, you can say X : constant T := T'(F); V : Integer := X (5); You can say V := F (I => 5); to indicate a call to F2. -- Jeff Carter "No one is to stone anyone until I blow this whistle, do you understand? Even--and I want to make this absolutely clear--even if they do say, 'Jehovah.'" Monty Python's Life of Brian 74