Does exist any language that:
- is statically (and strongly) typed
- supports generics (templates)
- supports traits / multiple inheritance / interface delegation
- allows function overloading (of inherited members, too)
Basically, in pseudo-code, I want this:
class Template<SomeType> { void function(SomeType i) {} }
class Composed extends Template<int>, Template<double> { };
Composed composed;
composed.function(3); //calls function(int)
composed.function(2.5); //calls function(double)
From the wiki list http://en.wikipedia.org/wiki/Multiple_inheritance#Implementations I tried to write code in following programming languages (I also included newest yet-unpublished-1.0-version (2013) languages like Kotlin, Ceylon):
- C++ almost possible, but cannot resolve overloaded function for composed variable
- Scala compile error: trait inherited twice; even if tricked with indirect inheritance it still produces error; see also other guy's question about multiple generic mixin inheritance in Scala
- Eiffel compile error: no function overloading
- Ceylon traits cannot have variables (and no protected members, so no trick for storing data in derived class, traits in Ceylon are useless)
- Fantom no generics/templates
- Kotlin compile error: supertype appears twice; delegation looks unique, but it's not useful, because one can access neither protected members nor variable that is delegated to
- Rust no function overloading; traits cannot store data; traits cannot have defined methods (with body) - issue that's being worked on;
- OCaml compile error: no function overloading; it also didn't check type of parameter for my function, so how "statically typed" it really is?!
- Curl compile error: no function overloading; it also doesn't check function body unless it's called, so how "statically typed" it really is? is it compiled at all or interpreted?!
- Gosu is a bad joke, it's not usable at all: cannot write and implement simple interface with one mathod (error: ClassFormatError: Illegal field modifiers). Who actually does use this language?!
By the way: I thought of this problem when I tried to put Java support for listeners into separate class (in many classes there is: List<ListenerType> ... addListener(...) ... removeListener(...))
C++ almost works:
template <typename T>
class Template { public: void function(T i) {} };
class Composed : public Template<int>, public Template<double> { };
Composed composed;
composed.Template<int>::function(3); //i want: composed.function(3);
((Template<double>&)composed).function(2.5); //i want: composed.function(2.5);
Edit: in C++, problem is inheritance function hiding. See also Function with same name but different signature in derived class and Why does an overridden function in the derived class hide other overloads of the base class?
Edit 2: in C++, with templates and partial specialization, there is possibility of dirty trick to allow usage of trait simpler:
#include <iostream>
#include <typeinfo>
class Void { };
template <class A, class B> class CleverTrait;
template <class A, class B> class CleverTrait;
template <class A> class CleverTrait<A, Void>
{
public:
void function(A arg) { std::cout << "Hello for type " << typeid(A).name() << std::endl; }
};
template <class A, class B> class CleverTrait<A, CleverTrait<B, Void> > : public CleverTrait<B, Void>
{
public:
using CleverTrait<B, Void>::function;
void function(A arg) { std::cout << "Hello for type " << typeid(A).name() << std::endl; }
};
class ComposedByClever : public CleverTrait<double, CleverTrait<int, Void> > { };
int main()
{
ComposedByClever composedByClever;
composedByClever.function(5);
composedByClever.function(2.3);
return 0;
}
This means this particular example in C++ works, however if unrelated traits shared function name, there is no way to inherit-and-using-all-functions in C++.
Edit 3: I should be also checking any programming language, that supports mixins: http://en.wikipedia.org/wiki/Mixins#Programming_languages_that_use_mixins
- D works, but only through string manipulation mixin, so refactoring is broken in such case:
mixin(GenerateSomething!("IfClassNameHereManualRenaming"));
Edit 4: added "Gosu" language comment.
Edit 5: Gosu programming language has update 0.10.2 which fixed the interfaces-are-broken problem. However, even though they claim to have reified generics and delegation, delegation + reified generics does not work.