I always though that dichotomy missed the point. You can give-up inheritance for generics, for interfaces (as if those were a different thing), for type classes, or for type ducking; but you can't give-up inheritance for composition because the only thing composition solves is code reuse.
Interfaces are a different thing than inheritance, precisely because of what we are talking about. Inheritance is about code re-use, and interfaces are about polymorphism. Interfaces are the polymorphism part of "inheritance", while dropping the code re-use part.
It is true that composition does not give you polymorphism, absolutely.
> because the only thing composition solves is code reuse.
Exactly. Inheritance combines polymorphism and code re-use in one form. If you instead don't have inheritance, than interfaces (or something similar by a different name; or "duck-typing" if you don't have static typing and also don't really want any kind of typing at all) give you polymorphism, so what gives you code re-use? Composition.
If you split the code re-use function from the inheritance function, interfaces plus composition is the (or one very common/obvious) solution.
I don't think we are disagreeing, I mean to show you we are all violently agreeing. :)
I do see some value on the "automatic linking" part, but deciding you don't want the complex mixed concept on your idiom isn't any radical idea that will change your life (neither for the better nor for the worse).
Not necessarily; see "Interface vs. Implementation (eg. private derivation in C++) inheritance".
I think the big abstraction problem inheritance solves is overrides. I think there’s a lot of FP cargo culting that overlooks the benefits of the ability to override (when used wisely). But aside from that I’m not sure there’s any reason to think inheritance is any more or less polymorphic than composition for a language with sufficient reflection/introspection support. If you lack type introspection it’s a different story. Maybe I’m missing your point though.
Favor composition is just that your solution will most likely be better with it. There are still cases where you want inheritance but also most likely you don't want to create class hierarchy with 5 levels and everything inheriting form everything else but maybe have have a base class. So even in single application or microservice you might still have some inheritance and most likely more composition.
Besides composition uses interfaces heavily because you want to use DI with constructor injection and then you can switch implementation even at run time.
Interfaces are fine.
The problem with inheritance is the code reuse mechanism