A lot of people who only know inheritance and can't understand why a lot of us slag on it so much don't understand how inheritance conflates implementation and interface. Polymorphism based on interface is a fundamental tool of programming. The way inheritance also drags along an implementation turns out not to be, and to probably be more trouble than it's worth. There are other ways of bringing along implementation, including the basic function, and those work better.
When inheritance is your only tool for interface, I absolutely agree that it looks fundamental, but the fundamentalness is coming from the interface side. Once you separate out interface from implementation, it turns out I have little to no use for the implementation portion.
I have also been programming in Go for a long time now. I sketched out an inheritance system once for an exercise. It's doable, though it's a terrible pain in the ass to use. I've kept it in my back pocket in case it is ever the right solution to a problem even so... but it never has been. And that's not because of any irrational hate for the pattern itself. I've imported other foreign patterns sometimes; I've got a few sum types, even though Go isn't very good at it, because it was still the best solution, and I've got a couple of bits of code that are basically dynamically typed, again because it was the best solution, so I'm not against importing a foreign paradigm if it is the correct local solution. Inheritance just... isn't that useful. The other tools that are available are sufficient, and not just begrudgingly sufficient or "I'm insisting they're sufficient to win the argument even though I know they really aren't"... they really are sufficient. Functions are powerful things, as the functional programming community (it's right there in the name) well knows.
When inheritance is your only tool for interface, I absolutely agree that it looks fundamental, but the fundamentalness is coming from the interface side. Once you separate out interface from implementation, it turns out I have little to no use for the implementation portion.
I have also been programming in Go for a long time now. I sketched out an inheritance system once for an exercise. It's doable, though it's a terrible pain in the ass to use. I've kept it in my back pocket in case it is ever the right solution to a problem even so... but it never has been. And that's not because of any irrational hate for the pattern itself. I've imported other foreign patterns sometimes; I've got a few sum types, even though Go isn't very good at it, because it was still the best solution, and I've got a couple of bits of code that are basically dynamically typed, again because it was the best solution, so I'm not against importing a foreign paradigm if it is the correct local solution. Inheritance just... isn't that useful. The other tools that are available are sufficient, and not just begrudgingly sufficient or "I'm insisting they're sufficient to win the argument even though I know they really aren't"... they really are sufficient. Functions are powerful things, as the functional programming community (it's right there in the name) well knows.