"Yet even with the amount of programs being written and problems about objects being solved, rather than converging on a complete representation of real-world objects, objects in programs seem to diverge, where an object from one project is different from an object from another project and is typically different from how a normal person thinks about the real world object."
The problem is not with object-oriented programming. It is a problem of our minds, of philosophy, of language.
An apple is an object. Our minds cannot know everything about an apple: the amount of information is too vast (the number and position of cells, different varieties, how to farm them, the quality of this particular apple, how it tastes to snakes, etc.).
So our minds create mental models of objects by assembling only a fraction of the information needed. The information that we use to construct our mental model is not random: it is goal-driven. I don't know much about apples except which ones I like and how to spot rotten ones. My mental models support my goal of eating tasty apples. If I were an apple farmer or even a cook then my mental model would need to be richer.
People will have many different mental models of a "real world object" depending on what their goals are with that object. So the problem of not converging on a "complete" representation of an object is not a limitation of object-oriented programming, it's an artifact of how our minds deal with the overwhelming vastness of the information around us.
A picture of a pipe is not a pipe. In the same way, an object in a programming language is not the same as the real world object that it represents (if there even is one). Of course we all know this, but it is also easy to get confused, if you're not careful.
I have posted this because of comments. Good part of them agree with your statement.
"One of the best leaps a programmer makes during their path from newb to godhood is to realize that 'objects' don't map well to real world objects. Programs work better, designs are more clean... code sucks less when a object in code represents the embodiment of a singular concept; a singular set of invariants rather than an object. Is that a failing of language design? A quirk of calling it object oriented programming rather than state oriented programming?"
This apparent mismatch has mostly to do with the common use of oo, rather than oo itself. Joe Armstrong, creator of Erlang, is famous for quoting Alan Kay (who invented OO) when he wrote that the big idea behind smalltalk is not classes or objects, but messages (Joe Armstrong recently mentioned this at 4:30 of his most recent Qcon presentation: http://www.infoq.com/presentations/Message-Passing-Concurren...)
Jim Coplien and Trygve Reenskaug discussed this apparent mismatch on the article: The DCI Architecture: A New Vision of Object-Oriented Programming (on http://www.artima.com/articles/dci_vision.html).
Because most programs aren't simulators, and there often isn't a natural way to map the concepts involved in an application to that of the real world. When you move beyond the garbage examples they give in computer science 101 ("RaceCar extends Car") you realize objects still have their place, just not in the way the professors taught you.
I think that people tend to fuse two different things in their designs. The first is the model that represents the real world and the second is the structure needed for software to work.
"RaceCar extends Car" is perfectly ok for modeling the entities involved. But writing a paint() method into Car or RaceCar is stupid. You need Visitors, Actions, Dispatchers, DAOs and whatnot for your programs to have a sensible and maintainable structure.
I believe that the success of OOP is more a matter of usability (for the programmer) than a connection with real world models. Simpler syntax and state conservation are in fact more intuitive to use than previous ways. Only if one tries to identify at all costs programming objects with real world objects, it reveals as a leaky abstraction.
As others have said; objects in programming languages do not map well to objects in the real world because a. the real world is vastly more complicated than any constructed abstraction, and b. our minds permit vagueness whereas computers do not.
It is not the case, anyway, that say nouns map to real-world objects for example. There are infinitely many variations and intricacies in the way we humans interpret nouns, many of which are entirely context-based. That is another issue - PLs do not have a sense of context the same way we humans do (which is probably a good thing as I'd rather a PL be less vague than a highly context-sensitive conversation with a friend.)
For an indication of the depth of complexity of natural language and the philosophical difficulties therein, Ludwig Wittgenstein's Philosophical Investigations is a good place to look - http://en.wikipedia.org/wiki/Philosophical_investigations.
I do think there is a deeper issue with objects in that the environment in which they are constructed often fails to permit the kind of complicated interrelation that the concept of the object should actually have, i.e. there is not enough freedom to compose and combine objects in a way entirely cohesive with the way you think of the object. However that has less to do with the relationship between natural language and programming and more to do with the limitations of oop itself.
Often, you are only interested in a "view" of this object. A subset of the total methods and data of the real world object. For example, an inventory app may only car about the MSRP, dealer's cost, etc and not necessarily implementing the functions of a real car ( horn.honk() door.IsOpened).
Now, software inside the car may well want to abstract the horn.honk() function for use. (maybe, i'm doubting it's that clean in implementation).
Anyway, not ever app cares about ever aspect of every real world object. Hence lack of re-usability. Even 2 LOB (line of business) app may have different views to the same object. For instance, a telecom circuit. One app is concerned with the physical layout/design, where it runs, what equipment, what locations, what size (bandwidth) etc, etc. While another app may account for this circuit, figuring cost and revenue. Both may share data, but much more likely at a database level than actually pulling objects out of one, straight into another. I've just not seen that level of re-use in biz apps. String is used all over the place, but a highly specialized class for telecom accounting? Probably not. However, these apps probably share customer information because customer contact info is useful for billing and trouble shooting connectivity issues.
So object re-use works great as a software vendor like Sun(oracle) or Microsoft. Java and .Net have some objects that see major re-use. Network, strings, web, drawing, etc. Very common, very easy to re-use. But LOB apps just don't have that re-usability. If they did, why would they need to hire you to work on them? They could just pull it out of the box.
Spot on about reuse - I think it's really the core of a lot of problems people have. Models get complicated because people naturally want to design them for reuse, when in almost every case it's just not feasible. You can't point to something like .NET and say "look at that level of reuse, our LOB applications should shoot for that," because entities in .NET represent things used by all computer programs, regardless of what they do. They model the machine and the network at a level of abstraction appropriate for the vast majority of computer programs out there - not all, but most.
Trying to achieve reuse like that - hell, trying to achieve any reuse in a collection of LOB apps - is incredibly tough, and in most cases not worth it. What's an "employee?" Height/weight/age? ID number? Location? Skillset? LOB apps are just like people: they have different ideas of what are and what are not defining characteristics of an employee.
Software development needs to focus on reuse of ideas, patterns and knowledge (both domain knowledge and computer knowledge), not code. The key to object modeling is making things loosely coupled and encapsulated enough that you can easily modify and add behavior later on, when you realize you actually need it, not throwing everything including the kitchen sink into your model. Even then, you can never be sure that your app or domain isn't going to take a hard left turn at some point and you need to do some major refactoring/remodeling.
I'm having this problem right now. Simulation/Entity type object model is working quite well for one app, but add another app and the cracks in the abstraction become obvious.
Using dynamic properties for the app-specific properties seems to help contain the problem. Also, putting app-specific code in extension methods.
I see this problem as a limitation of our current tools. Splitting the object model into separate perspectives is too hard right now.
Object oriented programming grew out of simulation of real world objects.
Turns out, good OO design requires objects to NOT be like real world objects, at least in some parts, and the OO field has moved past it. However the terminology is still all bound up in simulation type objects, and people are often confused by examples used in schools and books about animals and dogs and barking.
Like many other discussions about objects / OO, some of the confusion comes from having several (often contradictory) definitions of what constitutes an object. Is it an agent that responds to a given set of messages? Is it an instance of a class? What about prototypes? Is inheritance fundamental? What about CLOS? Etc.
Here's my unexamined hypothesis: Objects in programming are unintuitive because they aspire to resemble real-world objects, but inevitably fall short. When you're thinking about some abstract programming feature, your brain knows it's meant to be thinking abstractly. But when you think about an object, your brain can slip into an uneasy DMZ between thinking about abstractions and thinking about real-world objects.
In other words, the problem isn't that objects aren't similar enough to real-world objects—it's that they're too similar without being identical.
We did, but we did it on purpose. Programming languages are mere tools, subsets of human language. Human language evolved as part of human evolution, and is as intimately part of the definition and condition of "human" as a beating heart and a gleam in the eye.
Programming languages are created for limited and specific purpose, relative to human language. They take a few months to a few years to create. They're "received" by most of us, and only if we volunteer.
Human language wasn't created, it evolved, like feet and stereo vision, over hundreds of thousands of years, from grunts to sonnets. We have no choice to absorb language because language is part of the bath of human existence. It grows with us as the result of interaction between environment and genetic capacity, just as we grow arms.
To refer to computer languages as "language" is somewhat grandiose. They are very little like human language, and more like the rules and vocabulary of baseball. In other words, a computer language is merely one use of human language. You could refer to the traffic code or the penal code as language, and it makes about as much sense as referring to computer code as language. They all three are the same thing, a description of rules and vocabulary, meant to accomplish a set of goals in a constrained environment.
In contrast, human language has no purpose, not in the sense that traffic code and computer code have purpose. You can't decide to use human language or not, no more than you can decide not to use blood. Human language just is, and it's that difference in specified purpose and no purpose that tells me they are not the same thing, nor even like each other. At best, computer language is an extremely small and constrained subset of human language.
The answer to "why are objects so unintuitive" is in the question's implied requirement that a computer language be able to describe an object as fully as human language, and that we can understand such an object with all the precision and ambiguity which human language allows; that's impossible.
The relationship between real world objects is both: physical and independent of human thought; and subjective, contextual and dependent on human thought.
A real world object, like a car or a row in a database table, obeys physical or mathematical laws independent of human thought.
Objects also have relationships that don't exist without humans. The car and row mean different things depending on how we decide to perceive them. The row, in the limited context of SQL, is a collection of data that must adhere to constraints, and that's expected to be produced and consumed in limited ways. The car, in the limited context of the traffic code, is an object that moves through the traffic system according to (or not) designed and learned rules of motion and safety.
The row, in the limited context of love and ambition, is potentially my partner for the rest of my life, or this afternoon's rejection. The car in the same language is a symbol of desperate love, as so memorably programmed by Bruce Springsteen in Born To Run.
To expect a computer language to completely, intuitively and consistently describe an object makes no more sense than to expect a love song to determine the rules of traffic.
Language and syntax are not the same thing. You don't have exceptions to rules in programming languages like you do natural languages. That's the difference but in a more complex way. Through natural language, there are simply more intricate and accurate ways of describing things, than in a procedural or methodical object-oriented syntactical manner.
probably because reality is a lot more complex than a computer program.
most objects in the real world are just clumps of atoms and don't respond to messages.
you can take a loaf of bread and slice it into 12 separate objects. do that to a C++ object and you get twelve clumps of 1s and 0s that are completely meaningless.
objects are just attempting to model the world. the model is not the world, any more than a painting or photograph or a story is a real world experience. all are just tools that let you think about the real thing.
There is obviously a far superior amount of information in a loaf of bread.
What is really at work in PLs is the organization of information and in present times this information is not divisible into smaller fractions of itself in anywhere as close to an elegant platform as what the universe offers.
The problem is not with object-oriented programming. It is a problem of our minds, of philosophy, of language.
An apple is an object. Our minds cannot know everything about an apple: the amount of information is too vast (the number and position of cells, different varieties, how to farm them, the quality of this particular apple, how it tastes to snakes, etc.).
So our minds create mental models of objects by assembling only a fraction of the information needed. The information that we use to construct our mental model is not random: it is goal-driven. I don't know much about apples except which ones I like and how to spot rotten ones. My mental models support my goal of eating tasty apples. If I were an apple farmer or even a cook then my mental model would need to be richer.
People will have many different mental models of a "real world object" depending on what their goals are with that object. So the problem of not converging on a "complete" representation of an object is not a limitation of object-oriented programming, it's an artifact of how our minds deal with the overwhelming vastness of the information around us.