Delegates: No more need for Inheritance?

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

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)

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