One of the anonymous reviewers of my OOPSLA paper made the point, paraphrasing, that the main problem in software development is not the difficulty of programming, but the difficulty of getting a development project to function effectively. This is usually seen as the subject of methodology, with â€œextremeâ€ and â€œagileâ€ methods being the latest trends. My initial reaction to this criticism was to point to the example of spreadsheets, which make a certain class of problems simple enough to be solved by an end-user or power-user themselves, without enduring the trials and tribulations of a professionally staffed development project. Even on such multi-person projects, reducing the programming effort ought to reduce the size of the team and the number of interactions subject to error. However the fundamental point of the criticism remains true: the biggest problem in software development is teamwork. It has occurred to me that the design philosophy of Subtext can contribute to solving this problem.
The real problem is that we still havenâ€™t figured out an effective way to divide the labor of software development. Economists since Adam Smith have pointed to the division of labor as the key to efficiency and progress. To divide labor, there must be commodities to exchange between specialists. A prominent example of such a commodity in software development is the specification: an informal description of system behavior, produced by analysts interviewing users, approved by those users, and consumed by the programmers.
Programmers in the real world will tell you that specs arenâ€™t worth the paper they are written on. They are half-baked informal descriptions that are too abstract to be understood by the users, and too imprecise to be useful to the programmers. They are full of internal inconsistencies and factual errors, because there is no way to test them. They are obsolete the day they are published, because it is too difficult to rewrite them as the system becomes better understood. Things are no better with the other standard commodities of development: project plans, schedules, cost estimates, and documentation.
Extreme Programming responds to this problem by eliminating the specs and docs and plans, along with the specialists who produce them. There are just users and programmers, collaborating intimately without formal plans. The sole commodity is code, which is the spec, and the doc, and the tests. There is much to recommend this approach, but it appears to work best with smaller projects. In Economic terms, it is still cottage industry. The fundamental scaling problem remains: we do not know how to divide up big software projects to allow teams to solve them effectively.
I propose a universal commodity of exchange in software projects; a common currency of development: examples. Specifically, examples as executable artifacts integrated into the programming language (as in Subtext), or at least into the IDE (as in EG). The key properties of examples are that:
- They can visually demonstrate system behaviors of concern to the users.
- They can be built without coding by analysts or power-users.
- They can test code, asserting that certain inputs lead to certain outputs.
Examples essentially formalize use cases, which have proven to be an effective communication medium between users, designers, and implementers. By turning use cases into concrete examples, users gain realistic demos, designers gain automated tools, and implementers gain both a clear specification as well as a test suite. Managers gain the ability to plan and observe work by the satisfaction of examples; implementers can more reliably estimate the work required to satisfy concrete examples. Documenters can base much of their content on the examples. Everyone benefits from keeping the examples in sync with the code, which is required because they are used as tests. Development becomes more efficient because examples help everyone collaborate.
I see two major hurdles to be overcome for examples to function as the common currency of software development. The first hurdle is that although they are formal artifacts, examples must retain the informality and flexibility of use case techniques. Overcoming this hurdle is partly a matter of good usability-engineering, but may also depend on a simple yet general framework for expressing examples that can be adapted to specific application domains. This is a goal of Subtext, but I see no fundamental reason why it canâ€™t also be done in conventional IDEâ€™s like Eclipse, given sufficient resources.
The second hurdle is more fundamental: can examples truly replace specifications? Examples concretely describe only a finite subset of behaviors, while specifications can abstractly describe infinite sets of behaviors. Formal specifications, written in some machine-analyzable logic, are clearly superior to examples. But formal specification has been one of the great disappointments of software engineering. The dirty little secret is that writing a complete formal spec of a system can be as difficult and error-prone as implementing it in code. In practice, we rely on informal specifications. My conjecture is that formal examples are better than informal specifications.
I claim that in most cases, a well-chosen set of concrete examples can more effectively communicate an intended abstract behavior than an explicit but informal abstract description. People are quite adept at inferring abstractions from examples, but notoriously poor at understanding and constructing abstractions explicitly. This is one reason that use cases are so successful. But unlike informal specs, examples can actually test whether code satisfies them: they are â€œspecs with teethâ€. By serving as tests, examples are forced to evolve with the code, avoiding the rapid obsolescence of specs.
We are still free to mix informal specifications with formal examples. Informal commentary on examples could be quite helpful in conveying their intention. The key is to treat such commentary as just that: explanatory comments without proscriptive power. To actually require or disallow some behavior, a concrete example should be formulated that isolates that case. Once we no longer expect specifications to be complete, we are also freed to use lightweight formal techniques that are incomplete, such as Alloy. Alloy has the singular ability to both find and check models of a specification, within finite bounds. This capability could be used to concisely specify large (but still finite) sets of examples, generating their input states and asserting their outputs.
In summary, I am proposing that formal examples can serve as a common currency for software development. They support collaboration between users, designers, programmers, managers, testers, and documenters. Examples are a unit of exchange that allows the effective division of labor, making us more efficient and enabling us to do bigger things.