Live data from Hacker News

Inheritance Often Doesn't Make Sense

sicpers.info

171–180 of 255 posts

Re: Inheritance Often Doesn't Make Sense

#171

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…

I think OO has so many fierce defenders, due to the simplicity of the concept, allowing even the mediocre to paint a system by the photograph of reality as it is imagined to be.

In this Object Orientated Fairy world even the Programmer has a place- he usually becomes the "Controller" Object - passing messages and half finnished objects between components.

Everyone can do this, everyone can relatively fast read into this. And this is why object orientation persists. It has no value beyond that.

Inheritance is one of those concepts, people went overboard with in the 90s, generating matroschka objects- that only the compiler could read and whos methods without a IDE where unguessable.

Since then- we put it into the history box, and replaced it with composition, which is inheritance in all but syntax and creation call hierarchy.

The attack on the holy mountain of OO is thus doomed to be unsuccesfull, because those who are besieged up there can not come down here- because they allready struggle with "normal" code and are happy to code down reality as seen by some "architect".

Efficiency or adequate abstraction, is not actually part of the discussion. Neither is speed. What it provides is accessability- and that it provides rather well. Its a crutch for human minds- and a good one at that.

Re: Inheritance Often Doesn't Make Sense

#172

Earlier quoted context omitted.

Yes! The thing that ends up breaking in the squares and rectangles examples is mutability. Remember that math things are immutable by default. This thing is a square, and by definition also a rectangle, and since its properties and identity are immutable, that will always be true. However, programming takes those immutable concepts and tends to make them mutable. So now we have a rectangle, and we can change its iden…

Perfect! This is the covariant/contravariant/invariant distinction, right? "Read-only data types (sources) can be covariant; write-only data types (sinks) can be contravariant. Mutable data types which act as both sources and sinks should be invariant." from https://en.wikipedia.org/wiki/Covariance_and_contravariance_...

Absolutely, and that's another excellent way to explain the problem and come to the same conclusion. The mathematical relationship between rectangles and squares is covariant, because squares have more specific constraints than rectangles. But when you make rectangles mutable, those mutations are contravariant, because they only guarantee to preserve less specific constraints. So you can't make squares from mutable rectangles!

Re: Inheritance Often Doesn't Make Sense

#173
post #153

Earlier quoted context omitted.

I’m confused about your analogy. Indo-Arabic number representation enables one to mentally carry out computations that would be much more complex in Roman notation. The notation might not be the solution, but the notation certainly enables solutions not really conceivable in other notations.

I believe functions + immutable data enable me to mentally figure out solutions to complex problems that would be much more complex if solved with objects and inheritence and mutable state.

The analogy breaks down (at least for me) as there are some trade-offs being glossed over that don’t really exist with the different systems of numerals. What’s being lost for the conceptual simplicity you’ve gained?

Re: Inheritance Often Doesn't Make Sense

#174

Earlier quoted context omitted.

Yes! The thing that ends up breaking in the squares and rectangles examples is mutability. Remember that math things are immutable by default. This thing is a square, and by definition also a rectangle, and since its properties and identity are immutable, that will always be true. However, programming takes those immutable concepts and tends to make them mutable. So now we have a rectangle, and we can change its iden…

Excellent point! I think it's fair to say that substitutability can only be satisfied (in general) for a fixed set of operations. This is why I believe Haskell's (and by extension Rust's) approach to bounded ad-hoc polymorphism is the best that I've seen in a production language. Going beyond Haskell, Rust also allows you to choose static dispatch, making bounded polymorphism zero cost. Dynamic dispatch is still avai…

I'm a huge fan of the Rust and Haskell systems for exactly this reason. I sometimes play with the idea of a language that has that kind of type system, but with a more forgiving environment Rust or Haskell. Something like C#, but swap out the type system to feel more like Rust.

Re: Inheritance Often Doesn't Make Sense

#175
post #21

Earlier quoted context omitted.

I always find that the common example of Rectangles and Squares leads me to a different conclusion. It assume that the best way to go about is to only have a single sideLength method, but from a data structure perspective it seems more obvious that the Squares class substitute instead the validation method by adding constraints that a valid square only exist when both sides are equal. Rectangle class must already hav…

Agreed. In fact I would expect the Square subclass to implement width= and height= so that they each actually set both internal values.

As niklasjansson points out, this solution breaks Liskov substitution. Squares programmed in such a way are no longer substitutable for rectangles. Breaking Liskov substitution is a great way to hide bugs and make your codebase extremely hard to reason about, due to the fact that every subtype can have drastically different behavior than what's defined by the parent type.

Re: Inheritance Often Doesn't Make Sense

#176
post #9

A couple of other comments have argued that "ontological inheritance" and "abstract data type inheritance" are actually the same thing: > This is because Squares are Liskov substitutable for Rectangles... which is because Squares are, platonically, a kind of Rectangle. > If the type system is sound and expressive enough, ontological inheritance ( this thing is a specific variety of that thing) and abstract data type…

This is far from a silly example; it gets right to the core of the matter. As belorn mentioned, a square is a constrained rectangle, and inheritance by extension cannot represent this relationship.

Inheritance can represent this relationship, as long as all the defined operations in the rectangle are covariant. Because squares are covariant (more constrained) than rectangles. This generally means that the rectangle type must be immutable.

Re: Inheritance Often Doesn't Make Sense

#177
post #6

This gets off to a bad start: > There are three different types of inheritance going on. > 1. Ontological inheritance is about specialisation: this thing is a specific variety of that thing (a [soccer ball] is a sphere and it has this radius) > 2. Abstract data type inheritance is about substitution: this thing behaves in all the ways that thing does and has this behaviour (this is the Liskov substitution principle)…

> If you have code that is set up to handle Rectangles, and you give that code a Square, then the code will handle the Square correctly. Hmm...try setting different widths and heights on your square.

On a square either setting the height immediately also sets the width to the same value OR all the types involved are immutable OR you have actively chosen to make a subtype that doesn't properly allow substitution, which is bad.

I think this really shows the point the author struggles with: It's not that OO is flawed because inheritance like this is somehow not possible. It's a paradigm that is deceptively easy but is really very hard to get right. You need to keep these things in mind all the time. The simplest thing to start with is just make everything immutable if you can afford it.

Re: Inheritance Often Doesn't Make Sense

#178

If you ever open the hood of a modern car and look around a bit you'll discover that at the front there's a half dozen pullies connected to one or more belts. Each of these pullies is connected to some diffeerent system each able to turn rotational acceleration into a useful service. The alternator converts that rotational energy into electricity. The AC unit uses it to operate a heat pump. The coolant and oil pumps…

You’ve described interfaces, not so much inheritance.

In the language of the article, this is subtyping without subclassing. Sure Java/C# implement this as interfaces, but in C++ this would be a case of multiple inheritance. This is a good example of the article's main point that people mean a lot of different things by inheritance and get different value from the different applications of the concept.

Re: Inheritance Often Doesn't Make Sense

#179

If you ever open the hood of a modern car and look around a bit you'll discover that at the front there's a half dozen pullies connected to one or more belts. Each of these pullies is connected to some diffeerent system each able to turn rotational acceleration into a useful service. The alternator converts that rotational energy into electricity. The AC unit uses it to operate a heat pump. The coolant and oil pumps…

Which is also why these modern cars have turned a minor belt failure into an expensive catastrophic failure, often destroying much of the engine.

I'd hardly call it a design to aspire to.

I'd probably compare it more closely with a system where everything receives a mutable God object.

Re: Inheritance Often Doesn't Make Sense

#180

I took over the maintenance and enhancement of a customer's eCommerce site. It's written in Python, using an ancient framework - Pylons. The person who originally designed and wrote it, coded large super classes and then subclassed off those. And then somtimes subclassed off those subclasses. So now I'm lost in a maze of twisty classes/subclasses, which makes maintaining and enhancing this eCommerce site much, much m…

> In a few particular cases, I've found myself having > to move functions out from one subclass and into the > superclass, in order for related subclasses which > needed access to it, for me to be able to add more > functionality to the site. That seems like a refactoring basic. Far from being miserable, it is likely the easiest way to have met the requirement to add functionality.

The misery comes from zero documentation, no code commenting, very short variable names, and having to trace backwards from the subclass to the superclass to the ancient frameworks and libraries being used.

Especially tracing backwards from a subclass and it's undocumented! :)

Post reply on HN