Why can't overloads take into account the return type.

  • Thread starter Thread starter Michael C
  • Start date Start date
Very deep problems.

Consider the example.

y = F(F(x))

Given y is type A, in a system where there are types A and B.

F(x) is defined for

A F( A )
A F( B )
B F( A )

y = F(F(x))

Let x be of type A

can resolve to either

y = F( F<B>( A ) )

or

y = F( F<A>( A ) )

This is actually avoidable. The language would force a rule that says
a function return may not be used as a parameter to another function.
You would always have to assign through temporaries and that would be
safe. The only problem that comes into play though, would be for
overloads of things like the . or the -> operator, which are
effectively functions themselves.

If I have X -> operator
and Y -> operator

Then I would not be able to write X->Y->Z without introducing
ambiguity. You would then have to write something with a lot of
temporaries.

A Y = X->Y
B Z = Z->Y

which, honestly, is a lot of typing, even though it might make for
better practice as it is easier to debug.
 
In that case it is simple, notions such as object x should drive the
type selection.

string x = Foo() + Foo()

gives you the overload for string, and likewise for int.
 
stork said:
This is actually avoidable. The language would force a rule that says
a function return may not be used as a parameter to another function.

of it could just be written as Calc((int)Parse("1"))

Michael
 
Michael C said:
of it could just be written as Calc((int)Parse("1"))

And you'd know that this case indicates return type rather than being a cast
of

double Parse(String s)

because ... ?

Casts already mean at least two different things in C#

double d;
Object o;

(int)d
remove the fractional part of d, resulting in an int

(int)o
leave o unchanged, but throw an exception if it's not an int

Note that:

Object o = 12.2;
Console.WriteLine((int)o);

throws an exception, because "throw an exception if it's not an int" is
enforced strictly. (I had to try it to be sure.)

Now you're adding another meaning, which is "give the compiler a hint about
which overload to choose". I'm less than enthusiastic about making an
already complex situation more so.
 
Mike Schilling said:
Now you're adding another meaning, which is "give the compiler a hint
about which overload to choose".

Isn't this the same thing:

DoSomething((long)1);

?
I'm less than enthusiastic about making an already complex situation more
so.

I don't see it as that complex. Programmers have already learnt to handle
the types of parameters into a function. A lot of people have said it would
be too complex for ms but I'm sure they could manage it.

Michael
 
I think the straight answer to this question is that YES, a language can be
implemented such that the return type can be taken into account during
overload resolution. It's similar to asking if a language implementation may
include a return type as part of the method signature. The answer is also yes.

Now, to the academic arguments:
(i) Do we need it? I don't see much use for it. But that's only an opinion.
(ii) Will it cause problems? The ambiguity issues proposed so far does not
impress me. However, I have a more theoretic concern with semantics, ie: what
does the function do? A set of functions by the same name that takes the same
exact input but produces different results is an oxymoron. A named function
should do the same exact thing to the same exact set of inputs. If you want
the same set of inputs to produce different results, you should consider a
different function.

P
 
Well , I don't agree with your answer, primary reason is that when u design
a compiler then it is upto u , u can definitely overload on the basis of
return type as well using attibutes of "Attributes Context Free Grammer " .
But this probably requires an overhead & thus it increases complexity of
compiler. That 's why compiler writer don't normally prefer doing it.

I will appreciate any comments on it.
 
An overload is based on a methods signature, which is its name and its
parameters. When you call a function like:

MyFunction("Foo");

and then like:

MyFunction("Bar");

The compiler must make a distinction between the two in order to determine
which overload to call. In this case, the name and parameters are the same,
so the same method would be called.

The assignment, like the following

int x = MyFunction("AddNumbers");

occurs after the method call has been chosen. At this point, the compiler is
matching the return type of the method it chose based on the methods
signature and parameteres passed with the type the value is being assigned
to.

While you could argue that the compiler could see that you have 10 different
functions that take strings of the same name, and it could look to see what
type of return value you were looking for, this would remove the type safety
you are given in C#. This works fine for an untyped language where the type
does not matter. But why then would you care about the return type?

Hope this helps...

Frisky
 
Frisky said:
This works fine for an untyped language where the type
does not matter.

In untyped (and dynamicly-typed, are those really what you mean with
untyped?) languages overloading (static method-dispatch) is not possible
at all -- there are no types to dispatch on available ;)
 
IMO, there's a much simpler answer to all of this.

Loose typing means a slow application.

FoxPro for years had no typing at all. A variable was typed once
something was stored in it and that variable's type could change simply
by assigning it a new value of a different type.

Why was it slower? Because FoxPro could not be compiled down to
machine code and an interpreter was always running, even at run time.

FWIW, even if the C# developers *could* come up with a way to support
loose typing of functions, I don't think that they would. It would
encourage bad code design.
 
FoxPro for years had no typing at all.

That is not exactly right. Machine code and assembly have no typing at all,
everything is a byte. VBScript is type safe, just not strictly typed
(variables don't have explicit types, but the values they contain do). C is
strictly typed (all variables have a type), but not type safe (anything can
be cast into anything else, even if it makes no sense).
 
:)

Very true! Sometimes I must type before I think.

Obviously I was just contrasting. (I guess it didn't work)
 
Back
Top