Delegates: No more need for Inheritance?


#1

I lately had a look at Google Go which does not support inheritance. Instead it provides language built-in delegates. When I first saw it appeared absolutely obvious to me: no more single inheritance, multiple inheritance (with it's problems), traits (and stateful traits have their problems), nor mixins. It's all done through delegates. Okay, admittedly, delegates in Go are a simple construct. For instance, there is no protection of methods nor inst vars, and no late binding (which is a problem, I think). But in Kotlin these things can be done:

trait Base {   protected fun base() : Unit {   println("base")   } }

open class BaseImpl : Base {

}

trait Base2 {
  fun base2() : Unit {
  println(“base2”)
  }
}

open class BaseImpl2 : Base2 {

}

open class Bar() {
  protected fun bar() {
  println(“bar”)
  }
}

class Foo(b : Base = BaseImpl(), b2 : Base2 = BaseImpl2()) : Base by b, Base2 by b2, Bar() {
  fun foo() : Unit {
  base()
  base2()
  bar()
  }
}


And then running this:

{
    val foo = Foo()
    foo.foo()

  
}


will print:

        base2
        bar

I don't really see a difference to inheritance here. You get just the same bang. You don't even see that you get it through delegates instead of inheritance. The solution above is a bit verbose, yes. You have to implement and additional class BaseImpl and BaseImpl2. Then, this is a little verbose compared to inheritance:

class Foo(b : Base = BaseImpl(), b2 : Base2 = BaseImpl2()) : Base by b, Base2 by b2

Nevertheless, I keep asking myself seriously whether we can cross inheritance out. Find a more concise way to define lists of delegates (see code above), get a fix for KT-3029 and that's it. Don't get me wrong. I have been developing 10 years with Smalltalk (truly OO) and 10 years with Java (well, oops ...). But I think I know what inheritance is and I'm starting to get a feeling that it is a construct which back then was defined too narrow and resulted in a too narrow harness. Then it caught on, probably because people jump on everything that is new. And then it was a success you can't stop. I think late binding and classes were much more important than inheritance.

Any opinions?
Cheers, Oliver


#2

1) We have to support inheritance to interop woth the rest of the world 2) Many problems of multiple inheritance arise with multiple delegation (see the early Kotlin inheritance model)


#3

2) Many problems of multiple inheritance arise with multiple delegation (see the early Kotlin inheritance model)

Ah, I see. When I played with the code mentioned in the first post I renamed Base2.base2() to Base2.base() to see what happens. The ambiguity was flaged immediatedly by the IDE and hence I thought implicitly that diamond problems seem to be caught by the compiler. What a pity ... Might be the reason delegates in Go are that simple.

– Oliver