Object-Oriented Problem Separation (OOPS)

and how to achieve it through decomposition into

Many Irreducible Mini-Methods (MIMM)

Computer programming is a particular kind of problem solving.

Speaking generally, the essence of a problem is that we want to

OO programming describes situations by objects; so in the OO context it suffices to talk about objects.

OO programming describes problem solutions by methods. From the problem-solving perspective the purpose of a method is to produce new objects from existing ones or to query or modify existing objects.

We solve problems in steps, i.e., by solving a number of lower-level sub-problems in a certain order.

A method of a class in an OO program describes such a succession of sub-problem solutions.

Inspection of existing real-world programs shows us that methods are very often a conglomeration of problem solutions on several levels of detail. They do not just describe the solution of the actual, primary problem, but also the solutions of lower-level sub-problems in a way which makes it hard to understand all these and to modify and maintain or to completely replace particular of these partial solutions.

We conclude that

can be achieved only if we avoid this conglomeration of problem solutions belonging to several levels of detail. This is what we call

Object-Oriented Problem Separation (OOPS).

It centers around the idea that

Individual methods will become much smaller this way and (hopefully) easier to understand and to modify. Our object classes will consist of

Many Irreducible Mini-Methods (MIMM).

Decomposition of programs into many small methods is a common programming idiom in object-oriented languages. The above considerations show how this decomposition can be motivated in terms of "object-oriented problem separation". But OOPS:MIMM raises a number of obvious questions:

A) Doesn't OOPS:MIMM just transform the problem of bloated and conglomerated methods into a problem of bloated and conglomerated classes?

In Lava we have several ways to avoid this, fortunately:

  1. In many cases it will suffice to hide those "lower-level detail methods" in the implementation of the respective class. Since Lava provides complete separation of class interfaces and class implementations, they are concealed then from the eyes of the interface users and cannot confuse them any longer.

  2. In other cases it may be justified to associate sub-problem solutions with completely separate object classes in order to adequately deal with these sub-problems. In some of these cases it may be natural to utilize Lava's support of nested declarations and to nest the corresponding class declarations within the primary class (interface) declaration.

  3. In a third group of cases it may be more natural to utilize Lava's support of multiple inheritance and to provide specific base classes of the primary class for dealing with lower-level sub-problems. These base classes would be viewed as "mix ins" or "ingredients" of the primary class.

B) Isn't it too cumbersome to create and manage many mini-methods?

In cases 2 and 3 above, where it is justified to provide separate classes associated with lower-level sub-problems, the programmer will accept the additional effort, since he/she is rewarded by an obviously improved since more transparent program structure.

The crucial issue with case 1 is that you have to jump from your executable code to a different place in order to declare a new method, and then back to the place in your executable code where you wanted to insert a reference to the new method. In LavaPE this nuisance is largely mitigated

C) What are "clearly identifiable sub-problems"?

This is largely a matter of taste and context. Sub-problems will always be "smaller" in some sense or other. There are some general considerations, nevertheless, that may suggest to factor out certain aspects of a program explicitly as sub-problems and to solve them in separate methods:

If you exploit all these possibilities of method / sub-problem factoring you will arrive at a class structure with mini-methods that are in this sense irreducible:

MIMM = Many Irreducible Mini-Methods.

The MIMM notion doesn't have a strictly formal definition but shall encourage the programmers to exploit all above-mentioned reduction possibilities to remove all lower-level details from all methods until each of them deals only with a single level of detail and is of minimum complexity.

Some more general recommendations may help to further improve the comprehensibility of programs:

D) Isn't it too inefficient to invoke many mini-methods instead of using inline code?

Lava is an interpreted programming language and optimization isn't one of our primary concerns at present. But principally we think that the overhead of mini-method invocations could be avoided in most cases by automatic inlining and automatic recognition of tail recursion by the Lava interpreter (or a future Lava compiler) which would then be replaced by an internal loop execution automatically.

Speaking of loops: The semantics of traditional loops in programming languages is heterogeneous: Partly they are an optimized way to express tail recursion, partly their semantics would be expressed in mathematical terms by quantifiers ranging over finite sets. In contrast to this, Lava prefers to abandon traditional loops, to explicitly provide quantifiers ranging over finite sets, and to use recursive functions where appropriate. This is another "built-in" measure in Lava, beyond the above-mentioned features, to promote the OOPS:MIMM programming discipline.

See also:

Spaghetti-like, tortellini-like and fractal program structures.