Why don\'t we see C-like languages that allow for callables with polymorphism in the return type? I could see how the additional type inference would be a hurdle, but we hav
Because of auto-conversion of types, it is not obvious to know which function to call when return types are close.
If by "return type polymorphism" you mean overloading based on the return value type, I'm not sure about other languages, but for C++ here's the answer (pretty much from the horse's mouth):
Function return types don't come into play in overload resolution simply because Stroustrup (I assume with input from other C++ architects) wanted overload resolution to be 'context independent'. See 7.4.1 - "Overloading and Return Type" from the "C++ Programming Language, Third Edition".
The reason is to keep resolution for an individual operator or function call context-independent.
They wanted it to be based only on how the overload was called - not how the result was used (if it was used at all). Indeed, many functions are called without using the result or the result would be used as part of a larger expression. One factor that I'm sure came into play when they decided this was that if the return type was part of the resolution there would be many calls to overloaded functions that would need to be resolved with complex rules or would have to have the compiler throw an error that the call was ambiguous.
And, Lord knows, C++ overload resolution is complex enough as it stands...
i would love to see this feature in some language, not only so that function foo could return a double or an int or a string, but also so that foo could return a structure or objects of different classes. Disambiguating calls would be fairly trivial - if the call is ambiguous, require a cast to select the return type desired. Example:
string s = foo(); //foo returns a string
double x = foo(); //foo returns a double
int i = foo(); //foo returns an integer
float f = (float)(int)foo(); //call the int foo and convert to float
in addition
Animal a = fooFactory(); //fooFactory returns an Animal
Plant p = fooFactory(); //foofactory returns a Plant
these situations do not come up very often, but when they do the workaround is often fairly ugly...
double x = (double)foo();
The above is ambiguous if there are versions of foo() that can return double, int, float, etc.
In C++ you can do this with classes to a large extent. For example, say I have a data type that is routinely converted to ASCII on input and output;
typedef char* pchar;
class MyType
{
public:
operator pchar() { return(ConvertToASCII()); }
MyType& operator=(char* input) { ConvertFromASCII(input); return(*this); }
pchar ConvertToASCII();
void ConvertFromASCII(pchar ASCII);
}
This type of thing is often used in C++ frameworks. For example, have a look at the implmentation of the MFC CString class. IMHO, it is a very useful tool, albeit dangerous in certain circumstances.