Live data from Hacker News

Inheritance was invented as a performance hack (2021)

catern.com

51–60 of 252 posts

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

#51
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…

> 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 supports many kinds of inheritance. Early versions of react even used them for components. But it proved to be a worse approach.)

I've been writing a lot of rust lately. Rust doesn't support inheritance, but it wouldn't be needed in your example. In rust, you'd implement that by having a trait with functions (+default behaviour). Then have each robot type implement the trait. Eg:

    trait Robot {
        fn stop(&mut self) { /* default behaviour */ }
    }

    struct BenderRobot;
    
    impl Robot for BenderRobot {
        // If this is missing, we default to Robot::stop above.
        fn stop(&mut self) { /* custom behaviour */ }
    }

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

#52
post #35

Earlier quoted context omitted.

> "Trait/Typeclass"-style compositional inheritance as in Rust and Haskell is sublime. It's similar to Java interfaces in terms of flexibility, and it doesn't enforce hierarchical rules. Yes-and-no. Interfaces still participate in inheritance hierarchies (`interface Bar extends Foo`), and that's in a way that prohibits removing/subtracting type members (so interfaces are not in any way a substitute for mixins). Compo…

How are interfaces with ability to provide default implementations for members (which both C# and Java allow today) not a substitute for mixins? "Only reference types can implement interfaces" is simply not true in C#. Not only can structs implement them, but they can also be used through the interface without boxing (via generics).

> How are interfaces with ability to provide default implementations for members (which both C# and Java allow today) not a substitute for mixins?

Those default-implementations are only accessible when the object is accessed via that interface; i.e. they aren't accessible as members on the object itself. Furthermore, interfaces (still) only declare (and optionally define) vtable members (i.e. only methods, properties, and events - which are all fundamentally just methods), not fields or any kind of non-static state, whereas IMO mixins should have no limitations and should behave the same as though you copied-and-pasted raw code.

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

#53
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…

Yeah there can be a ton of derivative and convenience methods that would either have to be duplicated in all implementations or even worse duplicated at call sites.

Call them interfaces with default implementations or super classes, they are the same thing and very useful.

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

#54
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 think that's part of the charm of Go, as a language/community. I've worked with countless people who came from Java, who try to create the same abstractions and factories and layers. When I chide them, it's like realizing the shackles are off, and they have fun again with the basics. It leads to much more readable, simple code. This isn't to say Java is bad and Go is good, they're just languages. It's just how they…

> This isn't to say Java is bad and Go is good, they're just languages. It's just how they're typically (ab)used in enterprises.

Yeah; I agree with this. I think this is both the best and worst aspect of Go: Go is a language designed to force everyone's code to look like vaguely the same, from beginners to experts. Its a tool to force even mediocre teams to program in an inoffensive, bland way that will be readable by anyone.

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

#55
post #48
post #14

Earlier quoted context omitted.

Simple inheritance doesn't have the diamond problem, because that requires multiple inheritance, which isn't simple. Smalltalk doesn't have multiple inheritance; I don't think SIMULA did either.

Simula is strictly single inheritance (and no interfaces).

Thank you!

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

#56
I think many developers, especially in the range on 1999-2020, has gone through many pitfalls in programming. More specifically.. OOP.

As someone who was blessed/lucky to learn C and Pascal.. with some VB6.. I understood how to write clean code with simple structs and functions. By the time I was old enough to get a job, I realised most (if not all) job adverts required OOP, Design Patterns, etc. I remember getting my first Java book. About 1,000 pages, half of which was about OOP (not Java directly)

I remember my first job. Keeping my mouth shut and respecting the older, more experienced developers. I would write code the way I believed was correct -- proper OOP. Doing what the books tell me. Doing what is "cool" and "popular" is modern programming. Hiding the data you should not see, and wrapping what you should in Methods... all that.

Nobody came to me and offered guidance but I learned that some of my older codebase with Inheritence, Overrides.. while it was "proper" code, would end up a jumbled mess when it required new features. One class that was correctly setup one day needed to be moved about, affecting the class hierarchy of others. It brings me back to thinking of my earlier programming days with C -- and to have things in simples structs and functions is better.

I do not hate on OOP. Afterall, in my workplace, am using C# or Python - and make use of classes and, at times, some inheritence here and there. The difference is not to go all religious in OOP land. I use things sparingly.

At work, I use what the Companies has already laid out. Typically languages that are OOP, with a GC, etc. I have no problem with that. At home or personal projects, I lead more towards C or Odin these days. I use Scheme from time-to-time. I would jump at the opportunity to using Odin in the workplace but I am surrounded by developers who dont share my mindset, and stick to what they are familiar with.

Overall, his Conclusion matches my own. "Personally, for code reuse and extensibility, I prefer composition and modules."

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

#57
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…

> a tree probably doesn't represent the fundamental truth of things

It does. Trees appear in nature all the time. It's the basis of human society, evolution and many things.

Most of programming moves towards practicality rather then fundamental truth. That's why you get languages like golang which are ugly but practical.

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

#58
post #38
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…

But they're not building trees, that's how inheritance is mostly used today. After reading this, I'm thinking that intrusive lists is the one use of inheritance in C++ that makes any sense.

I'd still generally prefer intrusive lists to be done via composition. I've seen plenty of intrusive lists where each item was a member of multiple lists at the same time - which is quite hard to do if you need to inherit from an intrusive list element superclass.

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

#59
post #51
post #43

Earlier quoted context omitted.

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…

> 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.

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

#60
post #35

Earlier quoted context omitted.

How are interfaces with ability to provide default implementations for members (which both C# and Java allow today) not a substitute for mixins? "Only reference types can implement interfaces" is simply not true in C#. Not only can structs implement them, but they can also be used through the interface without boxing (via generics).

They just cannot access any field in the class itself. Which means... the default implementations fail to actually implement anything but the simplest methods or you need to expose API-private things via getters violating open-closed principle. (If you merge multiple interfaces, the implementations of the methods have to match. You end up with even more special getters for each one sometimes.)

In C# interface members can be implemented explicitly, which means that: 1) they are not visible on the object itself, only on interface-typed references to it, and 2) implementations of methods from multiple interfaces don't need to match since they live in separate namespaces.

It's true that you can't access private members (not just fields) on `this` from the mixin interface. But explicit implementations of members mean that only someone explicitly downcasting the object will get access to those members, so accidental access is not an issue.

Post reply on HN