A Typed Intermediate Language for Compiling Multiple Inheritance

Juan Chen. A Typed Intermediate Language for Compiling Multiple Inheritance.
This paper presents a typed intermediate language EMI that supports multiple and virtual inheritance of classes in C++-like languages. EMI faithfully represents standard implementation strategies of object layout, "this" pointer adjustment, and dynamic dispatch. The type system is sound. Type checking is decidable. The translation from a source language to EMI preserves types. We believe that EMI is the first typed intermediate language that is expressive enough for describing implementation details of multiple and virtual inheritance of classes.

If you really must have mutiple inheritance...

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Multiple inheritance isn't bad

I've never quite understood why people are so afraid of multiple inheritance. Sure it can cause name clashes but these are statically detectable and also easy to resolve. The benefit you can get from it seems to outweigh the potential harm.

Depends how it's implemented

Multiple inheritance is bad when it doesn't properly distinguish between interface and implementation. C++ is an example of the two being conflated, which has led to problems not just in code but even in the thinking of programmers about the subject — e.g. Scott Meyers and Bill Venners describe their own evolution on this issue in this interview.[*]

Once you properly decouple interface inheritance and implementation inheritance, it's possible to use both effectively, and there are patterns even in C++ to do just that.


[*] Another score for Sapir-Whorf as applied to programming languages. :)

Bah, having only interface ma

Bah, having only interface makes you copy the function again and again.
At least with C++ you can choose if you provide a default implementation for the function or not.

The only convincing thing I've heard against multiple inheritance is that it is complex to implement, but from usage point of view having the choice whether to put default implementation in the "interface" or not is nice IMHO.

I've been using C++ multiple inheritance in one project, the second class hierarchy was used for storing the object in the database.
It worked quite well, even though sometimes it was a bit complicated..

Mixins, traits, etc.

Were not mixins/traits/<other ways that make inheritance interface explicit> supposed to be a modern (or at least not too ancient) and really practical solution for problems with multiple inheritance?

I do agree that sometimes I wish Java had MI for implementations, but then again, I would prefer mixins even better.

Separate language design from implementation, too.

Bah, having only interface makes you copy the function again and again.
At least with C++ you can choose if you provide a default implementation for the function or not.

Presumably you're thinking of Java, which only provides single implementation inheritance. However, that's a limitation of Java, not a problem with the idea of separating interface from implementation.

One of the problems with most OO languages is that they focus too much on one model of implementation reuse - inheritance - at the expense of useful alternatives. In particular, higher-order functions make it easy to share implementations: just write "foo = bar", where bar is bound to a function, and you've just reused the implementation of that function, without having to drag the entire inheritance mechanism into the picture.

I still don't get your first

I still don't get your first point, if you separate interface from implementation whoever use an interface must implement it, leading to code duplication.

I see public inheritance as getting an interface with an (optional) default implementation that you can replace if you don't like it.

For your second point, I disagree too, OO provide inheritance but nobody said that inheritance was useful for just reusing just one function..
Writing C foo(A a,B b) { return bar(a,b); } is not a big deal.. Sure if you can write foo=bar, it's even better but it doesn't matter very much..

Inheritance actually comes in two flavors

There's Type inheritance and then there's Implementation inheritance. Many language implementations conflate these two forms of inheritance, but there are some that don't. Sather and Modula-3 come to mind. In Sather, you use the abstract class with the '

Since it's fresh on my mind, I've also been working on Alice ML. Admittedly the OO support in Alice is rough but you can take advantage of SML's Signatures (types) and Modules (implementation). Signatures use the "include" directive to support type inheritance (only recently fixed in Alice). Modules use the "open" directive to support code inheritance. And with higher order functions, you can always share a function definition within any number of modules by simply assigning a local module name to the name of a function in another module - no duplication of implementation is required.

Anyhow, the point being that the two forms of inheritance do not need to be tied together. Going back to Smalltalk, there really was no type inheritance per se, because type is purely implied by the ability of an object to respond to a message. Smalltalk uses inheritance purely from the standpoint of code re-use. There have been some attempts to add multiple inheritance to Smalltalk, but for the most part they were ignored. Multiple inheritance is much more necessary in the case of types, when the language is statically typed since the ability to treat objects polymorphically hinges on subtyping.

Clarifications

I still don't get your first point, if you separate interface from implementation whoever use an interface must implement it, leading to code duplication.

There are a number of strategies for reusing implementations indepedently of interfaces. Andris mentioned mixins, which you can even use in C++, with some discipline. However, it's not necessarily to have full C++-style multiple inheritance in order to support mixins. There are various other strategies, too — Chris' post talks about some, and the last few paragraphs of this post about separating interface from implementation mention some other possibilities, with references.

For your second point, I disagree too, OO provide inheritance but nobody said that inheritance was useful for just reusing just one function.. Writing C foo(A a,B b) { return bar(a,b); } is not a big deal.. Sure if you can write foo=bar, it's even better but it doesn't matter very much..
My example dealt with one function, but it wasn't intended to be limited to that. With first-class functions, you can reuse entire implementations of interfaces. Presumably, you would consider that a good thing, since you mentioned that you aren't happy about the problems of reimplementing entire interfaces, even though you don't see writing manual delegation for a single method as a problem.