I'm not directly arguing for OO. In my opinion, a good language is one which forces the black box encapsulation of complex behaviour.
'House' as an abstraction for a house is a good model. Performing an action on an abstraction should be in an intuitive manner, for example:
sell House
That's pretty clear. To cause the interaction between two objects, then one should place the action between the objects:
make "Agency" sell "House"
where 'make' is equivalent to calling a function. Now, let's bring in a contract
make "Agency" sell "House" using "Contract"
this OO model works in my opinion because there is one path between the objects, and the arguments describe the contents of the path.
make "Person" buy "House" using "TerribleContract"
I believe that programming languages are too flexible. I believe that programming languages should be constructed in a manner that forces you to abstract complex structures into aggregates of behaviour, where the input to these aggregates consist of a very low number of paths. Java, C+++ fail in this in that they allow you to break out of the abstraction hierachy. They allow you to have callbacks and inheritance and so on, which breaks the black-boxiness of your program.
A black-box should always take the same inputs and should always produce the same behaviour from those inputs. Now, what about other types of programming constructs?
Let's say I wanted to send a file to another PC using sockets:
create "File" using "/hello.txt"
As the next step I'm trying to open a port. However, a port has a number. I could try to do this:
create "Socket" using ("Port" using 8934)
"Port 8934" is something that can be merged together into a composite structure and so the user should be forced to do so:
"InputPort" is "Port" using 8934
create "Socket" using "InputPort"
make "Socket" send "File"
destroy "Socket"
This is an example of how I think a properly abstracted language should look like. Force single paths to all abstractions, and force abstraction use.