Hacker News new | past | comments | ask | show | jobs | submit login

> In all my experience with OOP, it's always been inheritance that is the root of all evil.

I have this "theory" in the back of my head that trees are usually the wrong things to model thing in life but it's what come to us naturally. For example, a blog with categories and sub-catogories for articles (a tree, inheritence) can often describe the content better by using tags (a graph, composition). I think that's because trees are easy to deal with and understand, but graphs are more "open" with what you can do.




Data modelling in OOP is an exercise in coming up with Platonic ideals, resulting in a hierarchical (tree-like) ontology as you try to choose of the atributes as the categorisation dimension, and leaving everything else as properties.

    class Animal
    class Mammal inherits Animal
    class Feline inherits Mammal
    class Cat inherits Feline
    ...
This is different than just asserting facts with data, which can lie in multiple dimensions.

    Is Feline
    Is Mammal
    Is Fluffy
    Is White
    Does Meow
The later is a much more flexible data model as it more closely mimics observed (subjective) reality, and is less disturbed when a new (counter-)example is introduced, but is also harder to reason about than idealised categories.


To your point, there are programs that deal in ontologies. These are the only times that it makes sense to care about the relationship between things. For example, an ontology might have a concept of a city and it might know that Munich is a city. But this is all data, it isn't about "types". It never makes sense to write `class Munich extends City {}` for the purpose of your program. Rather, you might have:

    struct Entity {
        name: string,
        parent: Option<Entity>,
    }

    let city = Entity { name: "city", parent: None };
    let munich = Entity { name: "Munich", parent: Some(city) };
That said, if you really wanted to make life hard for yourself, you could use types as data provided your language has a runtime type system and reflection (you could dynamically generate `class City` and `class Munich extends City` when deserializing `[{name: "city", parent: null}, {name: "Munich", parent: "city"}]` or something). But this is the kind of Rube-Goldberg territory that "Kingdom of Nouns" thinking leads us toward.


> Data modelling in OOP is an exercise in coming up with Platonic ideals, resulting in a hierarchical (tree-like) ontology as you try to choose of the atributes as the categorisation dimension, and leaving everything else as properties.

Only if that is how you choose to model the problem domain.

> This is different than just asserting facts with data, which can lie in multiple dimensions.

The "Is ..." examples you detail can just as easily be modeled "in OOP" as:

  class Animal {
    private knownFacts = ...

    def is (fact) ...
  }
Without the need for "a hierarchical (tree-like) ontology", since obviously this would be a poor choice in this situation.


Not the same thing, as the facts are now a property of Animal. My second example doesn't even mention Animal. You still have the problem of "putting things into a category" vs. just asserting facts.


There is an implicit subject you are asserting facts about though. You clearly are talking about a fluffy, white Cat in your example. It’s essentially structural rather than nominal typing. The “fluffy, white Cat” is defined by its traits. We could define a type Cat which has a subset of those traits and then be able to use our “fluffy, white Cat” anywhere we can use a Cat. We only name them to avoid having to name all the traits all the time. Doesn’t make it any less object based.

Structural typing is really cool though. An object built from a named, saved recipe will work just as well as something cobbled together on the fly and at runtime you won’t even know which is which. It’s the basis of a lot of general purpose game engines composition based game object interface.

I’ve also found it extremely fun to use with TypeScript.


> There is an implicit subject you are asserting facts about though. You clearly are talking about a fluffy, white Cat in your example.

No, I'm not, because I didn't assert this fact (it's a Cat).

See how hard it is to break free from this mindset of objects.


Right as I said it’s structural typing. It’s implicit that the traits are grouped together to describe something. And individual traits could be grouped together with completely different ones to describe something else. That you choose not to name it doesn’t change that the trait collection applies to fluffy, white Cats whether you like that or not. I can even choose to call it one thing and you can choose to call it something else and the types will remain interchangeable. You can even leave your type anonymous and it will still be interchangeable.


Uh, no. Either of those are possible without leaving the OO paradigm, and only very poorly taught and inexperienced students model data as an object inheritance hierarchy.


If only.

Spoken like someone who has never seen any kind of representative sample subset of real world code...


No, the problem is that code by poorly taught and inexperienced developers is rife. Heck it’s on display throughout the threads on this topic; for maximum irony, often as an example of “why <concept> is bad”, the author not realising this merely telegraphs their own limitations.


If f(x) is implemented for white xs and separately for fluffy xs, how do you disambiguate f(x) for x that's both white and fluffy?


Hence traits?


And ECS is fundamentally a trait system!


I know all the terms are overloaded nowadays so everything’s kinda unclear but I always wished that ECS components had been called traits, because adding a component to an entity gives it some a trait like “this thing has a position in the world” or “this thing can be drawn” (and perhaps have systems named “behaviors”, because systems add behavior to entities based on the traits/components that they have)

Years ago, when ECS was just starting to be talked about (after Adam Matrins blog posts), I wrote a toy ECS where I used that naming convention. Nowadays I stick to the mainstream terminology since that’s what other people know.


They have, but there is a certain tendency to ignore CS literature.

"Component Software: Beyond Object-Oriented Programming"

https://www.amazon.com/Component-Software-Beyond-Object-Orie...

1st edition, 1998


Yeah I've commented before that "entity component system" is roughly synonymous with "thing piece thing" or something like that - it's a really bad name because it's so ambiguous. Anything including the term trait would be 1000x better because at least "trait" means something.


I think it's named ECS because before then entity+component designs were common in games. ECS generally took the behavior off the C and puts it in the S.


There's a great old (2005) blog post on this topic:

Clay Shirky - Ontology is Overrated: Categories, Links, and Tags

https://web.archive.org/web/20191117162526/http://shirky.com...


Folks may enjoy some of these old posts too.

https://en.m.wikipedia.org/wiki/Pyrrhonism

For example, putting regions under a cold climates category, might not make sense to someone living near the pole where they would consider the same regions to be warm climates.


Thanks, that was a great read. Tangentially related, but I wonder what's the impact of Windows having a really bad search. Maybe people are thus relying more on the folder hierarchies, and that influences how they think?


Humans have a natural tendency to refine a single idea by splitting it into two based on a differentiating factor. This ends up looking like a tree when applied repeatedly. Dichotomous keys for species identification are another example of this.


The problem being that they don't categorize things into one tree, but many. One can view the same thing in different ways. OOP tree hierarchies do not allow that.

It's like trying to categorize your photos in a directory tree. Do you categorize by year first, by person, or location? There is no correct answer. What people want instead is a photo album with tags. The same problem applies to OOP.


> It's like trying to categorize your photos in a directory tree

A problem that made me think about tags instead of categories was precisely that: I have photos that I want to organize. I started by organizing them by person with a folder for each person. But how do I handle a photo where multiple people are in it? Tags don't have this problem. Unfortunately file systems don't support tags.


> What people want instead is a photo album with tags

What you really want is hierarchal tags :)


No, no. We want tags. Later we want hierarchal tags (with some complex workarounds to maintain some legacy thing included in the implementation).


  Silly monkeys
  Give them thumbs, they forge a blade
  And where there's one they're bound to divide it
  Right in two
SCNR :)

For everyone that doesn't know the text: I recommend listening to Tool's "Right in two". Although the text originally talks about war and strive, not programming. ;)


Oh man, I have a rabbit hole for you.

https://en.wikipedia.org/wiki/Rhizome_(philosophy)


Here's a near-decade old talk from me on this exact topic: https://www.youtube.com/watch?v=YfKAScYkGlk

I haven't watched this in like... a long time, so maybe I'd think it's bad now.


I recommend Manuel de Landa (stylizes his name to Delanda these days), particularly “Intensive Science and Virtual Philosophy” if your flavor is Anglo style analytical philosophy.

The relevant Deleuze texts (A Thousand Plateaus) can be infuriating if you’re not open to this whole other style of thinking, but Deleuze is no postmodern, he’s a realist and a materialist and sort of a science worshipper, albeit from an angle that would make Neil deGrasse Tyson start bleeding from his nose until he passed out, if he ever grokked it. Start with Delanda, probably.

[googling a little, this isn’t great but isn’t bad for something readily accessible: http://dar.aucegypt.edu/bitstream/handle/10526/3534/DeLanda%... ]


Heck yeah, in full agreement with all of that.


A tree is a graph where all vertices have exactly one path through them.

Trees are often implemented using composition, and inheritance can be graphical (the Diamond Problem is not game over).


    A
   / \
  B   C
 / \ / \
 D E F G
This is clearly a tree, but doesn't B have 2 paths through it? A->B->D and A->B->E.


You're right. The correct definition is that any two vertices are connected by (i.e. are the endpoints of) exactly one path.

Fun fact -- since graph-theory trees are undirected by definition, an inheritance graph is more properly called an arborescence (for single inheritance). For multiple inheritance it's a DAG (with diamond-pattern) or a directed tree (without).


> any two vertices are connected by (i.e. are the endpoints of) exactly one path

No.

You just described a connected acyclic graph, not a tree.

In addition to being connected and acyclic, a tree must also have a root, and is thus implicitly directed.


> I have this "theory" in the back of my head that trees are usually the wrong things to model thing in life but it's what come to us naturally.

Have you by any chance read the relevant passages in SICP? It has some things to say about OOP ontologies.


I don't think I did, I didn't finish the first chapter of SICP. I'm sure that I'm not the first one to come up with this though.


Could you link this?


https://mitpress.mit.edu/sites/default/files/sicp/full-text/...

Possibly that section. It's not about OOP specifically, but about type hierarchies generally.


You might enjoy this essay from 1965, "A City is Not a Tree": https://www.patternlanguage.com/archive/cityisnotatree.html


Except that trees are by definition graphs with specific conditions on direction and cycles.


Perhaps it is those very conditions which make trees less useful than they at first appear.


I would argue that its those restrictions that make trees a useful simplification, but also a simplification


In general yes, but in certain case they force you to simplify in a way that's later painful.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: