Live data from Hacker News

Inheritance was invented as a performance hack (2021)

catern.com

71–80 of 252 posts

Re: Inheritance was invented as a performance hack (2021)

#71
Performance is not a hack. Title is wrong... ;-)

Interfaces are indeed much nicer, but you have to make sure that your program language doesn't introduce additional overhead.

Don't be the guy that makes Abstract Factory Factories the default way to call methods. Be aware that there are a lot of people out there that would love to ask a web-server for instructions each time they want to call a method. Always remember that the IT-Crowd isn't sane.

Re: Inheritance was invented as a performance hack (2021)

#72
post #10

I'm not sold the evidence is there to show inheritance is a good idea - it basically says that constructors, data storage and interfaces need to be intertwined. That isn't a very powerful abstraction, because they don't need to be and there isn't an obvious advantage from doing so over picking up the concepts separately as required. And inheritance naturally suggests grouping interfaces into a tree in the way that se…

Yeah ya... everyone likes to go on and on about how inheritance is the root of all evil and if you just don't use it, everything will be fine. Sorry, it won't be fine. Your software will still be a mess unless it is small and written three times by the same person who knows what they are doing. The bottom line is, no one ever really used inheritance that much anyway (other than smart people trying to outsmart themsel…

> The bottom line is, no one ever really used inheritance that much anyway

That's just false. Before Java abstract factory era there was already a culture of creating deep inheritance hierarchies in C++ code. Interfaces and design patterns (including factories) were adopted as a solution to that mess and as bad as they were - they were still an improvement.

Re: Inheritance was invented as a performance hack (2021)

#73
post #43
post #36

Earlier quoted context omitted.

> The bottom line is, no one ever really used inheritance that much anyway If you think that, you have no idea how much horrible code is out there. Especially in enterprise land, where deadlines are set by people who get paid by the hour. I once worked on a java project which had a method - call a method - call a method - call a method and so on. Usually, the calls were via some abstract interface with a single imple…

I don't think Inheritance is always bad - sometimes it's a useful tool. But it was definitely overused and composition, interfaces work much better for most problems. Inheritance really shines when you want to encapsulate behaviour behind a common interface and also provide a standard implementation. I.e: I once wrote a RN app which talked to ~10 vacuum robots. All of these robots behaved mostly the same, but each wa…

To me (as a Java programmer) inheritance is very useful to reuse code and avoid copy paste. There many cases in which decorators or template methods are very useful and in general I find it "natural" in the sense that the concepts of abstraction and specialization can be found in plenty of real world examples (animals, plants, vehicles etc etc).

As usual there is no silver bullet, so it's just a tool and like any other tool you need to use it wisely, when it makes sense.

Re: Inheritance was invented as a performance hack (2021)

#74
post #36

Earlier quoted context omitted.

Yeah ya... everyone likes to go on and on about how inheritance is the root of all evil and if you just don't use it, everything will be fine. Sorry, it won't be fine. Your software will still be a mess unless it is small and written three times by the same person who knows what they are doing. The bottom line is, no one ever really used inheritance that much anyway (other than smart people trying to outsmart themsel…

> The bottom line is, no one ever really used inheritance that much anyway If you think that, you have no idea how much horrible code is out there. Especially in enterprise land, where deadlines are set by people who get paid by the hour. I once worked on a java project which had a method - call a method - call a method - call a method and so on. Usually, the calls were via some abstract interface with a single imple…

"But there's a reason the crowd is moving against inheritance"

Yes, in our fad-chasing industry the pendulum has moved in the other direction. Let's wait few years.

There is nothing wrong with OOP, inheritance, FP, procedural, declarative or whatever. What is bad is religious dogma overtaking engineering work.

Re: Inheritance was invented as a performance hack (2021)

#75
There is this wonderful presentation by Herb Sutter talking about how the C++ concept “class” covers over 20 other abstractions, and that Bjarne’s choice for C++ was the right choice since it offers so much power and flexibility and expressive power in a concise abstraction.

Other languages (just like the article) only saw the downsides to such a generic abstraction that they added N times more abstractions (so split inheritance, interfaces, traits, etc) and rules for interactions that it significantly complicated the language with fundamentally no effective gains.

In summary, Herb will always do a better job than me explaining why the choices in the design of C++ classes, even with multiple inheritance, is one of the key factors of C++ success. With cppfront, he extends this idea with metaclasses to clearly describe intent. I think he is on the right track.

Re: Inheritance was invented as a performance hack (2021)

#76

IMHO Inheritance (especially the C++ flavored inheritance with its access specifiers and myriad rules) has always scared me. It makes a codebase confusing and hard to reason with. I feel the eschewing of inheritance by languages such as Go and Rust is a step in the right direction. As an aside, I have noticed that the robotics frameworks (ROS and ROS2) heavily rely on inheritance and some co-dependent C++ features li…

To me, inheritence makes sense if you view your codebase as actual "Objects" The reality is that a codebase is not that simple. Many things you create are not representable as realworld "objects" - to me, this is where is gets confusing to follow especially when the code gets bigger. I remember those OOP books (I cannot comment on modern OOP books) where the first few chaptors would use Shapes as an example. Where A…

I’m not on the cutting edge of gamedev, but I still believe that ECS is a solid pattern with lots of use cases.

Re: Inheritance was invented as a performance hack (2021)

#77
post #65

Earlier quoted context omitted.

> But there's a reason the crowd is moving against inheritance. I doubt it; the majority of code is in enterprise projects, and they do Java and C# in the idiomatic way, with inheritance. I'm working on an Android project right now, and inheritance is everywhere! So, sure, if you ignore all mobile development, and ignore almost all enterprise software, and almost all internal line-of-business software, and restrict y…

Java and C# are already a huge step up from what came before, since they at least introduce the concept of an interface as a distinct thing from a parent class. The fact that you don't notice that is proof that progress does happen, if only slowly.

Java wasn't the first to do that Objective-C (10? years before) had interfaces.

Even C++ has that with multiple inheritance - some parents can just be interfaces.

As to whether Smalltalk needs interfaces see https://stackoverflow.com/a/7979852/151019 and https://www.jot.fm/issues/issue_2002_05/article1/

Re: Inheritance was invented as a performance hack (2021)

#78
post #51

Earlier quoted context omitted.

> I don't think Inheritance is always bad - sometimes it's a useful tool. I can only think of one or two instances where I've really been convinced that inheritance is the right tool. The only one that springs to mind is a View hierarchy in UI libraries. But even then, I notice React (& friends) have all moved away from this approach. Modern web development usually makes components be functions. (And yes, javascript…

The problem is of course that there is no useful default behavior you can define when the trait is so isolated and generic.

Don't mix implementation and interface inheritance.

Re: Inheritance was invented as a performance hack (2021)

#79
I find that structural typing is the most useful thing and unfortunately few languages support it. I'd like a language where:

- If I have a class Foo and interface Bar, I should be easily able to pass a Foo where Bar is required, provided that Foo has all the methods that Bar has (sometimes I don't control Foo and can't add the "implements Bar" in it).

- I can declare "class Foo implements Bar", but that only means "give me a compilation error if Bar has a method that Foo doesn't implement" - it is NOT required in order to be able to pass a Foo object to a method that takes a Bar parameter

- Conversely, I should be able to also declare "interface Foo implementedBy Baz" and get a compilation error if either one of them is modified in a way that makes them incompatible (again - this does not mean that Baz is the _only_ implementor, just that it's one of them)

- Especially with immutable values - the same should apply to data. record A extends B, C only means "please verify that A has all the members that B & C have, and as such whenever a B record is required, I can pass an A instead". I should be able to do the reverse too (record B extendedBy A). Notably, this doesn't mean "silently import members from B, and create a multiple-inheritance-mess like C++ does".

(I do understand that there'd be some performance implications, but especially with a JIT a feel these could be solved; and we live in a world where I think a lot of code cares more about expressiveness/ understandability than raw performance)

Re: Inheritance was invented as a performance hack (2021)

#80
post #39

Earlier quoted context omitted.

> Literally think about it. How else do you merge two structs if not using inheritance? What? Using multiple inheritence? That's one of the worst ideas I've ever seen in all of computer science. You can't just glue two arbitrary classes together and expect their invariants to somehow hold true. Even if they do, what happens when both classes implement a method or field with the same name? Bugs. You get bugs. I've bee…

>What? Using multiple inheritence? You just threw this in out of nowhere. I didn't mention anything about "multiple" inheritance. Just inheritance which by default people usually mean single inheritance. That being said multiple inheritance is equivalent to single inheritance of 3 objects. The only problem is because two objects are on the same level it's hard to know which property overrides which. With a single cha…

> But assume there are 3 objects with distinct properties...

Why would we assume that? If the objects are entirely distinct, why are you combining them together into one class at all? That doesn't make any sense. Let distinct types be distinct. Let consumers of those types combine them however they like.

> But fundamentally there's no OTHER SIMPLER way to merge two objects without resorting to complex nesting. [...] You have two classes A and B and both classes have 90% of their properties shared. What is the most fundamental way of minimizing code reuse? Inheritance. That's it.

So now the objects have 90% of their properties shared. That's different from what you were saying earlier. But moving on...

The composition answer is similar to the inheritance answer. Take the common parts and extract them out into a self contained type. Use that type everywhere you need it - eg by including it in both A and B.

> given this: A = {a, b, c, d} I want to create this: B = {a, b, c, d, e}. [...] What's the best way to define B while reusing code?

Via composition, you do it like this:

    B = { a: A, e }
What could be simpler than that?

You keep claiming that inheritance is simpler. But then you go on to say this:

> The problem with inheritance has to do with human capability. We can't handle the complexity that arises from using it extensively. [..] It is human nature or our incapability of DEALING with the complexity that arises from it. The issue is the coupling is two tight so you make changes in one place it creates an unexpected change in another place. Our brains cannot handle the complexity.

In other words, using inheritance increases the complexity of the resulting code for the human brain. It makes our code harder to read & understand. I absolutely agree with this criticism you're making.

And that's an incredibly damning criticism, because complexity is an absolute killer. Your capacity to wrangle the complexity of a given piece of code is the single greatest limitation of any software developer, no matter how skilled. Any change that makes your code more complex and harder to understand must be worth it in some way. It must pay dividends. Using inheritance brings no benefit in most cases over the equivalent compositional code. The only thing that happens is that - as you say - it makes the software harder for our brains to handle.

If you ask me, that's a terrible decision to make.

Post reply on HN