August 17, 2015

Why Most Unit Testing is Waste (Into Modern Times)

  —A call to action for more intelligent unit testing.

In “Why Most Unit Testing is Waste (An Exploration)” I summarize how Coplien views an explicit calling structure (or context) for the objects (and methods) as critical to enabling reasoning about the execution of a program. Here, I take an in-depth look at the article’s introduction.

What piques my interest in the introduction to “Why Most Unit Test is Waste” are statements comparing the difficulty of reasoning about programs written in FORTRAN to an object-oriented programming language. Understanding this is critical to understanding the motivation behind Coplien’s arguments on waste.

The object-oriented programming language Coplien refers too isn’t named. I selected C++. Java is an equally good choice.

It turns out that FORTRAN, C++ and Java all support polymorphism. In fact, all three languages support static (early) binding and dynamic dispatch. Static binding ensures that compilation fixes the binding of names. Dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time.

FORTRAN introduced polymorphic types in FORTRAN 2003. A review of FORTRAN 2008, J3/10-007r1, states that the class type specifier is used to declare polymorphic entities. A polymorphic entity is a data entity that is able to be of differing dynamic types during program execution.

A review of “Programming Languages — C++” and “The Java® Language Specification Java SE 8 Edition”, shows that both support static binding and dynamic dispatch.

The C++ standard states that virtual functions provide the mechanism for dynamic binding and object-oriented programming. A class that declares or inherits a virtual function is called a polymorphic class.

The Java standard that instance methods provide the mechanism for dynamic dispatch. A method which is not declared static is an instance method.  An instance method is also called a non-static method. In “The Java® Virtual Machine Specification Java SE8 Edition”, instance method is likened to virtual methods in C++.

If FORTRAN, C++ and Java all use dynamic dispatch what is Coplien’s thesis regarding reasoning about FORTRAN and object-oriented programs?

Some thoughts:
  • my analysis of FORTRAN, C++ or Java is incorrect.
  • Coplien’s discussion relies on a version of FORTRAN that predates the introduction of polymorphism.
If my analysis is incorrect then this article is done. If Coplien’s thesis relies on an outdated version of FORTRAN then it is worthwhile understanding how (if) this affects the conclusions.

I’ll assume that my analysis is correct and Coplien refers to an outdated version of FORTRAN for purposes of supporting his thesis. Reliance upon an old version of FORTRAN is in line with the article’s introduction, which makes FORTRAN sound ancient.

Relying on an outdated version of FORTRAN requires that it not support polymorphism. FORTRAN 95 does not support polymorphism. FORTRAN 95 is an official standard and no public previews are available. (FORTRAN 77 introduced ad-hoc polymorphism for operators and I’ll ignore this. [Wikipedia])

Assuming an outdated version of FORTRAN, then all three programming languages support early binding. C++ and Java support dynamic dispatch. FORTRAN does not. There is no need to examine early binding as it is common to all three languages.

Dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time. It contrasts with static dispatch in which the implementation of a polymorphic operation is selected at compile-time. Its purpose is to support cases where the appropriate implementation of a polymorphic operation can't be determined at compile time because it depends on the runtime type of one or more actual parameters to the operation. [Wikipedia]

In effect, you can’t reason about an object-oriented program without executing them because the behaviour of the program isn’t known until runtime. It isn’t known because the runtime type of one or more method parameters isn’t known until runtime.

FORTRAN is over-simplified in this article. Current implementations of FORTRAN support polymorphism and use dynamic dispatch to do so. This has no bearing on the position that object-oriented programs need to be executed in order to obtain an explicit calling sequence (or context) but it does clear up my confusion regarding the comments on FORTRAN—they illustrate the differences between a procedural and an object-oriented programming language.

My focus on polymorphism may also miss the point. The point may be that inheritance is a key differentiator over procedural programming languages and a key contributor to the complexity of testing object-oriented programs. Inheritance may be a better focus as polymorphism is required to enable it.


comments powered by Disqus