Category mistake

stackexchange
https://softwareengineering.stackexchange.com/questions/316507/what-is-the-correct-oop-relation-between-complex-and-real-numbers


 * @KevinMills math is very different from programming here in the sense that math objects are immutable. In the context of programming, establishing relation between real and complex numbers would be rather "a category error or category mistake" as was pointed in this answer to similar (possibly diplicate) question – gnat Apr 22 '16 at 12:16

Domain driven design
https://stackoverflow.com/questions/1222392/can-someone-explain-domain-driven-design-ddd-in-plain-english-please/1222488#1222488


 * https://en.wikipedia.org/wiki/Identity_(object-oriented_programming) "..Identity allows the construction of a platonic ideal world, the ontology or conceptual model, that is often used as basis of object-oriented thinking ..."

Which is meaningless nonsense. Stuffing the functions in a struct(class), doesn't give you "rock" based thinking but convoluted procedural programming.

https://en.wikipedia.org/wiki/Domain-driven_design

Herman Peeren
http://hermanpeeren.nl

https://groups.google.com/forum/#!topic/dddcqrs/X3v_b7lxOak

https://groups.google.com/forum/#!topic/dddcqrs/TbzX5OxpNSM

https://groups.google.com/forum/#!topic/dddcqrs/Icep9ujRllk Yes, I see something fundamentally wrong in our beloved concept of Value Objects: there is a category-mistake. That is an indication of a logical error. I'm still investigating the consequences of that and how we can improve our language and thereby our models by avoiding that mistake. This is work in progress.

But I also understand where Value Objects came from and what the merits of the concept was. DDD was a fresh wind in the merely technical modelling practice of those days.The core message of DDD was to focus on the domain, not on general technical terms and that is still a splendid advice. We mainly used ERD's and UML-diagrams in that time. It was very common to model everything as an entity (corresponding to a relational db-table), which gave huge highly integrated object graphs; accidental complexity at its top. Trying to dissect this mess and reduce this complexity, DDD came with practical 'design patterns'. One of those patterns was Value Objects: some objects in your domain don't need an identity-property, because they represent a value and can be replaced instead of updated. In our OOP-languages everything is an object (or mostly: everything is defined as a class and instantiated as objects). The Value Object pattern showed that there are objects where we can leave out the identity-property and just take a new one instead of updating its value. That was a simplification that greatly helped to reduce complexity.

The category-mistake of seeing domain objects as either entities or value objects already was in our models before we used the concept of value objects: when we modelled both the whole and the parts as entities, we already made the same mistake, but it was not visible yet. We didn't see the mistake because we were used to thinking in relational calculus, where everything is a tuple (a relation or table); that has greatly influenced our OO-thinking, where everything is an object, all of the same category. By making the distinction between Value Objects and Entities however, we started to make a distinction between two different categories of objects. By explicitly making two categories of objects, the category-mistake became visible.

When we can use a more elaborate and expandable type system for our values, then we don't need Value Objects. We can then say that something has some price, weight, time, etc. and both the quantity (number) and quality (currency, measure, etc) are part of that value. Those types describe what kind of value something is. That is what I meant by "value objects are just values": if you can only use classes/objects to type a value, then those objects are not the same category of objects as entities, but they are of the same kind as primitively typed (integer, string, etc) values. If a car is red, then its colour-property is the colour red; if a product costs 5 euros, then its price-property is 5 euros; if someone weights 65 kilograms, then her weight-property is 65 kilograms. So, in my model I don't have a car-object and a colour-object, not a product-object and a price-object, not a person-object and a weight-object, but a car, a product and a person with properties that have specific values (of some type). Of course, when implementing this in a computer language where the only way to specify the types for those values are classes/objects, then I have no other choice but to use Value Objects for those types. But those value objects are still nothing else than values.

My quest is to figure out what errors (if any) in our models are the result of the category-mistake of splitting domain-objects in Entities and Value Objects, how we can avoid those errors and so improve our models, without throwing the baby out with the bathwater.That is also why I emphasised the merits: we must keep the good things. This is still work in progress. Until now the main thing I learned from it is, that models are simpler when you don't put things from different categories together, but split it up in your models. Make a different diagram (or event storming session or other ways to model) from a whole and parts/aspects. Interestingly, categories don't have to be mutual exclusive; they can be orthogonal. Also see Christopher Alexander's "A City is not a Tree". That (implicit) complexity can only be unraveled by modelling per category. All sounds pretty theoretical, huh? I am looking for practical examples to illustrate this. To be continued, but then concrete; I promise.

ycombinator

 * the posters on the ycombinator thread gets agitated with one another because they don't realize the category error or mistake that oop entails. Stuffing procedures into a struct has nothing to do with the behaviour of ducks in the real world(Dave Acton) .

https://web.archive.org/web/20120113062955/http://lists.canonical.org/pipermail/kragen-tol/2011-August/000937.html

https://web.archive.org/web/20051214092027/http://plasmasturm.org:80/log/338/

https://news.ycombinator.com/item?id=2914405

Actually, this makes more sense as a trait or interface than as a superclass, especially as you're not even implementing any behavior. It's the same way for squares and rectangles. Square does the Rectangle and Quadrilateral interface, Rectangle does the Rectangle and Quadrilateral interfaces, and it doesn't matter. If you want a subtype/supertype relationship, then you have to diverge from what people intuitively think about classes. Liskov's Substitution Principle says that subtypes must be completely substitutable anywhere a supertype is used, which means a rectangle isa square because a square does setX, getX, and getY, whereas a rectangle does setX, setY, getX, and getY. (This doesn't make much sense because people use inheritance as "copy and paste this crap from the superclass into my subclass" rather than to setup substitutable subtype/supertype relationships.)

Interfaces avoid that problem because there is no supertype or subtype, only equal types that agree to have the same interfaces. Then it doesn't matter if a square isa rectangle or not.

When people say "Duck extends Animal" is bad they typically mean that it's trying to model real-world relationships rather than computational relationships. The example is meant to demonstrate that inheritance should be based on what inheritance means for your program, to make your codebase "nicer", and not to simply categorise your objects. "Spaceship extends GameObject" exists mostly to facilitate polymorphism and code reuse - virtual function resolution, probably, along with all of the non-virtual data and behaviour associated with every GameObject. A "GameObject" isn't a real thing, it's just a convenience.

So domain modeling has no place in software? The burden of proof for such a claim is a bit higher than "you can't add code to ducks". That ducks are physical is irrelevant in any case. You can't add code to bank accounts or insurance policies or leap years either.

jerf on Aug 23, 2011 [-]

"You can't add code to payrolls or insurance policies or bank accounts either." No... you can't. Exactly. OO isn't about real-world-objects, it's still about code-objects, and mixing the two up causes serious category errors. I don't get what you're saying. What does it matter whether software is modeling a physical system or, say, a business one? Either way you're drawing on concepts from some domain that exists prior to the software you're building. Either way you're trying to find representations of those concepts suitable for computing what you need to compute. The art of domain modeling is making those representations intelligible in domain terms. This has nothing to do with physicality. Of Evans' canonical examples in Domain Driven Design, one has to do with paint-mixing and another with accounting. The techniques are no different.

jerf on Aug 23, 2011 [-]

"The art of domain modeling is making those representations intelligible in domain terms. This has nothing to do with physicality." Yes, exactly. I do love how often people cite back my own points at me as if they are disagreeing.

I think perhaps people have forgotten the origins of OO. A lot of people were taught that the right way to do OO is to match the physical model of the domain they are trying to program for. It's great that you and so many other people have either thoroughly internalized how untrue that is, or were never taught that model in the first place. But I for one was, as were a great deal of the rest of my generation who learned about OO in the 90s, and it's actually somewhat important that we finish stomping the idea out that physical mapping is at all an important aspect of OO.

And the best place to stomp it out of is in the Standard OO Tutorial (TM).

If you and all the excited downmodders never learned that bad idea in the first place, great! Count yourselves amongst the lucky people who probably also never had to be broken of things like line numbering, or two-letter variable names. (If you think I'm joking, I only wish I could show you some of the first-C++-class homework I graded back in 2000. I'm not joking.) In the meantime, this is a real thing that is still floating around in real curricula today, and you may join me in boggling at this fact, but it doesn't change its truth.

It actually stuns me that some of employees that we've hired who graduated as recently as last year appear to have received the exact same OO education that I did in 1999, which was already pretty creaky then. The map is not the territory.

Actually, you're right. I started with OOP around the same time (sounds like), and I remember having trouble grasping the benefits of OOP then because, like you say, it was much more complex all the way 'round. I was used to just calling functions which would return a struct and then passing that struct to other functions, which was straightforward and easy to keep track of. > ...my instructor told me that was wrong and that I didn't understand OOP...

Ugh.

I wonder how it should be taught then? Looking at the comments in this thread, it looks like a lot of people are simply choosing to use it in ways that make sense to them. Is there a universally-agreed-upon use case for OOP? If not, is there anything wrong with just teaching it as one of many tools, and letting students sort it out on their own?

I've tutored a few kids on programming. OOP has been my least favorite part every time. I honestly have no idea how to approach it as an occasional instructor. --- 1. I absolutely agree with the linked article. My perspective is somewhat different, however. I submit that OO hierarchy should not mimic whatever properties whatever real-world objects may happen to possess. Instead, when we solve a problem and have come up with a solution, the OO hierarchy should describe the solution. A different solution, or a different problem, may easily lead to a different hierarchy of (perhaps different) objects. And these would be software objects. 2. Therefore, I suggest that a "simple" example would come from a well-known software system. Such as a window system (rectangle, button, icon, window, etc) which, either as a concrete example or an abstraction, should be easily understood by anyone with a minimal (desktop) computer experience and no programming experience.

siglesias on Aug 22, 2011 [-]

I completely agree with this. Duck-laden object oriented programming tutorials made no sense as I tried to transition from C to Objective-C. The best explanation I found was Chapter 2 of Apple's "Object-Oriented Programming with Objective-C": "Every object has both state (data) and behavior (operations on data). In that, they’re not much different from ordinary physical objects. It’s easy to see how a mechanical device, such as a pocket watch or a piano, embodies both state and behavior."

from apple oop paper

Is Kragen making an elaborate joke about duck typing here? Penguins don’t implement the “fly” method that can be found in birds. And you don’t go around causing things to fly without knowing what kind of bird they are. (Ducks themselves decide when they want to fly, and they certainly seem to know they’re ducks and not vultures.)

kragen on Aug 23, 2011 [-]

> Is Kragen making an elaborate joke about duck typing here? Not really, no. I was just saying that "fly" methods on hypothetical bird classes fail to motivate OO.

joe_the_user on Aug 23, 2011 [-]

Just one piece in the whole object orientation blows but still is the best thing we have to make complex systems understandable to simple people quandary. It is true that the real world object examples confuse everything that OO is really used for. It is also true that we need them to make OO approachable at all.

OO is essentially an ontological error where multitudes of logical and representational levels are trampled on. The thing is, OO uses* the adhoc mixture of logical confusions that is most people's description of their world. Somehow people's amazing brains muddle through speaking natural language despite it's terrible muddling of everything. Thus we can stand the confusion of not really knowing whether "class window" is a glowy thing on the screen, a location in memory or an abstract datatype.

javadevwannabe
http://javadevwannabe.blogspot.com/2012/02/state-behavior-and-identity.html Summary Objects are representations of abstract or real things. Their use in object-oriented programming is to allow designers to model the world accurately.

Objects represent particular instances of things, and classes represent types of object. Different classes are used for different problem domains.

links
oop, Apple oop paper

Noun, Nouns and verbs oop