When a programmer understands every detail of a piece of code and their interrelationships to such a degree that there is no possibility of a bug in the code, the programmer is said to have the code under intellectual control. This is desirable.
However, full intellectual control is possible only for very short routines, on the order of 20 lines or less; anything longer has complicated enough interactions that it's beyond the ability of the typical programmer to be 100% sure of its correctness.
It is possible to extend intellectual control to big programs using abstraction: by breaking them up into a hierarchy of modules. If the top level of the program hierarchy can be proven correct, assuming that sublevels do certain things, then if those sublevels can be proven to do those things then the entire program can be proven correct.
If you're thinking that this is just the old idea of structured programming, you're right. However, note that nobody really uses fully structured programming; everyone allows a little slop to creep into their code. In today's "structured" code, many modules have side effects, and modules have sort of fuzzy definitions. Unless modules have absolutely no side effects, and unless the specifications for each module are rock-solid, the guarantee of intellectual control is lost.
The term "structured programming" has been misappropriated to such a degree that now a new approach, functional programming, is being touted to provide the same advantages. But under the surface all this talk is about a single idea: intellectual control.
There are several documents available on different aspects of the intellectual control development process:
- The ICL (intellectual control level) rating system.
- What a good spec is.
- How to do an quick review.
- How to do an inspection.
- Tutorial on writing specs.
- Practical high-ICL techniques.
Our form of IC is designed to increase overall productivity, rather than to give us zero bugs. The method is straightforward enough to be applied to all of one's coding at little extra cost (once the techniques are learned); then the productivity increase comes from the savings in debugging time.
Why We Want IC
It slowly dawns on programmers as they learn IC that it isn't extra work. The work done during IC produces real added value, unlike the much-feared "write a comment for every block of code" management directive. This is because IC specs describe the code in a different way than the code itself does. Specs tell the reader how the code may be used, rather than what the code does. A seemingly small philosophical-sounding point, but it makes all the difference.
The revelation behind IC is that it is possible after all to write a comment that truly says something new, useful, and different than the code itself does; it's just not obvious how it's done, so you have to learn the techniques involved.
It's an industry maxim that great programmers are 10 times more productive than average programmers; many have sought the reason behind this difference. A large team (which inevitably consists mainly of average programmers) can get the most improvement by raising the performance of the average by 2x, rather than by squeezing even more out of the few great programmers. The Holy Grail, the silver bullet to slay the software werewolf, would be some technique to raise average programmers to the productivity levels of great programmers.
IC is such a technique. Great programmers use IC naturally. This enables them to produce huge amounts of code without the whole thing collapsing of its own weight. They can comprehend an entire system of code because it's all organized and arranged neatly in their minds.
What great programmers do naturally, the average programmer can learn to do. Overall team productivity is best enhanced by teaching the team IC. Since no one applies IC 100% of the time naturally, there is room for improvement in the productivity of even very good programmers.
Some ideas for refinement of our vocabulary come from the references. The term typestate or flavor refers to those parts of an object's state that are usually recorded as far as its MSS. That is, the typestate of the object indicates which method sequences may be applied to it.
Further Vocabulary Proposals
The work on Larch/C++ is interesting in that a formal but code-like specification language is detailed. Some of its terms are requires for preconditions, ensures for postconditions, claims for redundant derivations from the pre and postconditions, and self for referring to 'this'. This last is helpful because the variable 'this' is easily confused with the word's english use when embedded in the prose of a specification.
S. Colwell, "Components For Software Development", March 1996.
M. Deck, "Cleanroom Software Engineering and "Old Code" -- Overcoming Process Improvement Barriers", to appear in 13th Annual Pacific Northwest Software Quality Conference, May 12, 1995. A more recent overview of the use of cleanroom techniques in the industry, with a real-code box structure example and a usable ascii spec notation, as well as a discussion of combining high-quality with legacy code.
D. Evans, Using Specifications to Check Source Code, thesis submitted in Dept. of EECS, MIT, June 1994. Describes LCLint, a Larch-based linter. The thesis is most interesting for its bibliography, which lists many other verification systems and associated specification languages.
G. Head, "Six-Sigma Software Using Cleanroom Software Engineering Techniques," HP Journal, Vol 45 No 3, June 1994. Has a small section on short-interval scheduling.
S. Kirani, et al. "Method sequence specification and verification of classes", JOOP, pp. 28-38, Oct 1994. The basis for our MSS syntax, with a further discussion of inheritance effects, automatic correctness verification, and control flow checking.
G. Leavens, "An Overview of Larch/C++: Behavioral Specifications for C++ Modules", TR96-01, Department of Computer Science, Iowa State University, Feb 26, 1996. Larch is a model-based specificatation language that's been adopted to many languages, this article describes the C++ effort. It uses pre- and post-conditions with a specialized ascii syntax. The goal of executability renders this less clear and less powerful than our approach's design for understandability by programmers.
R. Linger, "Cleanroom Process Model", IEEE Software, pp. 50-58, Mar 1994. A quick overview of the cleanroom approach, with a small example of stepwise decomposition of some code, and some statistics from actual use. Almost none of this pertains to our approach but it's relevant background for those interested in software quality.
D. Parnas, et al. "Precise Documentation of Well-Structured Programs", IEEE Trans on Software Eng., pp. 948-976, Vol 20 No 12, Dec 1994. A good description of the "display" technique for showing info needed for proving correctness of a piece of code. Also shows a tabular mathematical language for specifications, and discusses a real-life use of the techniques.
| || |
March 25, 1996: created.
April 10, 1996: modified.
Copyright © 1996,
All Rights Reserved