6 ms·
I think the big problem with OOP is that it's designed to simulate the real world but has the real world backwards. Real world objects are a composition of par
by jwdunne 9y ago
I think the big problem with OOP is that it's designed to simulate the real world but has the real world backwards.
Real world objects are a composition of parts. The taxonomy of those objects, and its constituent parts, is am artificial construct independent of how those objects are composed. A frog is a frog because it fits some definition that experts agree on. The taxonomy comes afterwards - the composition just is.
What we have is a model where the taxonomy comes first. We say a frog inherits from an amphibian. What makes an amphibian an amphibian doesn't matter in OOP. Further, the language rarely provides the same means for composition as it does for inheritance and taxonomy. That's a problem.
In fact, the only reason why a frog is an amphibian is because it has parts all amphibians share. The label comes afterwards, after looking at the constituent parts.
In this way, OOP would benefit from composition-first, taxonomy after. An object is a thing because of what it has (and this includes behaviour too), not because of what it is or descended from.
It should be entirely possible for me to construct an object that fits the definition of a frog without specifying I'm creating a frog.
- jcelerier 9y ago> It should be entirely possible for me to construct an object that fits the definition of a frog without specifying I'm creating a frog. The problem with this approach is that different domain experts will have different definitions of what "is" a frog. If you ask a theologist, a molecular biologist, and a zoologist to define a frog, you'll certainly get three different but valid answers.
- akvadrako 9y agoThat's not a "problem" - that just means you have different frogs - each with a well defined criteria.
- jwdunne 9y agoThat's just a problem of context. With the taxonomy separate, the objects can be different things in different contexts. With de facto OOP, you have no hope in hell because the taxonomy is hard coded to the structure of the object itself. My point is supported by what you say, in fairness. A taxonomy is artificial and separate to the actual object itself. It can and is different based on who defines the taxonomy. My argument is that this is why OOP suffers: it makes the taxonomy inherent to the object and all best OO practice tries to work around that. "Composition over inheritance" anybody?
- jcelerier 9y ago> That's just a problem of context. With the taxonomy separate, the objects can be different things in different contexts. Except that you want to share properties between those different contexts, and this is where hell begins. For instance (for a more programming-related problem) say that you have a gui application with graphical objects that map to your frogs,say a frog pond simulation. Now months passes and the boss says "okay, seems that our software interests molecular biologists too, but they need to have another 'molecular frog view' with properties Foobigate and Brozigate to study them properly at the molecular level. Of course the 'molecular frog view' has to be in sync with the 'pond frog view', also they want a simple readable save format.". Now, how do you set up your code so that Joe programmer that comes next week can be operational on the code in three days ?
- jwdunne 9y agoI love how much this comment makes me think. Thank you! To be honest, this sounds like a hell hole no matter what you did. It's a complex program that services two domains. I would say that in the real world, a frog studied in a pond and frog studied at a molecular level share the same properties. A frog is a complex object that has many parts. Naturally for a pond view, you provide the properties needed for that, through composition of smaller objects. If you want to study it on a molecular level, you are really studying the properties, the constituent objects, at a much more granular level (and perhaps more that you didn't need in the simple pond view). It's all still one object. In fairness, this would be much worse to model in bog standard OOP. Could Joe programmer fair any better there too? Would Joe programmer be working on a macro/molecular simulation in the first place?
- dyarosla 9y agoAs I mentioned above, an Entity Component System would have no issue solving this. You'd add the molecular frog components (foobigate and brozigate) to wherever you create frog entities and then you'd also create and add a system that synchronizes between the entities that have pond frog components and these new components. None of the original code would change minus the instantiation function for a frog entity. Similarly simple change goes for the save format.
- icc97 9y agoOne of the main points of design patterns is composition over inheritance. Composition is also a major part of functional programming.
- jwdunne 9y agoYep, exactly! We now have a bunch if OOP languages that provide language features for inheritance making it easy but composition is an emergent property entirely based on existing language features - it's not a language feature itself. What I'm saying is flip it on its head. Build an OOP language where you have features to make composition easy and separate the taxonomy as a separate thing that shouldn't be tied directly to an object.
- filoeleven 9y agoWould you say that Scala is close to hitting that target? I've only taken a cursory look at it, but its traits appear to satisfy composition and its type system looks pretty close to being a decoupled taxonomy. I'm not sure what a full implementation of a separate taxonomy would look like. Duck typing with an algebraic type system that is only applied when you ask for it?
- jwdunne 9y agoI haven't looked at Scala closely. I'll take a look - thanks for the tip :) This is something I'm thinking about a lot. I've been wanting to sit down and sketch out what it would look like in terms of syntax / structure. Difficult with 3 kids, wife and a full time job. I think behaviours should be able to specify taxonomy, which in effect is a name for saying "I only accept objects that do this and have that". I envisioned a system where it's perfectly possible to work with purely anonymous taxonomies i.e your behaviours specify explicitly what its parameters have in terms of behaviour e.g if an object parsed a string, we could expect that the parameter has just the behaviours needed to do the work e.g length, substring, equality. Or we could just say it wants a string (which is just a separate alias that says an object has those things - like an interface except you don't have to declare you're implementing it). I think there is value in being able to see an object you want to be part of a taxonomy fits the bill - this would be more like interfaces. Maybe it's better left to static analysis (stop! you're trying to pass an object that doesn't have behaviour X to behaviour Y that expects it).
- maxxxxx 9y ago"In this way, OOP would benefit from composition-first, taxonomy after. An object is a thing because of what it has (and this includes behaviour too), not because of what it is or descended from." A lot of working programmers have figured this out already. Most experienced programmers I know don't use much inheritance.
- jwdunne 9y agoExactly and the languages don't express that practice. We get design patterns / DI and maxims like composition over inheritance. Our languages still make it easier to inherit than to compose despite all that. Plus, my wider point was that in the real world, which is the inspiration for OOP, the taxonomy is artificial and placed onto an object. The taxonomy isn't an inherent part of the object (i.e Dog extends Canidae). The taxonomy is given to an object based on its composition separately i.e a dog is a dog because of some property x, y and z and just so happens that X, y are what makes Canid a Canid and X is what makes a carnivore a carnivore.
- willtim 9y agoUnfortunately OOP languages typically lack sum types, the mathematical dual of product types (objects with just fields). This means subtyping and inheritance is often needed to encode sum types.
- mbrock 9y agoIn functional languages it's easy to run into difficulties with extending a sum type without changing the defining module.
- dyarosla 9y agoI think you'd benefit from taking a look at Entity Component Systems. Generally used for games, this programming pattern assigns behaviour to entities based on the components that they have. Moreover, neither entities nor components on their own actually own any behaviour. Behaviour occurs by systems that operate on entities with the associated component "signature". For example, an entity with a position and a velocity component (position could hold x,y,z values and velocity vx,vy,vz values) could be operated on by a movementSystem (which adds behaviour to any entities that have both a position and velocity component, and updates position values based on velocity values.) The nice thing about such a system is that the taxonomy as you call it gets defined when you instantiate the systems of your program. If you have entities with position and velocity components but dont want to use a movementsystem to operate on them, you simply dont instantiate the movementsystem. Pretty flexible, but not used excessively outside of video games.
- jwdunne 9y agoThank you - I think this was probably the inspiration or seed for what I was thinking :) I was amazed when I saw the ECS architecture when I filled my toe into game development. I remember wanting to apply it to other areas outside of game development. It's interesting though that a paradigm that intends to help simulate the real world has been eschewed for speed and maintainability in favour of something like ECS in game development, which is all about simulation.
- dyarosla 9y agoYeah it's an interesting pattern and even when implemented in an OOP language ignores most OOP ideas in favour of what is really more akin to data-driven design. There's some great insight into how the pattern evolves in non-game projects here: https://softwareengineering.stackexchange.com/a/306983/271434 https://softwareengineering.stackexchange.com/a/306983/27143...
- magnusjonsson 9y agoThat's an awesome article! Thanks for sharing.
- dragonwriter 9y ago> I think the big problem with OOP is that it's designed to simulate the real world I actually think that it's more designed to reflect (one particular idea of) the way humans construct mental models of the real world. > Real world objects are a composition of parts At the lowest level, sure, but if our aren't modelling quantum physics, the “parts” are abitrary artificial divisions (or aggregations), not part of the fundamental nature of the real world, which are no more fundamental than taxonomy (or identity) of the objects they compose. > In fact, the only reason why a frog is an amphibian is because it has parts all amphibians share. In a typical taxonomy, that's true, but it's not in a phylogenetic one, which is based on ancestry, not parts. > It should be entirely possible for me to construct an object that fits the definition of a frog without specifying I'm creating a frog. OOP allows this (and it's common in dynamic OOP languages, back to Smalltalk), though static class-based OOP (which treats inheritance as type heirarchy) relies on declaration to limit what an object can be used as.
- jwdunne 9y agoFood for thought. Your comment shows a wide range of knowledge and covers things I haven't thought about. I was reading about the history of Simula and how the majority of OOP features originated there. It was built as a simulation language, hence the name. I took from that it was designed to simulate the real world - I guess based on the below that's akin to simulation of mental models. I did briefly think about the quantum mechanics rabbit hole. You make a good point. I'll think about this more. People can tell what a radio is because they have a general idea of what a radio does - has a speaker, volume, aerial. This is what led my thinking. I'll think more about this.
- slackingoff2017 9y ago>It should be entirely possible for me to construct an object that fits the definition of a frog without specifying I'm creating a frog. This is known as structural typing and TypeScript does exactly this. Two objects with the same properties are the same. This usually works well, but there are a few issues with this. Number one is related to optimization. The type system that results from using structural typing is unsound. This doesn't matter for typescript since it compiled down to JavaScript which has no types anyways, but for a typical VM executed language there's many optimizations the compiler can't do. The second issue with structural typing is what I like to call the "mixin problem". If you get too flexible with composition it becomes close to having no type system at all.
- Others 9y agoIs it true that all structural type systems are unsound? I was under the impression this is a typescript specific problem.
- slackingoff2017 9y agoI tried to find the answer and it seems the problem is much more complex than I thought. Rather than bullshit about it I'll just say I have no idea :)
- didibus 9y agoIs structure defined just by type? Like is all things which only have two integer properties considered the same? { Int age; Int weight; } Would be equal to: { Int x; Int y; } ?
- slackingoff2017 9y agoClose, any objects with the same properties and types are compatible. The name of the properties and their types need to match. And this isn't always a good thing. If you have a function dealing with the property 'length' or 'value' for instance, you might as well have no type system because Typescript will allow you to pass in any object with those properties which is almost anything. While the code will still compile and run like this the type system has failed its purpose of preventing developers from using the wrong types.
- d0mine 9y agoDifferent languages encourage different OOP styles e.g., Go language encourages composition. Though people may argue on the meaning of OOP https://groups.google.com/forum/#!msg/golang-nuts/bSXry29pNo4/hO6z0tccEQAJ https://groups.google.com/forum/#!msg/golang-nuts/bSXry29pNo... Direct link: http://www.purl.org/stefan_ram/pub/doc_kay_oop_en http://www.purl.org/stefan_ram/pub/doc_kay_oop_en