Live data from Hacker News

Inheritance was invented as a performance hack (2021)

catern.com

161–170 of 252 posts

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

#161

I always thought this was common knowledge. I guess it isn’t. The only reason inheritance continues to be around is social convention. It’s how programmers are taught to program in school and there is an entire generation of people who cannot imagine programming without it. Aside from common social practice inheritance is now largely a net negative that has long outlived its usefulness. Yes, I understand people will…

It's not just school. There are a lot pieces of literature, tutorials/guides, discussions, papers I came across over the years that tell you something very useful _plus_ wrap everything either into OO (or sometimes FP) noise and treat this part as just as important. Often there are vague rationales sprinkled in without much backing.

So you get interfaces that are much bigger than they need to be, visitor pattern this, manager that. As someone who isn't used to OO it is sometimes difficult or cumbersome to compile these kinds of examples and explanations into its essence.

I also noticed that AI assistants often want to blow up every interface with a whole bunch of useless stuff like getter/setter style functions and the like. That's obviously not the fault of these assistants, but I think it's something to consider.

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

#162

Earlier quoted context omitted.

From a very modified version of something I was working on recently, but with the stuff I couldn't do actually done here (and non-functionality code because of that, but is shows the idea) public interface MetadataSource { Metadata metadata = null; default Metadata getMetadata() { if (metadata == null) { metadata = fetchMetadata(); } return metadata; } // This can be relatively costly Metadata fetchMetadata(); } publ…

Here's my take on implementing this in rust. I made a trait for fetching metadata, that can be implemented by Image, Video, Document, etc: trait MetadataSource { fn fetch_metadata(&self) -> Metadata; } impl MetadataSource for Image { ... } impl MetadataSource for Video { ... } impl MetadataSource for Document { ... } And a separate object which stores an image / video / document alongside its cached metadata: struct…

Isn't this essentially the generic typestate pattern in Rust? In my view there is a pretty obvious connection between that particular pattern and how other languages implement OO inheritance, though in all fairness I don't think that connection is generally acknowledged.

(For one thing, it's quite obvious to see that the pattern itself is rather anti-modular, and the ways generic typestate is used are also quite divergent from the usual style of inheritance-heavy OO design.)

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

#163
Fascinating.

Interestingly enough, my first non-class-related experience with "intrusive lists" was in C, and we implemented it via macros; you'd add a LINKED_LIST macro in the body of a struct definition, and it would unspool into the pointer declarations. Then the list-manipulation functions were also macros so they would unspool at compile time into C code that was type-aware enough to know where the pointers lived in that individual struct.

Of course, this meant incurring the cost of a new definition of function families for each intrusive-list structure, but this was in the context of bashing together a demo kernel for a class, so we assumed modern PCs that have more memory than sense. The bigger problem was that C macros are little bastards to debug and maintain (especially a macro'd function... so much escaping).

C++, of course, ameliorates almost all those problems. And replaces them with other problems. ;)

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

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

Objects are a pretty good abstraction for when you have data that represents, well, objects. In 3D graphics it's a very useful abstraction. Significantly less good when you're trying to model process, pipeline, or flow IMHO (I know there are some people who swear by them for anything they would bash together with UML first, and I just... Don't see it. I've used more than enough object-oriented flowchart-description languages to fundamentally disagree; charts are two-dimensional, text-represented code is one-dimensional, making the code "objects" doesn't fix that problem).

(Probably also worth noting that high performance 3D graphics torture the object abstraction past recognizability, because maintaining those runtime abstractions costs resources that could be better spent slamming pixels into a screen).

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

#165

Earlier quoted context omitted.

I’m surprised this is considered a controversial take. You can write spaghetti in any language or paradigm. People will go overboard on DRY while ignoring that inheritance is more or less just a mechanism for achieving DRY for methods and fields. FP wizards can easily turn your codebase into a complex organism that is just as “impenetrable” as OOP. But as you say, fads are fads are fads, and OOP was the previous fad…

I have a slightly different take: I think every new technology or idea is created because it solves some problems, but in the long run, we'll discover that it creates other problems. For example, transpiling javascript, C++ OO, actors, coroutines, docker, microkernels, and so on. When a new idea appears, we're much more aware of the benefits it brings. But we don't know the flaws yet. So we naively hope there are no…

Although Java/C# make you put functions in a class, you aren't compelled to think of a class as a "noun". Just call it "Utils" or something like that. A class is just a thing that you can put functions and / or data in. Use that however you want.

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

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

> The reason is that inheritance is almost always a bad idea in practice.

It's just slightly too strong of a statement.

I'm working in a very large Spring codebase right now, with a lot of horrible inheritance abuse (seriously, every component extended common hierarchy of classes that pulled in a ton of behavior). I suspect part of the reason is the Spring context got out of control, and the easiest way to reliably "inject" behavior is by subclassing. Terrible.

On the other hand, inheritance is sometimes the most elegant solution to a problem. I've done this at multiple companies:

    Payment
      + PayPalPayment
      + StripePayment
Sometimes you have data (not just behavior!) that genuinely follows an IS-A relationship, and you want more than just interface polymorphism. Yes you can model this with composition, but the end result ends up being more complex and uglier.

It doesn't have to be all one or the other. But I agree, it should be mostly composition.

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

#167
Before my time but I reject the idea that inheritance was "invented" in the context of a particular high level programming language. It was used widely in assembly/machine code programming. It's essentially a manifestation of two things: categorization of things (at least thousands of years old); and pointers to data structures (at least as old as the Manchester Mk1).

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

#168
post #83

Earlier quoted context omitted.

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/

Objective-C and Smalltalk were always niche languages, at least by comparison to Java and C#, and I think Smalltalk fans underestimate the value of many things. C++ does not (or at least did not at the time) have a concept of interfaces. There was a pattern in some development communities for defining interfaces by writing classes that followed particular rules, but no first-class support for them in the language.

Java having an explicit ”interface” construct is one thing I didn’t like about it, because it muddles the notion of a class implicitly having an interface (a notion that clearly exists in C and C++, by way of header files if nothing else) with that construct, while on the other hand there is no a-priori reason to have a distinction between Java’s interfaces and pure abstract classes. Both specify an interface to be implemented. And Java 8+ muddles its concept further by allowing default methods and static members.

The important thing is to distinguish between interface and implementation, and that is relevant to any class, whether it implements a separately defined interface or not.

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

#169

Earlier quoted context omitted.

The main reason (other than self-documentation) that some other languages separate interfaces form normal classes is that they only support multiple inheritance for interfaces. C++ doesn't have this restriction, so interfaces would add very little.

Because multiple inheritance causes the diamond problem. C# forces you to solve it by declaring one method as the "canonical" and the others as "explicit interface implementations" (only accessible if the variable/receiver is typed as that interface).

The diamond problem strictly speaking only has to be one when the common base class has constructor arguments. While a Java-style interface construct makes it easy to prevent, it also imposes much stronger restrictions than the above. It would have been possible to only impose the above restriction. Yes, there are failure cases with separate compilation, but the way Java dynamically loads classes, that would be similar to how when the JVM loads a class file that is supposed to be an interface, it discovers that instead it has been changed to a class.

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

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

> And inheritance naturally suggests grouping interfaces into a tree in the way that seems of little value because in practice a tree probably doesn't represent the fundamental truth of things.

The fundamental truth of things? What are you even talking about? What fundamental truth of things? And what does that have anything to do with building software?

Post reply on HN