问题
c, java and many other languages do not pay attention to return values.
int i = func()
float f = func()
int func() { return 5 }
float func() { return 1.3}
Why isnt the above legal? Does it make it more difficult to program
int i = func(func(func(func2(func3())))) //you dont know what you are getting
Is it hard to write a compiler? are there more language unambiguity? Is there a language that can do the above?
回答1:
What about this case?
class A implements Foo { /*...*/ }
class B implements Foo { /*...*/ }
A func() { return new A(); }
B func() { return new B(); }
Foo v = func(); // which do you call?!
There are already problems with ambiguity when you allow overloading of a single function name that take different arguments. Having to check the return type as well would probably make resolving the right function a lot harder.
I'm sure a language could implement that, but it would make things a lot more complicated, and would generally make the code harder to understand.
回答2:
Let's say it was allowed, which one would this call:
func();
That may not the the full answer, but I believe that is one reason why it is not legal.
回答3:
Yes, allowing overloading on return types complicates a language. It complicates the resolving of overloaded identifiers (e.g. function names). But it isn't impossible, e.g. Haskell allows to overload function based on their return type.
class Num a where
fromInteger :: Integer -> a
...
Num
is a type class in Haskell with a method called fromInteger
which is a function from an arbitrary size Integer
to an arbitrary type which has an instance of Num
. The Haskell type class mechanism is rather different from the class concept of object-oriented languages. Therefore my explanation might sound strange.
But, the result is I can use the function fromInteger and, depending on the calling context, different implementations are chooen at compile time.
There is a whole line of research on type systems, which made this feature possible. Therefore, I'd say it is doable in statically typed languages. Dynamically typed languages would either require time-travelling or some clever ideas.
回答4:
To avoid ambiguity.
a( int )
a( bool )
int b()
bool b()
a( b() ) -- Which b?
Here type inference has a cyclic dependency. Which b
depends on which a
, but which a
depends on which b
, so it gets stuck.
Disallowing overloading of return types ensures that type inference is acyclic. The return type can always be determined by the parameter types, but the parameter types cannot be determined by the return type, since they may in turn be determined by the parameter types you are trying to find.
回答5:
For a C++ example, consider:
void g(int x);
void g(float x);
g(func());
Which of the overloaded g()
functions would be called?
回答6:
Perl allows a certain degree of return type variation, in that functions can tell what kind of context they're being evaluated in. For instance, a function that might return an array can see that it's running in a scalar context, and just return the putative length directly, sparing the allocation and initialization of the array just to get its length.
回答7:
Most languages allow for mixed-mode operations with automatic coercion (e.g. float + int), where multiple interpretations are legal. Without coercion, working with multiple numeric types (short, int, long, float, double) would become very cumbersome; with coercion, return-type based disambigation would lead to hard-to-understand code.
回答8:
Allowing these may introduce problems. For example:
int i = func2(func());
int func() { return 5; }
float func() { return 1.3; }
int func2(float a) { return a; }
int func2(int a) { return a; }
This is ambiguous.
来源:https://stackoverflow.com/questions/1596628/why-dont-languages-allow-overloading-of-methods-by-return-value