Live data from Hacker News

Inheritance Often Doesn't Make Sense

sicpers.info

101–110 of 255 posts

Re: Inheritance Often Doesn't Make Sense

#101
The reason implementation inheritance with substitution (aka "virtual methods") is bad is that it results in classes having two APIs: the normal public API and one for inheritors, the latter of which is usually undocumented, and even worse the APIs are conflated.

To see the issue, imagine you have a class representing a thermometer, with two virtual methods: get_c() and get_f() returning the temperature in Celsius and Fahrenheit degrees respectively.

Now it turns out that a specific model of that thermometer was miscalibrated and always returns 10 C more, so you decide to make subclass that corrects the behavior.

Unfortunately, that's impossible (without composition or mutable state).

A first attempt could be to override get_c() to call the parent and subtract 10. However, get_f() will still be wrong unless it happened to be implemented by calling get_c() and converting.

A second attempt could be to override both and apply the correction to both. Except now if get_f() is implemented by calling get_c() and converting, the correction will happen twice!

The issue here is that how the class uses its internal API is undocumented, and also that the internal and public APIs are conflated, making it impossible to change only one.

This can be solved by never having a class call overridden functions on itself, but that just results in a system that is equivalent to composition with delegation.

If such overriding is really required, it can be accomplished by adding a "callback interface" parameter to the constructor and documenting how it is called and how it's expected to behave.

Re: Inheritance Often Doesn't Make Sense

#102
post #20

> you cannot use a square everywhere you can use a rectangle (for example, you can’t give it a different width and height) Can someone come up with a better example here? Intuitively, I would say, "Yes, if you ask me for any rectangle, and you reject a square, you are wrong." If you say you can use any rectangle to do your thing, you should absolutely be able to also use a square. Why am I not convinced with the give…

Agreed this example is deeply flawed! As you point out, there is a difference between what you can do with an object versus how you can create one. And "you could use SOME rectangles anywhere you could use a square" is not even a claim about type relationships... It would have to be "you can use ALL rectangles everywhere you could use ANY square" to reverse the type relationship.

In reality, abstract and usage typing are highly aligned. The incompatible sibling is code inheritance. Knuth put I more simply: "Don't inherit to reuse code, inherit to be reused."

Re: Inheritance Often Doesn't Make Sense

#103
post #96

The programmer's perspective: The phrase 'object-oriented' means a lot of things. Half are obvious, and the other half are mistakes. - Paul Graham. Implementation inheritance causes the same intertwining and brittleness that have been observed when goto statements are overused. As a result, OO systems often suffer from complexity and lack of reuse. - John Ousterhout Scripting, IEEE Computer, March 1998. The problem w…

> The conceptual purist perspective: > > The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages. - Alan Kay > Given that Alan Kay is the one who came up with the term "object oriented", it might be wise to give him authority about the definition.

"Misunderstood" is a nice cop-out.

Sure, misunderstanding happen, true. But at a certain point it becomes just another excuse.

And that's not to get into the "SOLID" definitions which are more a feel-good word for handwave and murky definitions typical of the "True Scotsman" fallacy

Re: Inheritance Often Doesn't Make Sense

#104

The programmer's perspective: The phrase 'object-oriented' means a lot of things. Half are obvious, and the other half are mistakes. - Paul Graham. Implementation inheritance causes the same intertwining and brittleness that have been observed when goto statements are overused. As a result, OO systems often suffer from complexity and lack of reuse. - John Ousterhout Scripting, IEEE Computer, March 1998. The problem w…

Another quote: ------------------ The No True Scotsman fallacy leads to arguments like this: Person A: “No Scotsman ever steals.” Person B: “I know of a Scotsman who stole.” Person A: “No True Scotsman would ever steal.” Person A is thus protected from the harmful effects of new information. New information is dangerous, as it might cause someone to change their mind. New information can be rendered safe simply by de…

Valid points, but I suppose that's an issue with anything, have heard similar from functional programming advocates, etc

Re: Inheritance Often Doesn't Make Sense

#105
post #96

The programmer's perspective: The phrase 'object-oriented' means a lot of things. Half are obvious, and the other half are mistakes. - Paul Graham. Implementation inheritance causes the same intertwining and brittleness that have been observed when goto statements are overused. As a result, OO systems often suffer from complexity and lack of reuse. - John Ousterhout Scripting, IEEE Computer, March 1998. The problem w…

> The conceptual purist perspective: > > The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages. - Alan Kay > Given that Alan Kay is the one who came up with the term "object oriented", it might be wise to give him authority about the definition.

Definitions arise in real world use, independently of who might have first invented a concept or coined the term.

In the end, only how a term is used by the majority of people matters -- because only that retains the basic requirement of language: to say something and have it be understood.

Re: Inheritance Often Doesn't Make Sense

#106
post #78

Earlier quoted context omitted.

> The real world is mutable Only if you ignore time. It's not possible to change the state of the world at some previous instant (as far as our understanding of physics is concerned). The mutable world model is an artificial construction that aligns with our human perception.

"Everything changes and nothing remains still; you cannot step twice into the same stream"

Ironically, the latter part of what you quoted shows the solution to representing change in an immutable system: create a different stream object instead of mutating the same stream object.

(Streams in this case not being streams in an I/O sense, just an example of a class).

Re: Inheritance Often Doesn't Make Sense

#107
post #87
post #42

Earlier quoted context omitted.

The problem balancing implementation vs ontological inheritance while providing strong type safety is that your language needs to either support defining contravariant types (and you still likely end in a mess, see Scala's eternal discussion about "total" type safety), or you disallow ontological inheritance completely (like Golang, and therefore cannot support many modern programming features, for the better or wors…

> or you disallow ontological inheritance completely (like Golang, and therefore cannot support many modern programming features Sincerely, what features does this preclude. I pretty much ignore ontological inheritance in any programming language because it never seems useful. Am I missing something?

Same here. The whole "is a square a type of rectangle, or is a rectangle a type of square" question seems like an unnecessary debate.

Re: Inheritance Often Doesn't Make Sense

#108
post #20

> you cannot use a square everywhere you can use a rectangle (for example, you can’t give it a different width and height) Can someone come up with a better example here? Intuitively, I would say, "Yes, if you ask me for any rectangle, and you reject a square, you are wrong." If you say you can use any rectangle to do your thing, you should absolutely be able to also use a square. Why am I not convinced with the give…

>Why am I not convinced with the given example? Because fundamentally, I don't think "set the width and height" counts as something you can do with a rectangle. A rectangle has a width and height, and you can't just will it to have a different width and height and expect it to obey you through some force of nature.

Sure you can. You can both dictate it its width and height at construction time (e.g. the table maker who makes an X by Y board), or at anytime later (e.g. the same table maker who cuts the a 3X by X board into a 2X by X board).

Even more so with other materials, where we can just bend them and squash them into the dimensions we want again and again (e.g. pastry dough).

Re: Inheritance Often Doesn't Make Sense

#109
post #44

I used to feel like this before writing big and complex programs. But in term of practicality, it's a whole lot easier to just write the expansion of "rectangle" to "square" than re-writing "square" from scratch, essentially copying the majority of "rectangle" properties and functionality.

Factor out the commonality into a service class (as stated in another comment), where your common logic can be shared.

Re: Inheritance Often Doesn't Make Sense

#110
post #43

Earlier quoted context omitted.

> and you can't just will it to have a different width and height and expect it to obey you through some force of nature I think you have let functional programming and immutable data-structures bias your world view. The real world is mutable and the wonder of the digital mutable world is that it is pretty much just will-alone that can set attributes as you describe. It is immutability that is a trendy but artificial…

Is the real world "subtypeable", in your opinion?

Sure. I want a vehicle to go to work. A car, preferably, but a motorcycle or bus will do too in a pinch.
Post reply on HN