The vast majority of practical programming languages used by programmers today are imperative (meaning that, for the most part, computations can have arbitrary side-effects and are not isolated). As a consequence, compilers are inhibited from applying optimizations that can achieve the best performance in the newest hardware. For example, a compiler may be inhibited from reordering operations, or arranging for pipelined or parallel execution when multiple processors are available since such rearrangement is invalid in the presence of arbitrary side-effects.
Many such programming languages are also object oriented (OO). A consequence of object orientation is that a call/return sequence (method call) executed at a particular program point can potentially invoke one of many different code bodies (methods) with different characteristics, making it even more difficult to determine what side-effects might occur.
There is a good reason why imperative OO languages are overwhelmingly more popular than functional and dataflow languages: many things that programs need to do are inherently imperative (side-effecting) and it is often difficult or even impossible to express an entire application in a strictly functional style. However, with such programming languages, it is difficult or impossible to express that portions of a program are intended to be side-effect free. Thus, there is no way for the programmer to cooperate with the compiler to achieve parallel or pipelined execution.
With current state of the art, classifying of methods into those that are pure functions, those that are stateful but isolated (receiving new information only as arguments and providing results only as return values), and those that have arbitrary side-effects is difficult and may be inefficient. For example, to do this directly (for instance, by adding a “pure” and or “isolated” keyword to the language) would lead to complicated and non-modular method checking. All of the method actions would need to be analyzed in context (i.e., what is it doing and what object is it doing it to). To ensure that a method is stateful but isolated is similarly difficult since one must enable one large class of accesses while disabling another large class which will break isolation.