Re: Why does this work? (overloads)
- From: "Jeffrey R. Carter" <jrcarter@xxxxxxx>
- Date: Wed, 07 Feb 2007 19:02:44 GMT
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
.
- Follow-Ups:
- Re: Why does this work? (overloads)
- From: Jerry
- Re: Why does this work? (overloads)
- From: Adam Beneschan
- Re: Why does this work? (overloads)
- References:
- Why does this work? (overloads)
- From: Jerry
- Why does this work? (overloads)
- Prev by Date: Re: in defense of GC
- Next by Date: Re: AW: Why does this work? (overloads)
- Previous by thread: RE: Why does this work? (overloads)
- Next by thread: Re: Why does this work? (overloads)
- Index(es):
Relevant Pages
|