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.
Inheritance was invented as a performance hack
201–210 of 268 posts
Re: Inheritance was invented as a performance hack
#202Earlier 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.
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
#203Earlier 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.
Re: Inheritance was invented as a performance hack
#204Earlier 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 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
#205Earlier 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.
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
#206This comment may get too meta, but technically everything we do, ever, is a performance hack.
Re: Inheritance was invented as a performance hack
#207Earlier 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.
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
#208Inheritance 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…
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:
Re: Inheritance was invented as a performance hack
#209In 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).
"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.