Home

SPECIFICATIONS

Of all the requirements that we might place on a program, first and foremost is that it be correct. In other words, it should give the correct Outputs for each possible input. This is what we mean when we say that a program "works," and it is often and truly said that "any program that works is better than any program that doesn't."
An example may serve to drive home this point to those whose minds are tangled in questions of efficiency and other secondary matters. A programmer was once called to Detroit to aid in the debugging of a new program-one that was to determine the parts requirements to build a certain set of automobiles. The input to the program was a deck of cards, each card representing a purchase order for an automobile, with different punches representing the different options selected by the customer. The program embodied the specifications relating the various options to the parts that would be needed. For instance, the choice of upholstery for the rear seat might be determined by such factors as body colour, body style, options for deluxe or leatherette upholstery, and whether or not the car was air conditioned. The air-conditioning Option is a good example of the basic complexity of the problem, for though to an untrained eye the choice of air conditioning might have no connection with, the choice of rear seat upholstery, it might very well require spaces for extra ducts. In general, then, each Option might have some effect on the-choice of parts made, so the determination of parts requirements was an excellent Job for the Computer.
Unfortunately, when this programmer arrived on the scene, the basic approach to the problem had long been settled-and settled badly. Each Option-as it affected each choice-was reflected as an individually programmed test and branch in the program. In a way, the program was an enormous tree, with more than 5000 branches, representing the decisions leading to part selection. Cast in this form-and with 16 programmers working at the same time-it was impossible to debug, as each and every case had to be tested separately. To test the program, a particular card would be put in and the Output would be observed. When our programmer arrived, things were so bad that typical cards were calling for the production of cars with eight tires, no engine, and three sets of upholstery. In short, a disaster.
As is usual with programming disasters, nobody recognised it as such. Instead, the whole crew had gone on double shift to get out the bugs, and new programmers, including our hero, were brought in from all over the country. Naturally, this led to worse confusion than ever, and our programmer, after a few days, determined that it was hopeless business- and in any case not reason enough to be away from his family and working night and day. He was roundly condemned for his uncooperative attitude but was allowed to leave.
While on the plane, he had his first opportunity in a week to reflect calmly. He immediately saw the error in the approach and perceived that a much better approach would be to divide the work into two phases. The main operational program would simply loop through a set of specially constructed specifications tables, so that all decisions would be made with a single test reapplied to different parts of the table. In that way, the program was at least assured to produce the right number of tires, engines, and so forth. The tables themselves would be compiled from input written in essentially the form of the engineering specifications. This would allow the engineering personnel, rather than the programmers, to check the specifications, and also permit one part of the specification to be changed without changing all parts further down a decision tree.
By the time he got off the plane, he had coded the two programs. It was a day's work to check them out, and another two days' work with the local assembly plant engineers to create the specifications in input form. After a week's testing in the plant, he was about to return to notify Detroit of the news when he got a telegram saying that the project had been cancelled-since the program was impossible to write.
After a quick call and a plane trip, he was back in Detroit with his version of the program. A demonstration to the executives convinced them that the project could continue, and then he was asked to make a Presentation to the rest of the programmers. Naturally, they were a rather cool audience-a phenomenon to which we shall return in our discussions -but they sat quietly enough through his explanation of the method. Even at the end, there was a lack of questioning-until the original creator of the old System raised his hand.
"And how long does your program take?" he asked-emphasising the possessive.
"That varies with the input," was the reply, "but on the average, about ten seconds per card." "Aha," was the triumphant reply. "But my program takes only one second per card."
The members of the audience-who had, after all, all contributed to the one-second version-seemed relieved. But our hero, who was rather young and naive, was not put down by this remark. Instead, he calmly observed, "But your program doesn't work. If the program doesn't have to work, I can write one that takes one millisecond per card-and that's faster than our card reader."
This observation-though it undoubtedly failed to win our hero any friends-contains the fundamental truth upon which all programming evaluation must be based. If a program doesn't work, measures of efficiency, of adaptability, or of cost of production have no meaning. Still, we be realistic and acknowledge that probably no perfect program was ever written. Every really large and significant program has "just one more bug." Thus, there are degrees of meeting specifications-of "working"- and evaluation of programs must take the type of imperfection into account.
Any Compiler, for example, is going to have at least "pathological" programs which it will not compile correctly. What is pathological, however, depends to some extent on your point of view. If it happens in your program. you hardly classify it as pathological, even though thousands of other users have never encountered the bug. The producer of the compiler-however, must make some evaluation of the errors on the basis of the number of users who encounter them and how much cost they incur. This not always done scientifically. Indeed, it often amounts to an evaluation of who shouts the loudest, or who writes to the highest executive; But whatever System is chosen, some bugs will remain, and some people will be unhappy with the same Compiler that satisfies thousands.
In effect, then, there is a difference between a program written for one user and a piece of "Software." When there are multiple users, there are multiple specifications. When there are multiple specifications, there are multiple definitions of when the program is working. In our discussions of programming practices, we are going to have to take into account the difference between programs developed for one user and programs developed for many. They will be evaluated differently, and they should be produced by different methods.

zurück zur Literaturliste

Home

18.7.2005 15:37