Note that these posts are intended to provoke a discussion, so that we can benefit from your feedback and come up with a better design.

What’s out there

The previous post concluded with the following (incomplete) list of solutions to the problem of multiple inheritance available in other languages:

Java and C# have classes and interfaces, i.e. multiple interface inheritance and single implementation inheritance;

Scala has classes and traits that may implement methods and even have state, but their constructors can not have parameters;

Some other languages, like Fortress, do not allow state in traits;

We all know that Java’s approach is rock-solid, but imposes severe limitations on code reuse, so we would like to relax these limitations, but without getting ourselves into trouble. “First degree” of relaxing the limitations would be stateless traits (like in Fortress, and in [1]): no state in traits, no implicit overrides. Or we can trade inheritance of traits off for state and get mixins (like in Ruby). Relaxing the limitations even more we get to Scala’s traits that have state but no parameters for constructors, and one trait may override functions of another. Then we get to CZ’s classes with requires (as presented in [2]). The next step, I guess, would already be unrestricted multiple inheritance, like in C++.

We will skip a thorough analysis of each of these solutions, and just make a remark about state.State. One important consideration is whether to allow multiple inheritance of state in this or that form. On the one hand, it seems to be very useful, but on the other hand, it imposes problems. One problem was discussed in the previous post under the name of Problem 2:

the implementation of Left assumes it’s initialized with 3, but it may call bar() that is implemented in Right and assumes everything is initialized with 4. This may cause some inconsistent behavior.

Another problem is that having state in a unit of inheritance (a class or trait or mixin) implies having a constructor there, and constructors may have side effects, and it’s important that those come in a predictable order.

Problem 2 is rather elegantly fixed by the Scala’s approach of having no parameters in the trait constructors. Unfortunately, the problem of constructor side-effects still stands: changing inheritance relations between traits (e.g. done by a library-writer) may reorder side-effects of their constructors upon creating a subclass instance (see this comment below). And this problem seems to be inevitable no matter what approach to multiple inheritance of state we choose (I wish someone could prove me wrong here!).

All that said, I’ll explain a design we are currently considering. As mentioned above, the purpose of this text is to start a discussion, so your feedback is very welcome.

The Kotlin way (Attempt #2)

First, I would like to note that at this point, we prefer conservative solutions, so that we could naturally extend them later if the set of features they provide is not enough.

that can “require” classes to be present in the set of supertypes of a concrete class that uses the trait,

with no automatic resolution for overriding conflicts: if a class inherits two implementations of something, it must override this something and provide its own implementation (i.e., choose from the inherited ones, or write its own from scratch, or mix the two).

So, we refrain from having multiple inheritance of state for now. I think it’s OK if we try it this way and consider relaxing the limitations later, if there’s a real demand for that.

Syntax. Now, let’s render this in some syntax. First question here is “Should we still call those stateless guys classes, or have a special term?” They differ from classes by imposing some limitations, and for now it is that they don’t have any state. If there are only classes, the user will fall into the following situation:

Nothing tells me that this class is special, so

I add a piece of state, and

the compiler complains about having no constructor, so

I simply add a constructor, and

get errors from some other classes telling me that I broke someone’s supertype lists, so

it takes some time before I track down the real cause of the error, which is no good.

It would be a lot better if I knew that this class bears some restrictions in the first place, so I wouldn’t make any changes blindly, and if I made a bad change, the compiler would know that I have violated a local restriction, and would complain appropriately. So, it’s better to have traits differ syntactically from unrestricted classes. So, let’s have a keyword trait in front of the declaration, rather than class1.

So, we have classes (state and all, but single inheritance) and traits (no state, no constructor, but multiple inheritance). Traits can declare (“require”, is CZ terms) one superclass, but not initialize it:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

open classMyClass(){

fun foo(){...}

}

trait MyTrait:MyClass{// MyClass is not initialized

fun bar(){

foo()// calls foo() from MyClass

}

}

classChild:MyClass(),MyTrait{// MyClass is initialized

}

classChildErr:MyTrait{// ERROR: MyClass must be a supertype

}

This allows traits to use members of a base class without interfering with the initialization logic.

One other syntactic issue is whether we should have a single homogenous supertype list (like in the example above) or something like Java’s “extends” and “implements” clauses, or even Scala’s “extends Class with Trait1 with Trait2 with Trait3” syntax. The idea of making things explicit speaks for some syntactic separation of a class in the supertype list, for it is privileged in some way, i.e. having something like Java’s “extends” and “implements”, at least. On the other hand, we all know this annoying case in Java, when I turn an interface into an abstract class, and have to change all those subclasses that used to implement the interface, and now must extend the class. The change that could be syntactically local becomes non-local. This is why we’re inclined to have a homogenous supertype list, as in the example above.

Using traits

Now, we prohibit state in traits. It certainly is a significant limitation, but I would like to point out what it is not.

You CAN have properties in your traits. The limitation is that those properties can not have backing fields or initializers, but properties themselves may appear in traits:

1

2

3

4

5

6

7

8

9

10

11

traitTrait{

val property:Int// abstract

fun foo(){

print(property)

}

}

classC():Trait{

override val property:Int=239

}

Our trait declares an abstract property, and the class overrides it with a stateful one. Now, the trait can use the property, and by late binding of calls, if we call foo() on an object of C, we get 239 printed.

You CAN access state in your traits. The previous example shows how you can do it sort of indirectly, by making subclasses override a property you define, but there is another way. Remember that a trait may declare (require) a superclass:

1

2

3

4

5

6

7

8

9

10

11

open classA(x:Int){

valy=x *2

}

traitB:A{

fun foo(){

print(y)

}

}

classC():A(239),B{}

In this example, we have a base class A, that defines a concrete property y and initializes it. The trait B extends this class, but does not pass a constructor parameter in, because traits have no initialization code at all. Note that B has access to the property y defined in A. Now, class C extends A and initializes it with 239, and extends B. Extending B is OK because B requires A, and we extend A, all right.
Now, what happens when we call foo() on an instance of C? It prints 478 (239 * 2), because the value of y is obtained from this instance, and the constructor of C has written 239 there.

Now, let’s look at the last example about traits:

How to resolve overriding conflicts. When we declare many types in out supertype list, it may appear that we inherit more than one implementation of the same method. For example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

traitA{

fun foo(){print("A")}

fun bar()

}

traitB{

fun foo(){print("B")}

fun bar(){print("bar")}

}

classC():A{

override fun bar(){print("bar")}

}

classD():A,B{

override fun foo(){

super<A>.foo()

super<B>.foo()

}

}

Traits A and B both declare functions foo() and bar(). Both of them implement foo(), but only B implements bar() (bar() is not marked abstract in A, because this is the default for traits, if the function has no body). Now, if we derive a concrete class C from A, we, obviously, have to override bar() and provide an implementation. And if we derive D from A and B, we don’t have to override bar(), because we have inherited only one implementation of it. But we have inherited two implementations of foo(), so the compiler does not know, which one to choose, and forces us to override foo() and say what we want explicitly.

I think, it’s enough for today. Your comments are very welcome, as usual.

One good way to do it is to have a qualifier on a class declaration, i.e. trait class instead of just class (we could say just trait, but there are some language extensibility considerations against it, which I do not want to dive into now).

But we have found a simple solution to our language extensibility problem, and the problem does not stand any more.

Diamonds are not corner cases, they may arise in library+user code system without any of the authors knowing without it, which basically prevents library writers from ever introducing new superclasses to existing classes, which is a very severe limitation.

In case you meant to ask a question. As mentioned in the post, Scala traits have constructors whose side effects may be reordered if hierarchy changes. This is unpredictable, and we would like to avoid this as long as we can.

First, about constructors in Scala traits. In Scala, you can initialize a member variable in a trait with some arbitrary code, or even just print something, like this:
trait A {
val x = computeX()
print("A")
}

This means that trait A has a constructor that is executed when an object of a class that mixes this trait in is created. In our example the constructor of A has an obvious side effect of printing “A” to the standard output. One can argue that something like this is not typical, but we should remember that the initializer computeX() may have side effects too, e.g., write something to some sort of a cache. So traits in Scala have constructors, and these constructors may have side effects.

Now, let’s look at another trait and a class that mixes both traits in:
trait B {
print("B")
}
class AB() with A with B {
}

Ok, when I create an instance of AB(), the side effects are ordered according to the traits coming in, i.e. it prints “A” and then “B”.

Now, my library evolves, and in the version 2 I decided to make my trait A extend B:
trait A extends B {
val x = computeX()
print("A")
}

Look: I didn’t touch the class AB. I didn’t even touch the code inside the traits’ constructors, I only reused some of the code by extending B in A. But what the client who wrote AB gets is that the side effects are reordered: new AB() now prints “B” and then “A”.
And this may cause bugs that are really difficult to track down, especially because the client code did not change AT ALL.

Aren’t those things you call “constructors” not pretty much akin to instance initializers, which even Java had from the early days?

Looking at your problem at hand, I think it is completely academic. There are always things you can’t do as a library producer. It is like this in Java, in Scala and in pretty much every other language, too.

Considering that the proposed goal of Kotlin is to “publish zero papers” about it, I think any solution here is far away from the possible design space. You probably have to take some existing approach and compromise.

If you still haven’t figured out substantial parts of the language’s inheritance mechanism, how realistic is a beta release at the end of the year?

The problem I described exists in Scala and does not exist in Java, because Java interfaces, unlike Scala traits, do not have “those things”.
You might not be able to do some things as a library writer in any language. But it does matter what things you can’t do.

So, I’d better deliver a language without this problem (and a possibility of relaxing the limitation at expense of introducing this problem, if it appears to be really needed, in practice).

As mentioned in the post, there are some language extensibility considerations. Basically we would like some external plugins to allow traits to have all the syntactic elements of classes. This does not mean that a plugin could alter the inheritance model, but it can leverage, say, constructor syntax for traits to allow users to “instantiate” them by calling their “constructors” that would be actually compiled down to some factory method taking instances from a container, like DI frameworks do. For all this it is convenient if trait is syntactically just a special case of class, so having “trait” as a modifier is the easiest way to achieve this.

The gain from state in traits like in scala outweighs the risks.
If a library writer changes print(a + b) to print(b +a) in its code, then any dependent class gets the same effect. It does not matter, whether the change is procesural or declarative. I believe coders will quickly learn to be aware of that. After all they are writing traits and not plain classes. Writing Scala, I was acutely aware of initialisation order and side effects.

And doing it like Scala reduces learning. You can simply tell any Scala user, that they can use traits as before.
Don’t just be different, fpr the sake of it.

Well, for me, the benefits at least are in dealing with third-party class hierarchies. To give a concrete example:

Android has a class called “Activity”, which corresponds roughly to a single screen of a mobile app, and a bunch of convenience subclasses — ListActivity, PreferenceActivity, MapActivity, and so forth — that support particular styles of interaction. Activities have an “onDestroy” hook that gets called when they are shut down — to terminate associated AsyncTasks, close associated Databases, unregister as an Observer of whatever kind, and so forth. But doing things this way can lead the implementation of all of these things to get coupled, in a single onDestroy that becomes a bit of a kitchen sink.

One way to mitigate the coupling is to mix in a trait that runs a bunch of callbacks in its onDestroy, and supplies a method to add a callback to the list. That, in turn, lets you write an openDatabase which registers the associated “close” as a callback.

In Scala, that’s easy — the list of callbacks is state (an extra attribute) that’s declared and managed by the trait. You could, alternatively, produce an ActivityWithCallbacks base class that manages the associated state (or implements the cleanup stuff directly). But then you couldn’t use it for MapActivity, whose superclass is plain Activity, not your variant.

By the way, in this example, the ordering consideration is really unlikely to arise, since the state is effectively private to the trait. Conversely, when you have constraints that are all manipulating base-class state (because they can’t have state of their own), that might arguably make them more likely to step on each others’ toes, not less — particularly if the implementers of some of the traits in question chose to use a particular piece of base-class state in incompatible ways. In particular, this sort of thing could easily introduce ordering incompatibilities, or worse, between traits that could otherwise happily coexist.

(BTW, one of my current projects is a Scala library for trying to mop up boilerplate in Android apps using this sort of technique, Positronic Net. Looking over the available material on Kotlin, it looks like it might be preferable generally — but a restriction to stateless traits would be a real stumbling block.)

It might, at that. Where I can imagine that getting awkward is if there are multiple trait-like entities that build on the Callbacks functionality in different, but compatible, ways. But it handles the simple version of the problem well enough…

The basic thought was that if we wound up with multiple extensions in a class hierarchy of delegates rooted at “CallbacksImpl”, that might ultimately lead to similar issues involving multiple inheritance at that level…

Well, the way we got to “CallbacksImpl” was to avoid having “Callbacks” as a stateful trait. The situation I’m imagining is what would be, in Scala, multiple other traits which build on the Callbacks functionality in various ways, but add some extra state of their own. There’s at least the potential for a tower of delegates with delegates, which could get awkward to manage.

(BTW, once again, the usual case is that each of these traits is adding state for its own use, to avoid stepping on the toes of the others — in which case, the ordering considerations you’re worried about don’t matter much.

Where ordering has mattered, in my experience, is with traits that override base-class methods to add their own special behavior, in ways which may not refer to trait-private state at all. For instance, in ScalaTest, the behavior you get by mixing both BeforeAndAfterEach and OneInstancePerTest into a Suite depends on the order in which you do it. Each overrides the runTests method — the first to call beforeEach and afterEach setup and teardown methods around each test, the second to create a separate test suite instance for running each test. So, if you add both, does beforeEach get called in the main test suite instance, or the private “InstancePerTest” copies? Depends on the order in which they’re mixed in.

So, ordering issues do arise here, but not due to trait-private state: so far as I can tell, neither trait declares any.)

The ordering problems I am worried about do not necessarily have anything to do with who uses the state, because problems arise upon initialization and involve side effects of constructors (that can come in unpredictable order). Overriding something in a base class can always be troublesome, whether you have traits or not.

If we are talking about keeping a little private state for our own, delegation looks like a pretty good fit. If there are a dozen variations of Callbacks implementations, they can build upon each other as an essentially separate hierarchy of classes and maybe traits and/or delegation, which seems OK to me.

The main reason is that with delegation you don’t get true overriding, because the object you delegate to does not know that is is being delegated to, i.e. is you “override” some of its methods, it wouldn’t know that you did.

Well, here’s more from ScalaTest. I’ve already mentioned the BeforeAndAfterEach and OneInstancePerTest traits. Those still work as traits in Kotlin (as proposed); they’re stateless. However, there are also stateful traits that can get mixed into a Suite — for instance, the FixtureSuite trait, which needs to add state of its own to keep track of the fixtures that it’s managing.

In Scala, these are all traits, so there’s a single way to add these standard extensions to suites. I guess in Kotlin, you’d need two: one for the stateless extensions (as traits), and another for the stateful ones (as delegates).

However, FixtureSuite also wants to override some of the base class methods — in fact, the same ones as the other two. If I read your last message right, it’s awkward for delegates to do that, which means that implementing FixtureSuite would get awkward…

Well, it boilds down to if you want to create a toolbox like Scala with many ways to do similar things or less ways as in Java.
I had the impression that you wanted to go the Java way here, to keep things simple.

The C# thing was meant to be: you could implement it in a way that you modify the behavior of the delegate, so it’s syntactic sugar for the first example (an inlined E)

Well, the example with E has the following disadvantages:
1. It eats up memory (especially PermGen space). In this sense traits are much better: no objects created at all, only constant number of .class files generated (vs. as many as subtypes in the E-example).
2. The “C# way” requires delegation to go only to a newly created object, I cannot use, say, a parameter for that. That’s a huge limitation that seems to defeat the whole purpose of delegation as such.

On the toolbox business. If we drop traits alltogether, we are left with classes, delegation and interfaces. Still three things. Following your argument, it’s much more appealing to drop delegation, but we are aiming at eliminating boilerplate here, and delegation introduces a lot of it if not supported on the language level…

While I really like programming in Scala; I’m also liking where Kotlin’s going (particularly with the goal of a fast compiler and a great IDEA plugin :).

However the worst thing about Scala by a mile is the ‘recompile all your code and your dependencies on the same major version of the scala compiler & make sure all your transitive dependencies do the same’ issue. One thing Java really got right was having a minimum bytecode level (1.5, 1.6 or whatever) so that all new compilers can output old bytecode and all your jars just worked & it doesn’t much matter which version of the compiler built the jars.

With Scala thats not the case; every library developer has to cross compile for every major version of scala (and really you probably should do minor too to be safe) leading to jar & dependency problem explosions; then release cycles all block on 1 dependency dragging its heels or upgrading too quickly or whatever; you get stuck unable to upgrade until every transitive dependency has been rebuilt and re-released.

It seems Scala’s stateful traits are the main culprit; changing a trait means classes using it need to be recompiled & if those traits are from the Scala SDK then everything has to be rebuilt.

To be honest; I’d rather a nice simple stable ecosystem of jars/bundles/modules which are compiler version agnostic than have the benefit of stateful traits; so I just wanted to say (in a rather long winded manner keep up the good work – but please try to keep Kotlin a compiler that generates bytecode thats Kotlin-version-safe & is capable of reusing older and newer Kotlin-compiled-code without major issues. Plus try to not make backwards incompatible changes to whatever Kotlin Development Kit you ship (I’m guessing you’ll have a library with map / filter / flatMap / join and whatnot on collections kinda like Guava but available as Extension methods etc).

I’d be much happier using just delegation and stateless traits if it means there’s no issues of which version of Kotlin was used to compile which jar. While in the early days of a language it can be tricky to fully maintain bytecode generated by older and newer compilers – I hope fairly early on you can get Kotlin to generate stable bytecode that can be mixed and matched easily among different Kotlin bytecode. Forcing the Kotlin ecosystem of jars to all rebuild should be a last resort every now and again (like the leap from 1.4 => 1.5 => 1.6).

So I’d much rather you prioritise bytecode stability above fancy features like solving diamond inheritence or stateful traits

Binary compatibility: we pay attention to what changes make clients recompile. Really. It is very important for us.
Version compatibility: we guarantee nothing before version 1.0 is out. But after that, backward compatibility will stand firm. (And we do not expect any production code in Kotlin to be written outside JetBrains before Kotlin 1.0 is out.)

now, with the above design, if I understand correctly, I have absolutely no way of benefiting from the useful stuff in both C and D. I’ve never encountered this case since I mostly program in java nowadays and can’t recall having done anything similar in scala, so I don’t know how much of an issue it could be, but I see how I could get really frustrated when I would encounter something like that.

I don’t think this blocking case you mention is likely to be a problem, because if something requires A, and something else requires B, this means that these two thing can’t do their useful stuff without being A and B respectively, and if they are designed this way, the design implies that you can’t have them both.

I do enjoy stateful traits in Scala, really. You see, for our educational project we’ve invented a tiny XML-(de)serialization library (mostly to get rid of clumsy Scala XML API).

Our objects are mutable (yes, this approach makes our library already a bit out of the True Scala Way), because most of the time they are handled by application-wide cache (yes, mutable objects are shared across different threads, and we are totally OK with it), or they are used thread-locally and do not require external synchronization.

Now, lots of our classes are composed of stateful traits. We define lots traits like these:

Now, if we were not allowed to have state in traits (in my example it would mean “no vals inside!”), we would replace these mutable attributes inside with methods, and eventually come up with something like this:

So for our project it would mean a handful of boilerplate lines in every implementation, which could be safely avoided with stateful traits.

On the other hand, I do like the order (in general sense), and I would prefer the overall tranquility over my own habits. Specifically, given that stateless trait limitation really helps to organize and discipline the code around, I would gladly rewrite it to conform to this new, more efficient paradigm.

Now what I don’t like with this solution is that I have to declare variables in my class enforced by the contract with the trait where those variables are declared abstract. Reason is that I thought I had delegated all this to the trait and it’s not my concern anymore. I think a lot developers will think that way. Most of them don’t understand what the problem for the compiler constructor is here. Unless he reads some blog entry like this one. I like very much the way the Kotlin language creators communicate with people interested in the project. Ceylon is also trying to do this, but they do it much less. For all others there is at best a mailing list.

Nevertheless, most developers wil just look at this and say: “No, what’s the gain?. Then I just go with Scala traits”. Not wanting to be rough. But that’s the way most “ordinary developers” like me will think, I believe. What I personally would do to get around it is this:

Now, the overridden vars from the trait are out of my sight and >that’s all I want<. My question is now whether the compiler could generate that AbstractRectangle class and insert it silently so that the developer wouldn't know about it. If the developer declared

What IMHO people are looking for in a language that will make them change from Java is extension methods, traits, closures (Java interoperability has to remain there, of course). JDK8 has closures and JDK8 default methods give you the same as what stateless traits give you except that you cannot have protected default methods. Extensions methods are really nice to have, but they won’t make you change language. If the problems with stateful traits can be solved, I’ll be the first one to develop everything in Kotlin :-).

First a disclaimer: although I worked on Java, my knowledge of language design is relatively limited. That said, my book “Coding: On Software Design Process” has a couple sections at the end describing an interesting approach to type extension: “type arithmetic” and “type enhancers”. Although very sketchy, these ideas might be an interesting starting point for something less sketchy. The key feature of type enhancers is that they work only through the public API of the object being enhanced (a “that” reference). This means that constructor ordering is not an issue and you can enhance even final types like String. Through type arithmetic you can combine types not only by type declaration, but instantly through various kinds of usage. There could easily be some fatal flaw in my ideas here, but they might be worth a look anyway. — Jon