*quick note: I don't have much formal training in PL's, so if I'm wrong, please correct me. For reference, I know python, C++, C, JAVA, OCAML, LISP, prolog (in that order of familiarity).
The quick one liner:
Why are objects that we use in programming so vastly different from real-world objects?
The slow multi-liner:
Human languages have the ability to talk about the state of the world, and all of them contain nouns, which rather than describing a particular thing, they are supposed to indicate a set of things that contain a certain property. Cars can be driven; boxes are containers; speakers produce sound. People from different cultures that have different languages, even with a difference in nomenclature, typically have common words that describe sets of things the same way. In addition, modern science has found mathematical relationships between classes of things with precision. All this to say there is such a thing as "real-world objects," it is not arbitrary (and suggests that there is a right way and wrong way of describing things.)
Most programming languages have a concept of objects, and allow programmers to define them and describe relationships between objects. The idea of objects helped programming with type-checking, encapsulation, code reduction, etc. In fact, an argument can be made that the job of the programmer is to figure out a representation (real-world object -> code -> binary data) of a problem and a process to solve the said problem.
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.
When the representation in code is the same as a person's understanding about a real world object ("common sense" or common understanding), the person can process and reason and be productive with the code with ease (like.. integer object types). On the other hand, if the representation is not the same (unintuitive), then the person has to go through the documentation/look over each line to match up the person's internal representation with the representation in code, making programming difficult (any large scale programming project).
Class of Real World Objects: A set of things that has the same property. ex: a cardboard box (made from paper, rectangular, contains stuff)
Relation: A relationship between objects. A relation between object A and object B describes a constraint on some properties of A and B. ex. a ball is "in a" box (constraint on the location of the ball)
Inheritance: A particular relation between object A and object B where object A has a subset of the properties of object B. (an ISA relation) ex. a paper box "is a" paper object. a paper object "is a" physical object
Functions: a relationship between the parameter and the return value
Objects in OOPL:
Objects in object-oriented programming languages (the most straightforward implementation of objects) are defined by the name of the class, with a list of attributes and functions. Relationships between objects are implemented through inheritance, templates, functions, or attributes. Many problems come from the use of inheritance, where the base class has to contain a subset of the derived class, so there is no implicit way of sharing attributes between derived classes if it isn't in the parent class -- unless you restructure the inheritance tree to no longer resemble any real objects (which require constant refactoring with each additional class). Note, functions in the class definitions are relationships between the parameter, the self object, and the return value.
Objects in logic programming:
Logic programming (the most straightfoward implementation of relations) defines objects in terms of relations. Atoms can be objects, and classes may be declared with single term predicates.
brother(A,B) :- isHuman(A),isHuman(B),father(C,A), father(C,B).
Defines the relationship "brother" for objects of class human
ownsPet(A,B) :- isHuman(A),isAnimal(B),has(A,B).
Another example of a relationship. you can find who owns a pet named kitty (?-ownsPet(X,kitty).) and you can find the pets that a person John owns (?-ownsPet(john,X).) (think about how to program this simple relationship in OOPL -- adding owner to class animal and pet to class human would require two fxns and messed up classes).
Some logic programming languages are object oriented, and with clear definition of objects and relations, come the closest to the way we think about objects. However, logic programming is (typically) done on horn clauses, and uses backtracking to solve the query (run the program). Therefore, you can't put all human knowledge into a prolog program, and still expect it to solve your query in a reasonable amount of time.
Object-oriented programming give very good benefits to the programming environment (encapsulation, abstraction, code reduction, code reusability, type correctness), but common approaches limit the definition of objects, creating objects that no longer describe real world objects and sometimes decrease productivity in the process. Rather than thinking "what objects there are, and how to use the relations between them to solve the problem," a programmer has to think about "what objects can I implement that will give me all the benefits without any of the problems."
Logic programming approaches, on the other hand have a particular control process, which make intuitive implementations of real world objects unfeasible to solve.
So here's the discussion: How do you improve object and relation definitions in a way that is "natural" and useful to programmers? Is there a provable reason why objects in programming languages are so unintuitive? will they ever be?
[and bonus question: benefits/pitfalls of object-oriented functional langages?]