# The Psychology of Computer Programming — Chapter-07: Variations in the Programming Task - **Source**: /library/The Psychology of Computer Programming/source-file.pdf - **PDF pages**: 169–190 - **Pages without text**: none - **Note**: Includes the Silver Anniversary comments that immediately follow the original chapter. Text comes from the scan's OCR layer and may contain recognition errors. --- VARIATIONS IN THE PROGRAMMING TASK dling around with a BASIC terminal is programming, but so is an engineer trying to produce the tightest possible mi- croprogram for a special-purpose on-line computer. Is there anything in common between these two activities besides their name? The programming literature usually assumes that there is something in common between the activities of the high-school student and the engineer, and this assumption is probably correct, as far as it goes. But perhaps much of the difficulty in trying to account for differences in programming performance arises from a lack of refinement in our classi- fication of the activities called programming. After all, we could create a theory of economic activity by flying over the United States at 5000 meters, but we couldn’t say much more than that ‘‘everybody is driving around 121 tT | rogramming’—like ‘‘loving’—is a single word that encom- = an infinitude of activities. A high school student fid- 122 Programming as an Individual Activity in all directions.” To account for more details of behavior, we would have to get closer to the ground, and this is what we shall have to do if we want to remove some of the mystery from programming. PROFESSIONAL VERSUS AMATEUR PROGRAMMING The high school student and the engineer represent two ends of a rich spectrum of programmers. These ends may or may not be differ- ent, but nothing antagonizes the professional programmer more than to hear an amateur—having just completed a six-statement program in BASIC to find roots of a quadratic equation—discourse on the theory and practice of programming. We know well, of course, that this vehe- mence could be a symptom of /ack of any difference between the two activities, for such a lack would put the professional in a much dimin- ished stature. Although some professional programmers may indeed be no more than hacks camouflaged by esoteric obscurities and some amateurs might be able to gain a deep appreciation of programming through the writing of a single short program, there /s a difference. Perhaps the deepest differences emanate from differences in the ul- timate user of the program. Almost invariably, the sole intended user of an amateur’s program is the amateur himself, whereas the professional is writing programs which other people will use. To be sure, the pro- fessional oftentimes finds himself writing a program for his own use— to generate test data or to evaluate the performance of an untried al- gorithm, to name but two instances. And, indeed, when doing this kind of work, the professional commonly slips into amateurish practices. But the main thrust of his work is directed toward use of the program by other people, and this simple fact conditions his work in a number of ways. Because the amateur will be the user of his own program, he has the choice of doing his thinking either before or after programming. Consider, for example, a student who wants to write a program to find roots of quadratic equations. Ideally, he is sitting at a terminal, for terminals are well suited to post-programming thought. He decides that he will probably need some input. This requires that he choose some names for variables. Here the small size of the program and its complete isolation from other programs give him a big boost—without his awareness, of course—for he may choose whatever names first come to mind, such as a, b, and c. In simply following the notation of high school algebra, he does not think at all about possible conflicts with other symbols, standards which must be observed, or even with declaration of attributes. No, he merely Variations in the Programming Task 123 types something like GET LIST (A, B, C); After adding some other program parts in a similar way, he will be ready to try his program. Upon initiation of processing, the terminal will pause in request for data. Since it is his own program, he does not need any prompting about what data are expected at this time, so he has saved at least such coding as a preliminary PUT LIST (‘ENTER A, B, AND C’); He also knows the order in which things are required, and the simplified input system of his language permits him to enter his data in such diverse forms as 123 1,2,3 1,2,3 1.0, 2.0, 3.0 1E0, 2.0E+0, .3E+1 Moreover, if he should happen to slip and enter 1A, 2,3 the system will reject the first value without his having had to program an error-handling routine or document the reasons why such a data item is rejected. He knows what is expected, for he wrote the program. Even more subtle problems can be handled for him because he can think after programming. When he enters such a case as 1, 2, 3, he will probably find that some later statement coughs up the data because he will be trying to take a square root of a negative number (b? - 4ac). He gets the diagnostic automatically—without any forethought or foreprogramming —and probably realizes rather quickly what the problem is. He may then simply decide that he doesn’t want complex roots anyway, in which case the problem disappears by definition. Only when the programmer himself is defining the problem is this sort of simplification possible, for the professional programmer would at least have had to leave the terminal and find someone to authorize a change or clarification of specifications. If the amateur does decide that he needs complex roots, his task is still much simpler than that of the professional in making the necessary modifications. Even when he has finished the program, his job remains simpler, for when he is finished, he merely has to forget about it. The professional, on the other hand, has to put it into a neat package and send it out into the cold world—from which it may return to him bearing caustic comments, comments whose sense has to be considered for subsequent modifications. A true professional, of course, would have con- structed the program in such a way that modifications will not be overly involved—but that was another thing he had to think about when writing. Even if the program is not intended for other eyes at all, the profes- 124 Programming as an Individual Activity sional cannot quite forget about it in the same way as the amateur. For instance, if the program is just stored in the terminal system, the user will eventually receive notification to clean up his storage. The pro- fessional has to recall each of the programs in his library, for some will still be needed. The amateur, however, probably has only one program, so he instructs the system to erase it—or lets the erasure be done auto- matically by default. But woebetide the professional who lets the system erase his library! No, he must drop what he is doing and check his long library list before the deadline comes around, or all his work will be gone with the wind. Many years ago, when programming systems were rudimentary, the difference between the professional and amateur was not nearly so pro- nounced. Today, however, so many of the things that amateurs want to do have been made implicit in our systems that the gulf is a wide—and widening—one. Paradoxically, however, as the gulf has widened, the amateurs have become less and less aware of it, for they have become less and less aware of what the system is doing for them. Just as a good manager faces the problem that his employees are unaware of his man- agement, so does the systems designer suffer because the better his sys- tem does its job, the less its users know of its existence. And speaking of managers, they can be the most amateur of amateurs when it comes to programming. A few years ago, one firm decided to try to give its executives a course that would make them appreciate the prob- lems of their professional programmers. Inasmuch as these were execu- tives, each was assigned a professional programmer as ‘‘assistant” for the duration of the course, the climax of which was a problem which each executive had to program “for himself.’’ To enhance the executives’ appreciation for the problems faced by programmers, this work session was interrupted by frequent trivial phone calls, meetings, and small changes in specifications. The executives got the point—that executives could increase programmer productivity by “sheltering” their staff rather than being the major source of disturbance. But they also took away another—deeper rooted—idea. After all, in spite of all these disturbances, they had managed to get their program working, hadn’t they? Sure, they had a little help from their ‘‘assistants,”’ but not much, really. So, if they could get a program done on time, why couldn’t their programmers? And what was so hard about programming, anyway, if they could master it in a week? This entire impression was based on a combination of illusions of the same sort that make any amateur unable to appreciate the abyss which separates him from the professional. First, there was the semantic illusion which equates the “program” they wrote—a trivial problem involving Variations in the Programming Task 125 compound interest calculation which could have been better solved using a log table or slide rule—with the “programs” written by their staff— operating systems, compilers, utilities, and the like. Second, there was the illusion that their assistants were ‘“‘not helping them much’’—an illusion based on a lack of understanding of the complexities of programming— the very complexities which the assistants were supposed to shield them from lest they take away a bad feeling about programming engendered by being unable to complete their little problem. And so, the very efforts directed at giving the executives a better appreciation for the problems of the programmer resulted in precisely the opposite effect. Better appreciation of programming by managers is needed: a case in point is the fact that a manager could even begin to believe that he could learn in a week what the professional has learned through years of ex- perience. Indeed, it is a homily that the difference between the profes- sional and the amateur programmer lies in the superior past experience of the professional. But one could also contend that an equally important difference lies not in the programs each has previously written, but in those he will write in the future. The amateur, being committed to the results of the particular program for his own purposes, is looking for a way to get the job done. If he runs into difficulty, all he wants is to sur- mount it—the manner of doing so is of little consequence. Not so, how- ever, for the professional. He may well be aware of numerous ways of circumnavigating the problem at hand. He may even employ one of them for the immediate purpose of getting the job done. But his work does not stop there; it begins there. It begins because he must understand why he did not understand, in order that he may prepare himself for the pro- grams he may someday write which will require that understanding. The amateur, then, is learning about his problem, and any learning about programming he does may be a nice frill or may be a nasty im- pediment to him. The professional, conversely, is learning about his profession—programming—and the problem being programmed is only one incidental step in his process of development. The other side of this observation is that the professional never quite takes any problem as seriously as does the amateur. He has had bugs before, and he will have them again. This difference in attitude is a source of constant friction between the two types: the professional is very tired and a bit irritated by the unending stream of amateurs waving their print- outs in his face and condemning the machine, the operator, the system, the keypuncher, the language, or the government. The amateur, on the other hand, can see that the professional does not even care that his means and standard deviations are not going to be ready in time for inclusion in the proceedings of the conference. 126 Programming as an Individual Activity WHAT THE PROGRAMMER IS TRYING TO DO There is an asymmetry in the relationship between amateur and pro- fessional programmers, because the one cannot appreciate the com- plexities that the other faces. Nonetheless, the professional often commits the error of deriding the work of the amateur for not being sufficiently professional; and this error is much less excusable than that made by the amateur in underestimating the distance between himself and the pro- fessional. The professional, if he is truly professional, should know better, whereas the amateur cannot. The amateur may fail to program an elaborate error-handling routine because he doesn’t know how or doesn't even know what an error-handling routine is. But then, why should he know, if he doesn’t need one? Isn’t it much worse for the professional to insist on treating a tiny one-time program for personal use as if it were an operating system intended to be used by thousands of people for five or ten years? Programs, like any other man-made objects, are designed—or should be designed—with a definite lifespan and scope of application in mind. Like the “Deacon’s Masterpiece,” which was “built in such a logical way it ran a hundred years to the day,” a program should have neither over- designed or underdesigned parts. Yet it is an occupational disease of programmers to spend more time on those program parts that present, for some reason, the most intellectual challenge rather than on those that require the most work. A case in point is the semi-professional programmer who was com- missioned by a physics professor to write a program to find the inverses of some matrices. As there were too many matrices to keep in storage at once, he needed a routine for reading them from tape one at a time for processing. He had little experience with input-output programming, so he decided that this would be a good chance to learn something, and he set out to get some advice. “How can | program the input from tape so as to buffer the input from processing?” he asked a somewhat more professional colleague. Being somewhat more professional, the colleague didn’t answer the question, but put one of his own. “Why do you want to buffer the input?” “To save time, of course.” “Have you estimated how much time you will save?” “Not exactly, but it will be a lot, because there are a lot of matrices.” “How many?” “| don’t know exactly. A lot.” Variations in the Programming Task 127 “Approximately how many?” “Maybe a hundred.”’ “Good. And how Jarge are they?” “Ten by ten.” The colleague did a quick calculation on the blackboard which showed that these matrices would require about one minute to read. “See,’’ said the semi-pro, in triumph. “That’s a lot of time.” “Perhaps—or perhaps not. How many times will you run this program?” ‘What do you mean?” “| mean, if you write a buffering routine, you’re going to have to test it, and | doubt if you can do that with less than one minute of machine time. So if you only have one set of matrices, I’d advise you to forget it. Just the computer time in testing will cost more than you could possibly save—not to speak of your time.’’ “But you don’t understand,” said the semi-pro, who was not willing to see his chance of writing a new and interesting program slip away. ‘This has got to be an efficient program!” His colleague should have been discouraged by this response, but could not stop himself from trying to rephrase the arguments. But, alas, it was all in vain, and the next time he chanced to see his friend—which was the next semester—he was still having problems getting his buffering routines working. The poor physics professor, still waiting for his matrices, was completely unaware of what was going on—but was mildly flattered that his programming problem had proved so complex. The moral of this tale—and a hundred others like it—is that each program has an appropriate level of care and sophistication dependent on the uses to which it will be put. Working above that level is, a way, even less professional than working below it. If we are to know whether an individual programmer is doing a good job, we shall have to know whether or not he is working on the proper level for his problem. The same talents or personality that make a person an excellent amateur programmer may make him singularly unsuited for being a professional one; but the lack of ability to adjust his working behavior to the problem at hand will always make him unsuited. Usually, though, the programmer fails to adjust his activities to the problem at hand because he does not know what the problem at hand is. That is, he assumes that certain things are wanted—perhaps on the basis of what he knows how to do, or on the basis of what was wanted in the last job he programmed—but he never finds out what was wanted until the job is finished. Working for buffering is not a bad thing in itself, but only in terms of what a particular program is going to be used for. If the matrices were 100 by 100, and if there were going to be thousands of them, the goat of our last tale could have been a hero. 128 Programming as an Individual Activity There have been very few studies of programming performance, but what few there have been all seem to have suffered from a lack of appre- ciation for the problem of ambiguous programming objectives. It is not enough to give a carefully selected bunch of programmers the same problem to work on and then measure their ‘‘performance.” Any psychol- ogist knows that subjects must be given explicit instructions on what they are to try to achieve, and that even that is not enough in most cases. For instance, if we are given a list of words to match with their synonyms, are we supposed to work for speed or for accuracy? And if the psychologist tells us to be as fast as we can, do we really follow that instruction at the risk of making truly careless errors? Well, that depends on a number of factors—because some people are inherently more meticulous than others. Psychologists lose many nights of sleep over such questions, and perhaps programmers and their managers should share a bit of that concern. In order to test for the influence of assumed goals on programming performance, we conducted a small experiment. Four programmers were asked to work on the same problem—a nontrivial one which would take perhaps one-fifth of their time for ten weeks. Although the problem specifications were otherwise as identical as a Xerox machine could make them, two of the programmers were given a last page which differed from the last page given to the other two. For one pair, the last page read as follows: Your objective on this project should be to get a fully debugged program which is as efficient as possible, in the sense of using the least CPU time possible. You may use as much core storage as needed, up to 128K. Although you are not working for fast completion of the project, you should plan to reach the final test level by the end of the ninth week. For the other pair, the last page read as follows: Your objective on this project should be to get a fully debugged program in as short a time as possible without considering the efficiency in speed or space of the program insofar as those factors will slow down the completion of the program. However, you should not spend any more time on the project than the normal work load allotted (one-fifth time). You must, however, keep the pro- gram size less than 128K. By making the instructions explicit, we hoped to measure the type of variation attributable to different understandings of the objectives of the Variations in the Programming Task 129 project. None of the programmers knew that the others were working toward different objectives. At the end of the project, however, the differ- ence in performance between the pairs was striking. Those who were asked to complete the program as quickly as possible used, on the aver- age, only two-fifths of the machine time and one-third of the individual time used by the other group. Their finished programs, on the other hand, were, on the average, about ten times slower! (See Figure 7-1, ‘Index Problem.’’) This experiment was repeated with another group of programmers and a different type of program, but one designed to be about equally com- plex. Here the possibilities for spectacular savings were not so great, but again the ‘‘fast-completion” group averaged two-fifths the machine time and one-third the individual time used by the other group. The “‘efficiency”’ group, in this case, achieved about 50 percent more speed in their pro- grams. (See Figure 7-1, ‘File Problem.’’) This pair of experiments gives a nice contrast, for it shows that the gains to be had from striving for efficiency depend on the type of problem as much as anything else. Thus, we could never make a general statement about how much effort toward efficiency is justified, even if we were equally interested in efficiency on all problems. But the important result from the experiments is that a large proportion of the variance between Figure 7-1 Effect of environment on performance. 130 Programming as an Individual Activity programmers on any job can be attributed to a different conception of what is to be done. When we investigated in more detail the source of added machine time and programmer time for the “efficiency” groups, we found that much of it could be accounted for in the way the programmers reacted to unan- ticipated difficulties. In the ‘‘fast-completion” group, when some method was not working out, it was simply dropped and another one was sub- stituted; but when the “efficiency’’ programmers had trouble, they were loath to change their approach because they would then have to sacrifice some efficiency. Thus, though two programmers in different groups might have started out with the same method in mind, the ‘‘fast-completion” programmer wound up with something rather different—but he did finish while the other was still struggling. It is also important to notice that the source of the difficulty is more or less irrelevant to this result. In one case, for instance, a compiler bug caused trouble with a feature that was critical to one of the possible approaches to a problem. Although both groups encountered the same bug and neither could do anything about it, the “‘fast-completion” group dropped the approach long before they ever found out that it was a com- piler bug, and the others stuck with it until the bitter end, only to have to drop it when the source of the difficulty was uncovered. Although this turn of events may have been “unfair” to this group, it was nothing that does not happen thousands of times a day in computing centers all over the world. From a psychological point of view, the lesson is clear. The same objective event (a compiler bug, a difficult algorithm, or what-have- you) affects a project in different ways according to the objectives—even though they be unstated—of the project. Therefore, if we are to measure programmer performance, or language performance, or operating system performance, or anything else, we must be sure that everybody is truly working on the same problem. In real life, of course, we do not usually have more than one group working on “‘the same’”’ program at a time. Thus, we may not be aware that the group is working toward a different set of objectives than, say, their manager thinks they have. Consequently, unless we take precautions to see that a// the objectives are communicated—and remain communicated —we should not be surprised when the program does not meet schedules or runs inefficiently, or uses too much storage, or what-have-you. But let’s back off a moment, for “real life’ is never so simple. There is a certain danger in communicating objectives: objectives can change estimates! In our experiment, after we had found the effect of instructions on performance, we went back and checked the estimates given by each programmer. The programmers had estimated number of batch runs and number of elapsed days to complete each project, and the comparison of Variations in the Programming Task 131 \ Figure 7-2 Effect of environment on estimating. their actual and estimated runs and days is shown in Figure 7-2. It is easy to see what happened. Those who were instructed to finish as fast as possible were motivated to be far more conservative in their estimates of time to completion, and they actually performed much better than their estimates and much better than the other group—even though the other group had been much more optimistic in their estimating. One interesting sidelight is that there was one person who absolutely refused to make a time estimate, and he was in the group asked to do the job as quickly as possible. He was also the only one who got appendicitis in the middle of the project (though fortunately he was a fifth person in that group). Programming managers should take a long, hard look at this figure before they set down the goals for their next project. If a goal is set explicitly, there are two effects: programmers work toward that goal at the possible expense of another goal, and programmers will be far more conservative (or accurate) in estimating how well they will meet the goal. Estimates on goals not emphasized will probably be completely unreliable, both because they are not made carefully and because they are not im- portant enough to resist being sacrificed to other goals. Unfortunately, 132 Programming as an Individual Activity this modification of estimates was not anticipated by the experimenters, so we neglected to ask the programmers to estimate the efficiency of their programs, but it seems reasonable that the same type of result would have obtained—but reversed for the two groups. Should this result prove general, it would clarify somewhat the mys- teries of Parkinson’s Law and might thereby relieve the nightmares of numerous managers. When Parkinson said that “work expands to fill the time allotted,” he was making us aware that the very existence of schedule goals can influence the rate of work. But now we see that the very existence of schedule as a goa/ can influence “the time allotted.” The reason work can expand to fill the time allotted is the existence of other goals whose importance relative to scheduling is not made clear. Perhaps we might follow this line of reasoning and begin to under- stand what fallacies underlie the generally accepted conclusion that programming projects can never be done on time. STAGES OF PROGRAMMING WORK Another fallacy which we shall have to lay to rest is that “program- ming” is some sort of uniform effort requiring a set of uniform talents. For the professional, at least, the job of getting from specifications to delivered program demands various kinds of work, which, in turn, de- mand various talents. In a properly organized project, not every programmer need have all of the talents required to produce complete programs, since work may be allocated according to individual abilities. Indeed, it may be that suit- ability for work in one stage of programming makes one more or less unsuited for work in another. The job of system design calls for an eye which never loses sight of the forest, whereas the job of debugging may require that every tree—even every branch or leaf—be seen with utmost clarity. The job of coding often requires squeezing out every drop of redundancy, and the job of documentation may require that simple sen- tences be plumped up to paragraph size. Just as a successful programmer may become a failure when moved into a management position, so may a successful designer become a handicap when the time comes to debug a system. On the other hand, the man who might have helped us most in debugging may have been pushed out of the project during the design phase because his peculiar ~ talents were neither needed nor appreciated at that time. If we are to ensure that the proper talents are available when needed, we shall have to classify the work that programmers do into somewhat more refined categories than the simple term “programming” covers. Programming is often described as a process moving from problem Variations in the Programming Task 133 definition through analysis to flow diagramming, then coding, followed by testing, and finishing with documentation. Although this rough view contains some truth, it distorts the truth in several ways. First of all, the actual sequence is not so fixed, because, for example, documentation may precede testing, coding, flow diagramming, and even analysis. Secondly, not all steps need be present, as when we are recoding a program for a new machine or language. Thirdly, it need not be a sequence at all—and, in actual practice, rarely is. Who has not experienced a problem definition that changes as discoveries are made in analysis, flow diagramming, cod- ing, testing, and documentation? Or who has ever seen a flow diagram that remains unmodified throughout the coding—or code that remains unmodified throughout testing? If we are to study programming from a psychological point of view, we must decompose these complex activities into simpler ones—that we have established. And yet, because of the cyclic, or iterative, nature of the programming process, even such a decomposition as we have made above is too refined. These divisions lack sharp boundaries, or perhaps have no boundaries at all. To be sure, if we ask a programmer what he is doing, he will say ‘‘coding’” or ‘debugging’ without any hesitation. Moreover, the system of “progress reporting,’’ which is in effect in most installations, tends to force people to put their work in sharper categories than really exist. In this way, people are led to believe in the reality of the categories they write on their time sheets each week. To take a specific example, consider a project which has a set date when each of the activities will be completed. As the date for problem definition approaches, great haste is evident in the preparation of “prob- lem definitions.” At the required date, all the definitions are in the hands of the project manager—but that does not mean that the project is de- fined. All it means is that the definitions are in the hands of the project manager. Now that definition is formally finished, analysis starts. If, perhaps be- cause of the hasty definition process, some flaw is discovered in the definition at this point, one of two things will happen. First—and worst— the flaw may be covered up, under the belief that the definition is now fixed. Second, the definition may be changed—probably informally in most cases, but with the time and effort required being charged against “analysis.” And so the project goes on, from category to category without ever a backward step—or so it seems to the project manager. His model of how a programming project is done has been superimposed on the project itself, and he never becomes aware that things are not so simple. It all makes for a very neat accounting system, but it will never do for an understanding of the psychological processes underlying success or failure of the project. Even if it really were possible to force a programming project into 134 Programming as an Individual Activity sharply defined stages, it might not be a good idea to do so. The pro- grammers on a project constitute mixed talents, some of which are better suited for one type of work than another. If only one type of work is being done at a time, certain talents are going to be underexploited at that moment. Moreover, even for the individual programmer working alone, it may be a good idea deliberately to break up the work so that different parts are in different stages at any one time. Why? Because the progress of the work is likely to be more uniform and less dependent on day-to- day variations in the programming environment or in the programmer's own temperament. Consider, for example, the idea that not every day is a good one for coding. If we are coding and become aware that we are muddling about— taking four steps backward for each three forward—it would be a good idea to put aside the coding for some other activity requiring a different set of skills and perhaps a different frame of mind, such as documenta- tion. But if the only work being done at the moment is coding, there is no escape from coding except by escape from the program altogether. Since we can seldom afford to drop work altogether—or at least to be seen dropping work altogether—we would then have to try coding anyway, in spite of our best knowledge of ourselves. The external environment also varies from day to day. If, for instance, the computer is down for installation of some new equipment or for fixing some hardware bug, machine testing must cease altogether. If all that is going on at the moment is machine testing, then progress grinds to a frustrating halt. If there are a number of phases in progress at once, we merely turn to some other activity. Another consequence of “lock-step” programming is that, at any given moment, certain facilities are likely to be overloaded at the same time that others are lying fallow. Program testing makes the biggest demands on machine time, and if everyone is testing at the same time, the ma- chine may be overloaded. Documentation puts a big load on the secre- tarial staff: the same secretaries who were idly waiting for work while the machine was overloaded with testing runs now find themselves swamped with typing and such as everyone starts to document at the same time. And because certain people in the project are specialists in certain phases of programming, they, too, are alternately idle and swamped. The ideal project design, then, would avoid having all its parts in the same stage of programming at the same time. However, if one were to believe typical management texts, one would get precisely the opposite impression. What saves us, more often than not, is the lack of true boundaries between these stages, so that a little debugging is already going on during problem definition and a little problem definition is still Variations in the Programming Task 135 going on during debugging. The same kind of ‘‘smearing” is done by the good programmer—whether consciously or unconsciously—so that when he runs into an obstacle in one area of activity he switches to another. Indeed, one mark of a poor programmer is that he can be found sitting around doing nothing whenever there is machine trouble and he cannot get his programs run. If he can’t do the one thing scheduled for today, he is lost. Of course, not everybody is equally good at all things, and we like to work on the things we do best. The widespread inability to write plain English, for instance, no doubt explains why documentation is a universal festering sore. Even when there is nothing else to do, doing documenta- tion is never a voluntary alternative. We can try to arrange the work of our project so that each person specializes in what he does best, but this approach has at least two drawbacks. First of all, we probably will find nobody to do the documentation work; and, second, nobody will learn very much. We can, on the other hand, maximize the rate of learning by assigning each programmer to be a specialist in that part of the work he does /east well. In this way, also, we can ensure that each one will jump at the op- portunity to switch to some other task when he runs into a snag. The multiplicity of different types of work under the rubric of “pro- gramming” also accounts for a certain exaggeration in psychological studies of programming. If we test for performance on a small program- ming project, the results are likely to be daminated by performance on one phase of the work. For instance, in a problem which emphasizes painstaking attention to detail, certain programmers will show a marked superiority to others. The situation might reverse itself if the problem posed required the ability to sit back and take the broad view of things; therefore we could well have two studies which showed thirty-to-one differences in performance. When we put these same programmers on a somewhat larger prob- lem, however, we may see these extreme differences reduced, for each type of programmer now finds some parts that are suited to him and some parts that are not. With larger problems then—such as we reported in the previous section—we will more likely find differences of two- or three-to-one. Even these differences, moreover, are no longer attributable to differences among the programmers, but to cer- tain external factors, in many cases. Not that the programmers do not differ, but simply that these differences average out over a project that requires all sorts of attitudes and skills. All the same, there is a certain truth in the thirty-to-one ratio, if we but knew how to exploit it. This ratio is probably representative of the differences in ability among programmers—in different stages of program- 136 Programming as an Individual Activity ming work. Thus, a project that can divide the effort not into programs but into types of work might realize gains in productivity of this magnitude. Notice that this is precisely what happens when egoless programming is practiced; and as long as programmers “own” programs rather than, possibly, “owning” programming stages, we are not going to realize these potential gains. With this argument, then, we come the full circle, back to the attempt to isolate the truly different kinds of activity that programmers do. Even acknowledging the fuzzy boundaries between the classical divisions, we will be able to do some fruitful subdividing as we go along. For example, consider the testing stage. We can immediately isolate at least three different activities (from a psychological point of view), which are lumped under this single title: 1. Detecting the presence of errors. 2. Locating errors which are known to exist. 3. Correcting errors that have been found. In a very broad way, we can see that these three activities could require different combinations of skills and personality traits. To detect errors, the programmer must have a conniving mind, one that delights in uncover- ing flaws where beauty and perfection were once thought to lie. Perhaps a touch of paranoia helps—the kind of thinking that automatically con- jures up the worst imaginable case. For locating errors, however, we want a person who has the persistence of a mother-in-law and the collecting instincts of a pack rat. In one pro- ject, for instance, a bug in the operating system was known to exist for six months before it was finally tracked down by one programmer who had saved every dump taken in that period—three nine-foot stacks of paper! Late at night he could be found poring over his dumps—searching, groping, rummaging about for some slight clue that would have escaped the eye of a Sherlock Holmes. Months went by, and then, in one dump, a single bit which didn’t seem quite right. Back he went through all the other dumps, until he had ferreted out two more cases, then five, then a dozen out of the hundreds. These twelve cases he arranged on a large table, first in one pattern, then another, until some threads of connection became visible. By this time, his mind was so specialized to the cases at hand that it was fruitless for him to try to explain his hypothesis to anyone else. It seemed to him that one of the data channels—when certain conditions were just right—was picking up a bit in one of the positions of its address register, thus causing a single character to be stored out of its regular sequence. Since this error usually occurred in the middle of a large data block, the stray character was usually wiped out by subsequent characters in the block, but in a few cases—the twelve—the character was found just Variations in the Programming Task 137 past the end of the block. He tried to convince the engineers, but they would not listen. Programmers always say that there are machine errors. So, finally, he constructed a program that would force the channel into just the right circumstances with an increased frequency. Then, when he made the error occur with more regularity, he was able to define the circumstances with enough precision to find on the schematic exactly the circuit card that must be in error. The engineers were impressed with his diligence, so they finally granted him a test of the card—and found that he was right! Such programming sleuths are not rewarded for their discoveries with the fame of a Pasteur or a Salk. Nonetheless, they are satisfied—beyond the comprehension of ordinary men—with the work itself. And yet, such a bug-finding genius may be rather inept at correcting a bug once it has been found—indeed, the found bug has lost its interest for him. If forced to make the correction, he will, more often than not, introduce a much cruder bug in its place, or else create a clumsy and inefficient patch. For corrections that fit into a program with a certain elegance, another type of programmer is needed. Correcting errors in other peoples’ programs requires a sense of fitness and proportion, plus an extensive repertoire of tricks for one machine or language. The “patcher,” in other words, must have a “synthetic’”’ mind, aS opposed to the “analytical” mind of the ‘‘bug-finder.” To be Sure, the same person could excel at both of these tasks, but we are more likely to find that a team can do a far better job than any of its members—if they have the sense and humility to recognize their talents and shortcomings. SUMMARY Programming is not an undifferentiated mass. Software designers often forget that professionals need different types of tools than do amateurs. Managers often forget that programming work breaks up into stages, and not very neatly or linearly at that. And programmers themselves often forget that they are trying to do different things with different programs. The variegated nature of programming leads to confusion and compli- cation in the work of software designers, managers, and programmers. But most important for us, it leads to confusion and complication in the psychological study of programming. Just as we could not say in absolute terms what is a ‘good program,” we cannot say what is a “good pro- grammer,” “‘a good programming manager,” or, for that matter, ‘a good piece of software.” As a result, we shall be forced to elevate the discus- sion of programming by lowering the level of discourse: we shall only be 138 Programming as an Individual Activity able to make conclusions of general validity if we get down to much more detail than is usually found in discussions of “what makes a good programmer.”’ And perhaps we shall find that what makes a good pro- grammer is much like what makes a good friendship—a mutual recogni- tion and encouragement of individuality. QUESTIONS For Managers a Have you ever had an “executive’’ programming course? Describe what you did, and how it relates to the job of the professional programmer. Also describe any practices in the course which misled you as to the nature of programming. . How do you estimate the complexity of a programming assignment? By examining the specifications? By listening to what the assigned pro- grammer tells you? By taking several informed opinions? . How explicit are your assignments in terms of the relative importance of the following? . Schedule . Specifications Speed . Space . Documentation Other factors ™~OD9QA0 0D . Describe the sequence of work planned for your current project. Is the actual work proceeding according to the original scheme? Do you expect it to continue in this manner? . How close is your progress reporting scheme to the reality of the pro- gramming work that goes on? What checks do you have to find out if it corresponds to reality? Does your scheme achieve correspondence to reality by forcing programmers to work in patterns that conform to the scheme rather than to the needs of their current task? . What steps do you take as manager to level the load on critical fa- cilities? For Programmers LP 2. Are you a professional programmer? What is it that makes you a professional programmer? Make a list of things that your software does for you that fifteen years ago you would have had to do for yourself. Or don’t you know anything about what software was like fifteen years ago? Do you think a pro- fessional should know something about the history of his profession? Variations in the Programming Task 139 3. Is your programming a balanced effort, or do you tend to favor the work you like best? What steps are you taking to improve your per- formance in those areas where you are weak or where you dislike the work? Or, alternatively, what steps are you taking to see that you can work most in those areas where you excel? 4. What are the objectives on your current project? Make a list of them, in order of importance, and ask your manager if he will make a similar list without seeing yours. Then compare the lists, and report on the differences. 5. What do you do when the machine is down for a day or more, so that you cannot make any debugging runs? 6. Which of the following do you do best? a. Detect subtle errors in output. b. Locate errors in the code, once they have been detected. c. Choose corrections that are simple and effective. What do you do to overcome your deficiencies in the other two areas? BIBLIOGRAPHY Rosen, S., ed., Programming Systems and Languages, New York, McGraw-Hill, 1967. Rosen has collected and annotated most of the important original papers on com- puter software, particularly languages and compilers. The collection can be used by the beginning professional programmer to get a sense of what has brought his profession to the point in which he finds it today. Sammet, Jean E., Programming Languages: History and Fundamentals, Englewood Cliffs, N.J., Prentice-Hall, 1969. Whereas Rosen goes back to the original papers, Sammet tries to give the sense of history by bringing all work, major and minor, into one coherent pattern. Her approach is valuable for two reasons. First, in attempting to bring pattern to this potpourri, she succeeds in displaying how rich and complex the pattern of pro- gramming work really is. The second value to this approach is related to the first, for a collection such as Rosen’s of only the best and most successful work tends to give the impression that there was much less experimenting going on. Sammet successfully captures the flavor of trial and error (more error than trial) which has dominated software development. Of course, even she fails to capture the flavor of all the errors which were (happily) never published. | can think of one, called MYSTIC, which was so bad that it should be resurrected for the educational purposes that only a horrible example can serve. Metzger, Phillip W., Programming Project Management Guide, IBM Federal Systems Division, April 1970. Lecht, Charles P., The Management of Computer Programming Projects, American Management Association, Inc., 1967. These two documents represent a fair sample of the management school of pro- gramming project management. Metzger’s book is a guide for an IBM internal course on programming project management—a course originated by Al Pietra- 140 Programming as an Individual Activity santa and Joel Aron, and one of the original guides. The Lecht volume is the effort of the American Management Association on the same subject. Both volumes con- tain useful information, as well as management pep-talk. The vantage point they take, however, is well characterized by this sentence taken from the last page of the Metzger collection: “You know, it’s no crime to want to work in some field other than management.” You almost expect the next sentence to read: ‘“‘Why some of my best friends aren’t managers.” Given this elitist undercurrent in the thought of managers—or, to be more precise, of the staff people who prepare courses for managers—is it any wonder that the typical project management view of programming is rather remote from the individuality of the programmer and his task? Williams, R. J., Biochemical Individuality, New York, Wiley, 1956. Williams’ highly individual book on individuality at the physical level should be required reading for all those who suffer from the illusion that “all programmers look alike.”” Can we really comprehend that some people have three kidneys and some have one and then still believe that each programmer should take the same amount of time to do the same job? Tyler, L. E., The Psychology of Human Differences, 3rd ed., New York, Appleton- Century-Crofts, 1965. Tyler does for man at the psychological level what Williams does at the physical level. Is it a coincidence that both of these books saw the light in 1956, the year FORTRAN was born? Silver Anniversary Notes Comments on Chapter 7: Variations in the Programming Task “Programming is not an undifferentiated mass” (p. 137). Today, perhaps, | wouldn't have thought to write this chapter, for the diversity of programming tasks is so much greater that the conclusion is obvious to any observer. Around the time the first edition was in preparation, Ed Schulman and | extended the experiments described in this chapter to measure other dimen- sions besides efficient programs and fast programming.! With the perspective of time, and with just a bit of humility, I'd have to say that these experiments were the most crucial of any I’ve seen on the psychology of programming. What we showed was that programmers could do just about anything they were asked to do. (This doesn’t, of course, mean that they could do everything they were asked to do, as some managers wish to believe.) As a result of these experiments, | decided that the greatest return on the investment of my time would be in the area of discovering and communicating clear requirements. And, indeed, this subject has paid off handsomely for those organizations that have paid attention. 1 These experiments are reported in G.M. Weinberg and E.L. Schulman, “Goals and Performance in Computer Programming,” Human Factors, Vol. 16, No. 1 (1974), pp. 70-77. aan wed et acer, seit don aft on cmnenins 4 Hog Avera a namanagualagirenmongicalaucednke pea ahiig hands, deal peneriie4 Bs went an Wat Bet as , : ve. ae CAME Usa lubrhnd yay erteaica (xlan “ iby Sietaget LVR oe. ou) en, he eee bs Weald 0 Meow is lala aa ii ein fey Mogg \ HA fine eae mecit > Teme, ANT arte at ay shack yriiieee. 4 * ar Cae.