Before I come to the question whether object orientation does or does not have its limitations, I would like to define what a class in the object oriented sense is to me. To me, a class is a description of a data type T together with a description of functions f_i, with the interpretation that the data of type T can be exclusively manipulated only by these functions f_i. Hence, the data of type T is “encapsulated” and can be accessed only through the functions f_i. As a result, the signature of the functions f_i is per convention incomplete, as they additionally to their mentioned I/O data types operate also on the only internally visible data of type T. Additionally, but not so important for my further discussion, object oriented languages provide extension mechanisms for classes, often also called inheritance. More formally, we could say that a class is a description of a finite functional structure representable by a finite state. So, it comes to no surprise that object orientation was invented as programs became more and more complex and the pure algorithmic issues faded into the background because of the more and more dominant issues related to program structure. And compatible with this similarity, a common parlance talking about classes is to say that they define an “object model”. I think there is no doubt that object orientation has indeed brought us quite some step to conquer the increasing structural complexity of modern programs. However, there seems to be some dissonance in this doxology. E.g. object orientation seems to have its difficulties with distributed data processing. And it seems to have some issues with mass processing. In my opinion, these limitations of object orientation stem from the fact that – following model theoretic ideas – encapsulating data with functions is a semantic determination with respect to the meaning of the data. The essential question arises when the blessings of providing functional structure become a curse. The simplest things first: mass processing. Uops, you might say, there is no difference in the semantics of single versus mass item processing. But unfortunately this is wrong! Just imagine the difference between processing 1 data item an hour or 1 million, especially if a systematic error throws 20% out of the course and you have to deal with this mess. Object orientation tends to singularize. Because single versus mass processing is a question of the type of provided functionality, object orientation determines the program structure in this respect. Thus, we have to be particularily careful not to hinder mass processing by singularization. E.g. if we create a single method save() as an instance method, then we are pretty close in inserting single data items on the database. However, this issue can largely be solved by the buffer pattern, where the data of some objects is just registered for further processing and the actual processing is then done on data packages of adequate size. As this buffer pattern is ultimately based on the transfer of data from the single item into a multiitem structure (in the model theoretic sense), a language which does not allow for a separation between processing by functions and data at all, will probably not allow to describe a completely satisfactorily solution to this issue. There is another realm, even more important, which cannot be described with function declarations: the meaning of asynchronous branching for control flow. If a parent thread of control (ToC) realizes some function f and in addition generates a child ToC, representing some function g, then it makes no sense to describe this additional functionality by the function declaration, actually abstracting f. We can illustrate this fact by looking at possible exceptions. The exceptions of the ToC representing f have to be declared at the interface, abstracting f. However, it does not make any sense to declare the exceptions of the child ToC functionality g at the same interface, because the flow of control of this thread will not return to the calling point of f in case of an exception. A good example is the difference between transportation and processing of business documents. The sender of a business document may control the transportation functionality, using a synchronous transport protocol like HTTP, but it will definitively not control the document’s processing, as this will happen asynchronously under the control of the logical recipient. The consequences of this issue for the way we can (or can’t) describe processes are quite interesting – so stay tuned for the next blogs.