Live data from Hacker News

When did people favor composition over inheritance?

sicpers.info

101–110 of 218 posts

Re: When did people favor composition over inheritance?

#102
post #43

An important point not mentioned by the article is that of "co-recursion" with inheritance (of implementation). That is: an instance of a subclass calls a method defined on a parent class, which in turn may call a method that's been overridden by the subclass (or even another sub-subclass in the hierarchy) and that one in turn may call another parent method, and so on. It can easily become a pinball of calls around t…

I 100% agree. And even though I use C# which is kind of OOP heavy, I use inheritance and encapsulation as least as possible. I try to use o more functional worklflow, with data separated from functions/methods. I keep data in immutable Records and use methods/functions to transform it, trying to isolate side effects and minimize keeping state.

It's a much pleasurable and easier way to work, for me at least.

Trying to follow the flow through gazillion of objects with state changing everywhere is a nightmare and I rather not return to that.

Re: When did people favor composition over inheritance?

#103
post #6

Arguably the answer is “When Barbara Liskov invented CLU”. It literally didn’t support inheritance, just implementation of interface and here we have her explaining 15 odd years later why she was right the first time. I used to do a talk about Liskov that included the joke “CLU didn’t support object inheritance. The reason for this is that Barbara Liskov was smarter than Bjarne Stroustrup.”

There's nothing wrong with implementation inheritance, though. Generic typestate is implementation inheritance in a type-theoretic trench coat. We were just very wrong to think that implementation inheritance has anything to do with modularity or "programming in the large": it turns out that these are entirely orthogonal concerns, and implementation inheritance is best used "in the small"!

Re: When did people favor composition over inheritance?

#104

Earlier quoted context omitted.

There is a reason C++ devs and only C++ devs have nightmares of diamond inheritance. Oh the damage that language has done to a generation, but at least it is largely passed us now.

Diamond inheritance is its own special kind of hell, but “protected virtual” members of java and c# are the “evil at scale” that’s still with us today. An easy pattern that leads to combinatorial explosion beyond the atoms in the universe. Trivially. People need to look at a playing deck. 52 cards, and you get 8×10^67 possible orders of the deck. Don’t replicate this in code.

Why do protected virtual methods lead to an explosion?

Re: When did people favor composition over inheritance?

#105
Inheritance is not a fundamental concept of anything. Inheritance is just composition with syntactic sugar. The semantic meaning was always composition.

Oop is a mistake. Rust and pythons explicit self passing and turning of the dot operator into simple syntactic sugar is the correct approach. We should just stop teaching everything related to this in universities and go back to fundamentals.

Re: When did people favor composition over inheritance?

#106
post #79

Earlier quoted context omitted.

Aside from game dev, Rust is being used in quite a lot of green field work where C++ would have otherwise been used. Game dev world still has tons of C++, but also plenty of C#, I guess. Agreed that it’s not really behind us though. Even if Rust gets used for 100% of C++’s typical domains going forward (and it’s a bit more complicated than that), there’s tens? hundreds? of millions (or maybe billions?) of lines of wo…

The problem in Rust is that if B is inside of A, struct A { name: String, owned: B } struct B { name: String, } you can't have a writeable reference to both A and B at the same time. This is alien to the way C/C++ programmers think. Yes, there are ways around it, but you spend a lot of time in Rust getting the ownership plumbing right to make this work.

It's kind of crazy that OOO is sold to people as 'thinking about the world as objects' and then people expect to have an object, randomly take out a part, do whatever they want with it and just stick it back in and voila

This is honestly such an insane take when you think about what the physical analogue would be (which again, is how OOP is sold).

The proper thing here is that, if A is the thing, then you really only have an A and your reference into B is just that, And should be represented as such, with appropriate syntactic sugar. In Haskell, you would keep around A and use a lens into B and both get passed around separately. The semantic meaning is different.

Re: When did people favor composition over inheritance?

#107
post #14

Earlier quoted context omitted.

There is a reason C++ devs and only C++ devs have nightmares of diamond inheritance. Oh the damage that language has done to a generation, but at least it is largely passed us now.

I'm spoiled by Python's incredibly sane inheritance and I always have to keep in mind that inheritance is a very different beast in other languages.

Python is slightly better because it can mostly be manipulated beyond recognition due to strong metaprogramming but pythons operator madness is dangerous. Random code can run at any minute. It's useful for something's and a good scripting language, and a very well designed one, no question there. Still it would be better if it supported proper type classes. It could retain the dynamic typing, just be more sensible.

Re: When did people favor composition over inheritance?

#108

Inheritance is not a fundamental concept of anything. Inheritance is just composition with syntactic sugar. The semantic meaning was always composition. Oop is a mistake. Rust and pythons explicit self passing and turning of the dot operator into simple syntactic sugar is the correct approach. We should just stop teaching everything related to this in universities and go back to fundamentals.

Implementation inheritance is not just composition. Composition on its own does not allow for open recursion (implementing methods that were called on a base class in a derived class, via an in-built dispatch step), whereas inheritance does.

Re: When did people favor composition over inheritance?

#109
I once worked with a library that had such a deep inheritance tree, only for ontological purposes, that I was always confused as to where anything was actually implemented. I decided to squash the layers and found almost every method was overrode two or three times.

That was the project that I turned against inheritance, it was 2009, project was written in Java 1.4

Re: When did people favor composition over inheritance?

#110
post #38

Earlier quoted context omitted.

I find the Monoid/Semigroup typeclass pretty concisely captures what is generally meant by "composition" in the minimal sense. > As a rule, I've always viewed "composition" as "gluing together things that don't know necessarily know about each other" The extension to this definition given the context of Monoids would be "combining two things of the same type such that they produce a new thing of the same type". The m…

I actually knew most of that (I've done a lot of Haskell). I don't really disagree with what you said, but I feel like like you eliminate a lot of stuff that people would consider "composition" but aren't as easily classified in happy categories. For example, a channel-based system like what Go or Clojure has; to me that is pretty clearly "composition", but I'm not 100% sure how you'd fully express something like tha…

The thing about inheritance is it limits you to one relation. Composition is not a single relation but an entire class of relations. The user above mentioned monoids. That is one very common composition that is omnipresent in computation and yet completely glossed over in most programming languages.

But there are other compositions. In particular, for something like process connection, the language of arrows or Cartesian categories is appropriate to model the choices. The actual implementation is another story

In general when you want to model something you first need to decide on the objects and then you need to decide on the relations between those objects. Inheritance is one and there's no need for it to be treated specially. You will find though that very objects actually fit any model of inheritance while many have obvious algebras that are more natural to use

Post reply on HN