https://www.destroyallsoftware.com/talks/boundaries
A lot of people I know consider object-oriented design orthogonal to the programming style — that the real improvement is moving from a procedural to functional approach. Any system that grows large enough to clearly define an architecture technically is object oriented, so long as it's passing messages among stable interfaces.
You want to have that functional core and imperative shell. Tell above, ask below.
It's just unfortunate that a lot of "object-oriented programming" that you learn in school is really just imperative programming with interfaces ;)
@straws: I'm curious, why do you think that the situation you mention above implies that such a system is 'technically' object oriented?
If I'm understanding your claim, I disagree. All you need are mechanisms for:
(1) function-calling or message-passing (I don't think you were trying to emphasize an extremely rigourous definition of 'message passing' were you?)
(2) namespacing
(3) validating a 'stable interface'
There are many definitions of OO, but this is one is good enough for my point: "Objects, which are usually instances of classes, are used to interact with one another to design applications and computer programs" (from http://en.wikipedia.org/wiki/Object-oriented_programming)
You don't need object-based inheritance (e.g. Java) or prototype-based inheritance (e.g. Javascript) to build large systems in this way.
For example, you can build very large systems in Erlang (passing messages too!) without any kind of OO.
There are lots of examples of how functional languages can enforce interfaces without classes, including Haskell.
It's unnecessary to create classes for functionality when it's unnecessary to create objects for functionality. Here's an eloquent article on that subject:
http://me.veekun.com/blog/2013/03/03/the-controller-pattern-...