Live data from Hacker News

Inheritance was invented as a performance hack

catern.com

201–210 of 268 posts

Re: Inheritance was invented as a performance hack

#201

Earlier quoted context omitted.

Inheritance is a natural phenomenon. If all my money were stolen when I die (let's say, 100% inheritance tax), I wouldn't have much incentive to grow my business more once my business makes more money than I can possibly spend in a lifetime. Sure, some people may still do it because they love working or because they love providing for their society. The main reason I want to accumulate money, is so I can offer them a…

It's also an extension of basic property rights. An owner of property may will it to whomever he pleases on the event of his passing. It's no different from simply gifting property while alive.

You imply an interesting question: Do the dead have all the same rights as the living? I'm leaning towards no. So I think it's a little different from gifting something while alive, for starters, a gift while alive is typically at personal cost unless you no longer have any use for the item. Once dead you have no use for any items, as you're definitionally out of the "able to use things" population.

Re: Inheritance was invented as a performance hack

#202

Earlier quoted context omitted.

> it can also produce code that is easily and clearly extendable It can also produce code that is not easily and clearly extendable, if the behavior you're trying to extend is buried a layer or two further down the inheritance hierarchy. Unfortunately, due to the First Law of Kipple, the rate at which you run into this problem is proportional to the age of the code base. And so we grow frustrated with implementation…

I think the practice of not using a tool because people could potentially misuse it is misguided in this day and age. Linting and static code analysis are quite capable of enforcing good usage patterns.

The problem is "developer" spans a gigantic range of capabilities. Someone who wrote Hello World in Chrome's Console is a developer, and someone writing kernel code professionally is also a developer.

It's hard to define a "good practice" for this wildly heterogenous group. What's good for a beginner (training wheels on a child's bike), is completely counter-productive to a pro (motorcycle sports driver).

Re: Inheritance was invented as a performance hack

#203
post #199

Earlier quoted context omitted.

I frequently hear people malign inheritance, and while it can obfuscate code in some circumstances, it can also produce code that is easily and clearly extendable. For example, a class with a static method that uses class properties to control behavior is cleaner than a function factory that takes a config object. Interface inheritance is also quite useful.

I think thanks to Java opting to use "implements" for interfaces, people no longer associate "inheritance" as the thing we do when we write a fully abstract class (i.e. interface) and then "inherit" this abstraction to implement it. Interfaces are, of course, crucial. Not sure I understood your example about the static class vs. function factory tbh though.

But I don't think a "fully abstract class" is the same thing as an "interface", at least in Java? As far as I know, you can implement multiple "interfaces" but you can still only "extend" one abstract class, even if it is "fully abstract" in that it has no concrete member variables and all methods are abstract.

Re: Inheritance was invented as a performance hack

#204
post #139

Earlier quoted context omitted.

I've heard "monomorphisation" to refer to something a compiler does, but not something a programmer does. I think this is just "repetition"! The need for something to solve the problems inheritance solves has been known in Rust for a long time. Mostly it's been motivated by the need to implement the HTML DOM, which is fundamentally an inheritance hierarchy, in Servo. There's a longstanding RFC about it: https://githu…

I do hope they adopt one solution or the other. Rust for me seems incomplete because of this. Another issue I have with it is perfectly described in this article: https://theta.eu.org/2021/03/08/async-rust-2.html

For reference I have over a decade of JavaScript experience in industry and my async Rust rewrite of a large JS project was *more* concise then the heavily refactored and polished NodeJS version (a language I consider more concise then most). If you are having to copy and paste excessively in Rust that is an issue but it is not necessarily intrinsic to the language.

For what it's worth traits largely prevented copy and paste and where traits fail there are macros. The classic inheritance example you link to is a tiny percentage of my code and an orders of magnitude smaller time sink when compared to the code maintenance problems I faced in other languages.

Re: Inheritance was invented as a performance hack

#205

Earlier quoted context omitted.

> it can also produce code that is easily and clearly extendable It can also produce code that is not easily and clearly extendable, if the behavior you're trying to extend is buried a layer or two further down the inheritance hierarchy. Unfortunately, due to the First Law of Kipple, the rate at which you run into this problem is proportional to the age of the code base. And so we grow frustrated with implementation…

I think the practice of not using a tool because people could potentially misuse it is misguided in this day and age. Linting and static code analysis are quite capable of enforcing good usage patterns.

My concern is not exactly that it could potentially be misused. It's more that it seems to set up forces that subtly push projects toward becoming resistant to change over time. And, while it's possible for individual programmers to exercise discipline in order to push back against these sorts of forces, at a larger scale the guiding principle seems to be, "water flows downhill." So we should seek to find ways of building things that generally set up forces guiding us toward good design in the long run, without having to drill people on large laundry lists of best practices. That approach only works for as long as the code is owned by a sort of benevolent dictator who is able to, by hook or by crook, keep all their teammates on (their version of) the righteous path. And that approach itself is unstable; it has a tendency to degrade rapidly whenever the leader decides to spend a week at the beach. If they should ever leave the company, it's likely to be lost forever.

I can't say that I know a software development idiom that reliably creates a more stable equilibrium point. But I don't think we'll ever find one unless we're willing to examine the failure modes of existing paradigms.

Re: Inheritance was invented as a performance hack

#207

Earlier quoted context omitted.

It's also an extension of basic property rights. An owner of property may will it to whomever he pleases on the event of his passing. It's no different from simply gifting property while alive.

You imply an interesting question: Do the dead have all the same rights as the living? I'm leaning towards no. So I think it's a little different from gifting something while alive, for starters, a gift while alive is typically at personal cost unless you no longer have any use for the item. Once dead you have no use for any items, as you're definitionally out of the "able to use things" population.

Personally, most gifts I've given or received have been items which I didn't need and not at any great cost. I still gave them to a person of my choosing. So when dead and in need of nothing, one's wishes to give to a particular person, charity, or even hypothetically anyone should be respected.

If John owns an item, he can say what happens it. So if he says to an notarised person 'when I die X becomes property of my son James' then that's simply respecting his wishes over his property.

Is it much different if John choose to give something away moments from death, or if he asks someone else to arrange the giving on his behalf after death?

We respect the wishes of the dead because it's part of the continuance of life and civilisation (which is itself fundamentally the store and passing down of value, I.e. inheritance). The same reason we'd honour someone who died for freedom, or honour the funeral wishes of a family member. Their wishes are worth much to everyone who knew them. The same should apply to personal property.

I think I'm stabbing in the right direction. A better answer might come from a better read or more philosophical mind than mine.

Re: Inheritance was invented as a performance hack

#208
post #171

Inheritance is static composition. Everything we do statically is for two reasons: 1. Static invariants (not subject to runtime-defined conditions). 2. Performance (AOT compilers know more about the system and can elide more code and devirtualize more calls, etc.). I think the characterization of performance features as a "hack" is misleading. The article builds a bit of strawman, being dismissive of a performance fe…

> Honestly I've not seen such a strong characterization of inheritance as being purely semantic.

As articulated elsewhere in the discussion, classical inheritance has a great affinity for the "specialization" design pattern, which is everywhere. Classical inheritance is not just a performance hack, it is semantically compelling, as illustrated by the enduring popularity of "Cat Extends Animal"!

Furthermore, single inheritance has a really elegant canonical implementation: "extending" structs and vtables in subclasses by appending their member variables and new virtual method pointers.

Using composition may inoculate against certain brittleness problems in code sharing, but if "has-a" is cumbersome to code up, no amount of scolding is going to change mass behavior.

Emphasizing interface inheritance as an alternative to classical inheritance seems to be more effective at breaking people away from the problems of implementation inheritance, even though interface inheritance is still "is-a" and not "has-a". And "fat pointers" with two words, one for the dispatch table and one for the object, are an elegant canonical implementation for interface inheritance.

> Sure, there's the "Cat extends Animal" shtick that refuses to die. But everyone refers to this kind of talk of inheritance ironically these days.

This sort of "everyone knows" dissing of inheritance is why I tend to dislike HN discussions of it.

For what it's worth, the rust-by-example for traits uses the Animal "schtick" unironically:

https://doc.rust-lang.org/rust-by-example/trait.html

Re: Inheritance was invented as a performance hack

#209

In my experience, 90% of the time people use inheritance but they really only cared about composition, and their language simply does not have any convenient facility to compose types and re-export their methods. With a good type system that includes traits, you almost never need virtual dispatching, as any Rust developer may tell.

Very true. I'm checks cloc 14,000 lines into a personal project and I have yet to feel any need to use `dyn` (virtual dispatching for non-Rust folks).

"I've designed this project in Go following Go naturally imposed design patterns and found that I did not need inheritance.", said the Go programmer.

"Well, mmm, duh?", thought programmers of other languages.

"I've designed this project in Rust, following Rust-imposed design principles, and found monomorphism sufficient", said the Rust programmer.

"Well, mmm, duh?", thought programmers of other languages.

"I've designed this project in Python, using Python-style design and I've found that I did not need strictly typed functions", said the Python programmer.

"Well, mmm, duh?", thought programmers of other languages.

"I've designed this project in language X, which impose Y and as such I've found that you actually don't need Z", said the X programmer.

"Well, we got the picture already", said the HN reader.

Post reply on HN