Notes for Gerald Weinberg The Psychology of Computer Programming
Key concepts: chunking, cognitive dissonance, critical case, democratic team organization, egoless programming, extensibility, fixation, inhibition, linearity, locality, Parkinsonianism, programming group, programming project, programming team, psychological set, sequential memory, synesthetic memory, technocratic organization, working to rule.
Related theorists: Joel Aron, Luc Boltanski, Jerome Bruner, Eve Chiapello, Charles Hockett, Catherine Malabou, David B. Mayer, C. Northcote Parkinson, John von Neumann.
Purpose of book is to initiate new field of study of computer programming as human activity, psychology of programming as I likewise wish to articulate critical programming as a new digital humanities practice.
(vii) This book has only one major purpose—to trigger the beginning of a new field of study: computer programming as a human activity, or, in short, the psychology of computer programming.
Imagines holistic perspective by manager would yield higher performance by programmers and better designs.
(vii) If our experiences are any indication, each of them could be
functioning more efficiently, with greater satisfaction, if he and
his manager would only learn to look upon the programmer as a human
being, rather than as another one of the machines.
(vii) I think that great strides are possible in the design of our hardware and software too, if we can adopt the psychological viewpoint. I would hope that this book would encourage our designers to add this new dimension to their design philosophy.
Suggestions for Course Use
Criterion of programming literacy, writing not just reading if possible to only read.
Arising from computer science psychology of programming exemplifies end of continuum whose humanities end is still forming.
(ix) It does not seem advisable to give such a course to people who are not able to write programs themselves, or who are at lower than a graduate level or a senior level with a strong major in Computer Systems or Computer Science.
PROGRAMMING AS HUMAN PERFORMANCE
1 READING PROGRAMS
Programming a kind of writing connects period to late literacy before born digital generations.
(5-6) Programming is, among other things, a kind of writing. One way to learn writing is to write, but in all other forms of writing, one also reads.
Nostalgia for reading following advent of terminals.
(6) Just as
television has turned the heads of the young from the old-fashioned
joys of book reading, so have terminals and generally improved
turnaround made the reading of programs the mark of a hopelessly
(6) Perhaps if we want to understand how programmers program—to lift the veil of the programming mystique—we could fruitfully begin by seeing what is to be learned from the reading of programs.
Read programs by asking what each part exists rather than serial traversal like reading a novel.
(6-7) We shall need a method of approach for reading programs, for, unlike novels, the best way to read them is not always from beginning to end. . . . Instead, we might base our reading on a conceptual framework consisting of the origin of each part. In other words, as we look at each piece of code, we ask ourselves the question, “Why is this piece here?”
Comments rarely left concerning overcoming machine limitations such as handling precision, real numbers and intermediate storage.
(8) Of course,
when the programmer includes something that is intended to overcome
some limitation of the machine, he rarely marks it explicitly as
such. . . . For instance, much programming has to be done to overcome
the limited precision of our machines—or better still, the fact
that they do not calculate with real numbers but only with a limited
set of the rationals.
(8) Another area in which machine limitations are rife is intermediate storage.
Language limitations include loss of facilities provided by the hardware like end of file indication, although may not be noticed until compared to newer languages.
(9) One of the
consequences of moving up above machine language is that certain
facilities of the hardware may be lost to the user. An example of
this type is the end-of-file situation which exists in some FORTRAN
(10) Still, we may not feel these limitations until they have been lifted from us, just as we often do not know we are sick until we suddenly feel better. Therefore, it is reasonable to expect that future languages will make us feel those limitations of PL/I that are not detectable today.
History of program development leaves traces beyond machine, language and programmer limitations, especially due to size and composition of original programming group; compare to sedimented composition of psychoanalytic unconscious.
(11) We often find
material in programs that might be accounted for under one of the
above categories but is really present because of the history of the
development of the program.
(12) Even the very structure of the program may be determined by the size and composition of the programming group that originally wrote it—since the work had to be divided up among a certain number of people, each of whom had certain strengths and weaknesses.
Specifications evolve during development; writing programs is a learning process for all parties involved.
in most cases, we do not know
we want to do until we have taken a flying leap at programming
(12) Specifications evolve together with programs and programmers. Writing a program is a process of learning—both for the programmer and the person who commissions the program.
Each chapter concludes with questions for managers and programmers as well as a bibliography.
2 WHAT MAKES A GOOD PROGRAM?
Metrics must be based on asymptotic perfection.
(19) If a program doesn't work, measures of efficiency, of adaptability, or of cost of production have no meaning. Still, we must be realistic and acknowledge that probably no perfect program was ever written.
Another instance where going beyond individual imbricates social conflict in addition to other communication challenges as point made later about decisions as soon as another ego is involved.
(19) 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.
Rather have longer wait time than missed schedules.
(20) Losses from late delivery of programs are not always so severe, but even were the costs negligible, there seems to be, in the United States, at least, an incredible amount of annoyance when schedules are not met. . . . This is an area where some psychological study could be rewarding, but there are indications from other situations that it is not the mean length of estimated time that annoys people but, rather, the standard deviation in the actual time taken.
Programs do not seem to write for reuse even though they know code continues to be used when they are not involved with it.
(20-21) Why, we should ask, do programmers, who know full well that programs will inevitably be modified, write programs with no thought to such modifications?
adaptability theory explains surprising difficulty of adapting well
(21) Fisher's Fundamental Theory states—in terms appropriate to the present context—that the better adapted a system is to a particular environment, the less adaptable it is to new environments.
Challenge of coding for both efficiency and adaptability despite bias of both in rhetoric of high level object oriented programming paradigms; embarrassing sexist cast to otherwise correct maxim of common sense computer programming folk psychology.
(22) When we ask for efficiency, we are often asking for “tight” coding that will be difficult to modify. . . . Asking for efficiency and adaptability in the same program is like asking for a beautiful and modest wife.
Foreshadowing more complex networked environments where efficiency measures will be even harder to make.
(24) As hazardous as it is to make simple measure of efficiency in a single-machine, simple-scheduler environment, it is child's play compared with the difficulties of obtaining meaningful efficiency estimates in a multi-processing or mutliprogramming environment.
that virtual memory and other technological enhancements will favor
scalable, transportable programs, implying all things from
environment level, for example POSIX, to most basic computational
units, for example common native data structures.
(24) We may be moving toward a computing environment in which the best programs are those that retain the ability to be run in various sizes of main memory, on various machine configurations. . . . Machines with virtual memories give us the kind of flexibility without special programming, although there are indications that performance improvements can be obtained even in this environment by taking special characteristics into account.
that effectiveness will overshadow concerns of efficiency due to
enormous amplification of computing power (Kurzweil).
(25) And so we expect that with each passing year we will hear less and less about efficiency—and more and more about effectiveness.
The overall research question for the book investigates how can we study programming.
3 HOW CAN WE STUDY PROGRAMMING?
Capability of directly recording user behavior alters human computer relationship from other activities that can be studied.
Direct recording by computer a unique feature
(31) But we should take time to discuss one type of unobtrusive measure which is more or less unique to computer studies—the direct recording of user behavior by the computer.
Using college freshmen may suffice for general psychological experiments but without seasoned subjects study risks being psychology of programmer trainees.
(33) In selecting subjects, inadvertent constraint may slip in. Whereas psychology may be the psychology of college freshmen, the psychology of programming could easily become the psychology of programmer trainees.
Individual versus social unit a methodological shortcoming of other types of study, for example ethnographies of software development; Brooks is aware of need to study groups.
(35) To the extent
that experimenters have believed this, they have chosen the
individual programmer—experienced or not—as the suitable object
for study. But there is much evidence, as well shall see presently,
to argue that the proper study of programming is done at the level of
the programming social unit.
(35) The neglect of social effects casts doubt upon all individual studies, since these studies force the individual himself from his normal working environment.
Still in stage of looking for questions, defining the field, before undertaking extended studies for answers.
(37) For the present, most of the work in the psychology of programming is going to have to be “looking for questions.”
USING BEHAVIORAL SCIENCE DATA
Cultural and personality of anthropology provides best model, studying social structure of culture of computer programmers, how they relate to each other and nonprogrammers; predicts more room for improvement in social over individual activities, thus the focus on group behavior over individual psychology from which Turkle and others base their conclusions.
(39) The social science that provides us with the most useful overall model for computer programming is anthropology. With a little artistic license and stretching of the imagination, we could imagine computer programmers as having a culture—a shared set of beliefs and activities which shape their day-to-day activities. In our study of programming, we shall first examine the “social structure” of that culture—the way programmers relate to one another and to other people who are not programmers. We shall find some surprising possibilities for improvement in this area over present practices, more even than in the second area of study—programming as an individual activity. Although stretching a bit to make the analogy, this study is related to the personality and culture studies of the anthropologist. We shall see how the individual lends his individuality to his program and how programming lends shape to the programmer himself.
Tools are next, as embodiment of material culture; language learning plays large but not exclusive role in explaining recruitment and training into complex skilled art of professional programming.
(39) Once these two sections have prepared the way, we should be in a proper frame of mind to examine the programmer's tools—his languages, operating systems, and other devices—from a psychological point of view. These tools are the “material culture” of programming—the artifacts which the programming archeologist would find and study to understand the dead civilization of programming. Also, as programmers are not born into this culture, we shall study how they are—or should be—recruited, and how they learn this complex way of life. Hence the psychology of learning—and especially language learning—shall play a large, though not exclusive, role.
PROGRAMMING AS A SOCIAL ACTIVITY
Social assemblages of group, team, project; project level aims at producing single integrated system or closely knit collection of programs as experienced in professional software development.
(46) For our
purpose, we shall identify three sorts of programmer assemblage—the
group, the team, and the project. Roughly speaking, the group is a
collection of programmers, working in the same place, probably
sharing the same machine and system, but working on separate
programs, although there may be a relationship among some of the
(46) A programming team, on the other hand, is a collection of programmers who are trying to produce a single program by working together. . . . The project is a group of programmers plus their supporting activities which has probably been brought together for the purpose of producing a single integrated system, or at least a closely knit collection of programs.
4 THE PROGRAMMING GROUP
FORMAL AND INFORMAL ORGANIZATION
Writes from early period before organizational charts captured division of labor effecting software development, promoting ideologies hierarchical, structured operations.
(47) The organization chart is a nice toy for a manager, but little programming work would ever get done if interactions among programmers had to follow its narrow, straight lines.
Famous example of vending machine social hub informal organization shunting formal consulting mechanism.
(50) Since most of the student problems were similar, the chances were very high that he could find someone who knew what was wrong with his problem right there at the vending machines. Through this information organization, the formal consulting mechanism was shunted, and its load was reduced to a level it could reasonably handle.
Warning of disrupting informal mechanisms from failing it understand their function.
(50) The point of these stories is that informal mechanisms always exist and it is dangerous to change things without understanding them, lest you derange some smoothly operating system which you will not be able to replace at similar cost.
PHYSICAL ENVIRONMENT AND SOCIAL ORGANIZATION
Studying effects of layout of workspace on social interaction and ultimately work product.
(51) What we are concerned with is how the layout of work space affects the pattern of social interaction which in turn influences the work that is done.
ERROR AND EGO
Personality dimensions of compliant, aggressive, detached relevant to programmers; their detachment from people likely accompanied by attachment to their programs, leading to discussion of egoless programming as optimal solution.
(53) Among the general personality traits is one which is measured
along three “dimensions”--whether a person is “compliant,”
“aggressive,” or “detached.” The compliant type is
characterized by the attitude of liking to “work with people and be
helpful.” The aggressive type wants to “earn money and prestige,”
and the detached type wants to “be left to myself to be
(53) Like most good things, however, the “detachment” of programmers is often overdeveloped. Although they are detached from people, they are attached to their programs.
Cognitive dissonance explains why programs as extensions of ego are hard for their authors to judge and find errors.
(55) Now, what cognitive dissonance has to do with our programming
conflict should be vividly clear. A programmer who truly sees his
program as an extension of his own ego is not going to be trying to
find all the errors in that program. On the contrary, he is going to
be trying to prove that the program is correct—even if this means
the oversight of errors which are monstrous to another eye.
(56) Thus, if we are going to attack the problem of making good programs, and if we are going to start at the fundamental level of meeting specifications, we are going to have to do something about the perfectly normal human tendency to believe that ones “own” program is correct in the face of hard physical evidence to the contrary.
Reference to von Neumann humility regarding quality of his programs beside reputation for computing genius; was he a hacker, and does it matter since he got others to help him improve them?
(56) John von Neumann himself was perhaps the first programmer to recognize his inadequacies with respect to examination of his own work. Those who knew him have said that he was constantly asserting what a lousy programmer he was, and that he incessantly pushed his programs on other people to read for errors and clumsiness. Yet the common image today of von Neumann is of the unparalleled computing genius—flawless in his every action.
Idea of egoless programming is training people to accept their inability to function like a machine to always produce perfect work.
(56-57) Average people can be trained to accept their humanity—their inability to function like a machine—and to value it and work with others so as to keep it under the kind of control needed if programming is to be successful.
Practice of egoless programming concealed behind proprietary business practices and smug satisfaction, as well as lack of tests in sense of Latour, Boltanksi and Chiapello; note default practice is isolated individual programmers relying on their personal competence, and in competition with each other for prestige.
(58) Why is the practice of “egoless programming” not more
widespread? . . . First of all, many of the successful software firms
are based on this type of interaction, and though they will admit to
it under direct questioning, they often regard this knowledge as
valuable proprietary information. Secondly, groups working in this
way tend to be remarkably satisfied and stable, so that the
programmers we find wandering from installation to installation are
not likely to have come from such a group.
(58) Another reason these methods are not better known is that nobody has ever experimented on the difference in quality of work produced by this method and the method of isolated individual programmers.
Account of egoless programming suggests advantages beyond detecting errors from sense of writing for future readers; apply to four factors of good programming.
(59) he raised the point that he had worked throughout as he always did in his own group—always with an eye to making the program clear and understandable to the person or people who would ultimately have to read it. This insight indicates that all the advantages of egoless programming are not confined to the detection of errors, though that was perhaps the earliest and strongest motivation for adopting the technique. In fact, it might be useful to examine our four factors in good programming in light of what effect this method would have for them.
Egoless programming practices would likely help meet specifications, scheduling, estimating, continuity.
(59) For meeting specifications, the value is quite clear. On the
matter of scheduling, the effect on the mean time to complete
programs is not immediately evident, but the effect on the variation
should be clear from our example of the bugged simulator.
(59) since there is more than one person familiar with the program, it is easier to get realistic estimates on the amount of real progress that has been made. . . . The adaptability of programs is also improved, for we are assured that at least two people are capable of understanding the program. Under certain programming circumstances, this represents an infinite improvement. Also, the entire work is less susceptible to being disturbed.
CREATING AND MAINTAINING THE PROGRAMMING ENVIRONMENT
Maintenance easier than changing existing groups due to fixation of social structures such as using particular languages.
(60) Maintenance is by far the easier task, for converting an
existing group to this philosophy will usually run against the
phenomenon of “locking” or “fixation” of social structures.
Fixation occurs whenever a situation creates an environment favorable
for maintaining that situation.
(60) One typical computing example of social fixation is the adoption of one programming language by an installation.
A functioning group will social new members to its philosophy of programming: there, somebody said philosophy of programming.
(61) To a large extent, we behave the way we see people behaving around us, so a functioning programming group will tend to socialize new members to its philosophy of programming.
Clashes between aggressive management and egoless programming groups.
(61) Adherents of the egoless programming philosophy are frequently subjected to threatening moves on the part of managers from the “aggressive” component of society and have difficulty appreciating the fact that other people do not completely share their goals of money and prestige.
Managers often evaluate group based on assessment of sum of individual contributions rather than property of the group.
(62) Even when the manager appreciates the work of the group, it is not consistent with his own philosophy to see the productivity of the group as a property of the group, not as a sum of the contributions of the individual members.
5 THE PROGRAMMING TEAM
Coordination whenever scale of effort more than can be remembered by a single mind involved, and resolving conflicting demands in a group involves social mechanisms.
(67-68) As long as the work of the entire group—from its purpose and general organization to the last coding detail—can be held in the mind of one person, there is no need for coordination of programming effort. . . . In the second case, conflicting technical demands are translated into potential interpersonal conflicts, and a social mechanism must be formed to resolve them.
HOW A TEAM FORMS
Parkinsonianism one extreme of scheduling dangers whose other is cutting corners and hoping for ideal conditions.
(68) The minimum schedule can only
be achieved by putting the best team to work on the project; and the
minimum work team can only be used if we are willing to let the
project stretch out for a longer time.
(68-69) Although we must always be on our toes against Parkinsonianism (work expands to fill the time allotted), too tight a schedule will inevitably lead to the temptation to take shortcuts. These shortcuts might succeed in getting the system working on time—but only if everything goes right, which it rarely does. So many failures to meet programming deadlines can be traced back to an initial schedule and plan of attack which assumed the most optimistic conditions—no days lost through illness, no machine trouble, no compiler problems, no “impossible” bugs.
Three programmers only twice as productive as a single programmer because of time spent on coordination (Brooks).
(69) As a rough rule, three programmers organized into a team can do only twice the work of a single programmer of the same ability—because of time spent on coordination problems.
Design structure often chosen to accommodate team, nicely illustrated by figure; may complicate retrospective analysis.
(70) Because there are frequently several ways of approaching the structure of a system but rarely more than one group of programmers available to do the work, the structure is often chosen to accommodate the strengths and weaknesses of the team members.
ESTABLISHING AND ACCEPTING GOALS
True consensus best reached having group set their goals; danger of micromanaging by manager who used to code.
(76) To achieve true consensus on group goals, there is no better
method than having the group set the goals itself.
(76) The greatest danger is the manager who has come up through the programming ranks and wants to define every bit and byte before the team even sees the problem. Nothing is more sure to dampen the team enthusiasm and make them feel that they are “mere coders.”
Clarity requires outlining task in context of meaning of work, and critical for goal acceptance, so distinguishable from precision which may be decontextualized.
(76) Precision and clarity are not the same. To be clear—and goal clarity is one of the most critical factors in goal acceptance—the task outlined must be placed in a framework of the meaning of what is being done. The programmer wants to know why, not just what.
TEAM LEADERSHIP AND TEAM LEADERS
Authoritarian, fascist leadership not tolerated for programming; working to rule as form of dissent by programmers and other project members (Boltanski and Chiapello).
(78) In programming, this is scarcely the type of leadership which is needed—or which would usually be tolerated. Try to imagine the reaction of a typical programming team to a supervisor standing over them with a whip or issuing commands like a lieutenant leading his squad in a charge on the enemy machine-gun emplacement. The reaction to even milder forms of authoritarian “leadership” need not be imagined, for we have numerous examples of unenlightened executives trying this approach on programmers. One typical reaction is “working to rule.”
Feelings about leadership primary factor affecting dissatisfaction among programmers.
(80) To be sure, there are instances of underpayment in this generally high-salaried profession, there are dull jobs, and there are bad companies. But these are exceptions, whereas bad supervision and leadership is more common than we would like to imagine. Thus, the attitude of a programmer toward his “superiors” is more likely to be the cause of his dissatisfaction—with consequent loss of productivity—than perhaps all the other three put together.
Forced labor only works briefly, and on immature or unskilled programmers; some game the system, moving from job to job.
(81) But forced labor—to the small extent that it does work—can only be made to work with relatively immature programmers who are not aware of other possibilities, or with relatively unskilled programmers who are quite aware that other possibilities are not open to them. The typical programmer, on the other hand, is aware of other possibilities and aware of his chances of getting them. Carried to an extreme, this awareness leads to the programming type whose career is an unending succession of job changes and very little accomplishment. Normally, however, it leads to programming teams which are run more democratically than typical work teams in many other fields.
Democratic, later called technocratic, work team works when based on inner realities of team life, leadership assumed by those most qualified at the time, not members exerting equal leadership.
The important factor in democratic group functioning is not that
every member exerts equal leadership, but that the determinants of
leadership are based on the inner realities of team life, not imposed
(82) In a democratically organized group—given, of course, sufficient talent and intelligence to draw upon—the right man can be chosen for each time.
Management wants kept promises; leader must win team acceptance of promises as their goals.
The shortsighted or insecure team leader may feel that the best way
to please management is to promise them whatever they ask. But,
ultimately, what the management wants is kept
and these can only be obtained if the team leader can win team
acceptance of the promises as their goals.
(85) One of the paradoxes of leadership is simply this: only the leader who is ready to step down has a real chance of success.
THE TEAM IN CRISIS
Team work consists of accomplishing goals and maintaining effective functioning; each team has a task and maintenance specialist.
(85) Indeed, it is useful to consider the work of the team in two
categories—work directed at accomplishing the team goals and work
directed at maintaining the effective functioning of the team in the
face of the crises it meets.
(85) In certain types of groups, and often in programming teams, the group tends to choose two complementary leaders—a task-specialist who sets, allocates, and coordinates work; and a maintenance-specialist, who irons out conflicts among group members or between individual goals and group goals.
Observation that a woman on a team takes on mother role; softness and hardness characterizations.
(85-86) In any case, it seems quite frequent that when there is a woman on a programming team, she assumes the role of “team-mother,” although no studies have been made to verify sex as a significant factor in choosing the maintenance-specialists. . . . Softness is one of the terms which has been used to characterize the maintenance task, whereas hardness seems to characterize the one who must direct the work.
Replacing team members most frequent crisis; change better withstood by democratically organized team.
(86) The replacement of a leader—or any team member—is probably
the most frequent and typical crisis in the life of a team.
(86) The “democratically” organized team tends to be better able to withstand the shock of loss of a group member—whether by promotion, resignation, illness, death, pregnancy, or a call to the cloth.
Dealing with uncooperative and underperforming members also sources of crisis.
(87) Another sort of crisis appears when the team members begin to be
aware that one of their number is not able to carry his share of the
(87) A member who is competent but who does not get along with the others can be an even more serious problem for the democratic group than an out-and-out incompetent.
Democratic, or technocratic, organization natural for programming teams.
(90) We can see, then, why the democratic—or perhaps we should say “technocratic”--organization is such a natural one for a programming team. When selecting programmers for teams, we should try to choose people who will fit well within such a self-shifting structure—neither too dominant nor too passive. In training our programmers, we should try to teach them how to follow able leaders and how to grasp leadership opportunities when they themselves are the most qualified in the group. And during the life of a team, we should try—if we are on the outside—not to interfere in those democratic processes which, though seemingly traumatic for the team and its members, will in the long run lead to most effective team functioning.
Time span and complexity of programming situations exceed typical experiments by social psychologists.
(91) In the programming situations, the span of time and the complexity of the task performed are each orders of magnitude different from anything ever attempted in an experiment by social psychologists.
6 THE PROGRAMMING PROJECT
Project management is second order coordination among teams.
(95-96) Coordination among teams now requires a second level—or higher—of leadership, and so emerges the phenomenon of leaders whose followers are not engaged in the basic work of the project, but are leaders themselves. . . . What we shall discuss in the next few sections are a few selected aspects—aspects selected for their amenity to psychological treatment and perhaps somewhat as a corrective to certain schools of programming project management thought.
STABILITY THROUGH CHANGE
Large organizations survive while individual members may be transitory.
(96) One of the most intriguing characteristics of large organizations is their ability to survive over periods of time which are longer than the time that any one member remains.
managers view as house versus river, the former subject to collapse
if a keystone member is removed.
(96) Even in a programming team, we sometimes see the survival of the team when not a single original member remains. . . . In a sense, a programming project or team is like a river which remains the same river even though its water is undergoing constant change.
(96) Many project managers are unable to grasp this view of a project. Their view of the project's structure is, instead, much like that of a house—a structure that might collapse should one of the beams be removed. Their actions with respect to the people in the project—especially so-called “key” people—reflect this static view, often with disastrous consequences.
Raises often interpreted as substitution for more desirable situation.
(97) Managers are quite frequently surprised to find that a
programmer quits a project very soon—sometimes immediately—after
getting a solid raise.
(97) More frequently, however, the raise is interpreted as an attempt to substitute money for something the programmer really wants.
Project as programmer processing plant or training grounds.
(99) Not every programmer wants to advance to more challenging work—some will leave if pushed too fast—but for the most part, as programmers learn they become discontented unless they can apply their knowledge. Thus, to achieve a stable project over a long period of time, a manager must encourage the project to function as a sort of programmer processing plant—with a fresh supply of trainees coming in one end and a stream of experienced leaders coming out the other, with people in the middle being bumped up one position at a time by the flow.
Danger of indispensable team members.
(100) No, if a manager wants to run a stable project, he would do well to follow this simple maxim: If a programmer is indispensable, get rid of him as quickly as possible.
Project progress a combination of different views of different programs.
(100) Since progress on a program is such a subjective matter, opinions would differ about the amount of progress a particular program had made, even if it were not for other effects. But we never get the opportunity to study the different views on one program. Instead, we compare and combine different people's views of different programs into some sort of picture of project progress.
Reporting system as series of filters; surprising news is the most information reports carry.
(102-103) From an information-theoretic point of view, this reporting system can be seen as a series of filters—each with a certain delay and each with a certain loss of information. Information, in this sense, is carried by a report to the extent that it carries surprising news. . . . Similarly, in a progress report, the most information is carried in these items which indicate very much or very little progress. But what happens to those items?
Psychological tendency of moving extremes toward the middle affects reporting; recall organizational deception loops from CAP conference.
(103) To answer that question, we must identify the psychological
source of the tendency to move the extremes toward the middle. One
possibility is cognitive dissonance.
(103) Another possibility—not excluding the cognitive dissonance idea—is implied or inferred pressure from higher up. . . . What a manager must learn to do is to motivate people to modify the way they work or the rate at which they work, not motivate them to conceal what they are doing. Therefore, he has to reward an accurate reporting of good work. Since the person doing the reporting is usually the one responsible for the work being reported, it is difficult, if not impossible, to reward him for accurate reporting at the same time he is being reprimanded for poor performance. Inasmuch as the hierarchical system of organization requires this confusion of goals for its managers, we generally see that reporting systems in this type of organization move further and further away from meaningfulness as time goes on.
Social pressure experiments reveal influence of announced opinions of others (Abilene paradox); thus value of devils advocate role.
(104) There are many variants to these social pressure experiments,
and it would pay the programming manager to study them. For our
present purposes, however, it is sufficient to notice how opinions on
concrete matters can be easily influenced by the announced opinions
of others, and how the influence becomes more effective as the
judgment becomes more difficult.
(105) Recognizing that even a single ally can provide a safety valve to release the social pressure to produce conforming opinions, some programming projects have established a “devil's advocate” system for their management meetings.
Many deviations from simple hierarchic structure emerge: standards groups evaluate production of other groups to mitigate progress reporting biases, task forces for dealing with intractable bugs.
(106) In order to combat this deterioration, deviations from a simple
hierarchic structure begin to emerge.
(106) Many projects have a standards group whose principal duty is not production, but evaluation of the production of other groups.
Projects need slack for adjustments to staffing and priorities, such as forming special task forces.
(106) For instance, if there is a bug in the system which ordinary methods do not find, a special task force may be set up to root it out. To be able to establish such temporary groups, the project manager must preserve a certain amount of “slack” in the project, so that people can be extracted and used to plug the leak. No project, no matter how carefully planned, can anticipate all contingencies and set up grounds in advance to meet them. Thus, the typical project may expect to experience several reorganizations throughout its lifetime.
Specialized teams may have uncommon goals, such as testing groups whose job is to criticize.
(107) Each person working on a team within a project has come to
accept certain of the team goals as his own. But when the team is
specialized, its goals do not necessarily coincide with the overall
goals of the project, or with the goals of another team.
(107) Any testing group is also put into a difficult relationship with other groups, because it is their job to criticize.
Egoless programming research suggests friends can be stern critics of one another.
(108) However, we do know through our experience with egoless programming that there is no particular reason why your friend cannot also be your sternest critic.
Conflict between management and workers develops because project goals are not sum of individual team goals.
(108) Another natural conflict which arises in projects cuts horizontally instead of vertically—tending to separate the management from the working programmers. This conflict arises over the setting of goals, for project goals are not simply the sum of individual team goals.
View project in terms of successful machines or natural systems rather than hierarchical organization modeled after Austrian army.
(108) Many of these problems can be overcome if the management of the project can see the operation as a machine for getting the project done, rather than as a pyramid to be climbed for the satisfaction of their personal ambitions. In an engine, for example, the valves are not the “boss” of the cylinders, nor is the crankshaft the “boss” of the valves. The hierarchical organization, which so many of our projects seems to emulate, comes to us not from the observation of successful machines or natural systems, but from the nineteenth century successes of the Austrian Army. . . . The hierarchical organization, then, was conceived as the structure that could give the fastest and most direct coordination between these interchangeable parts. But a programming project is not a battle, regardless of appearances.
COMMON SOCIAL PROBLEMS OF LARGE PROJECTS
Many social problems due to remoteness of leadership from workers, complicated when managers used to be programmers, though reward for appearance of work also common when they do not understand it.
(109) The remoteness of the project leadership from the workers is
the source of many social problems in large groups.
(109) Even thought the nth-level manager may have originally been a programmer, which is rare enough, he has almost certainly lost any programming ability by the time he reaches these heights.
(109) Whenever a supervisor is responsible for work he does not understand, be begins to reward workers not for work, but for the appearance of work.
Status linked to ability to perform technical tasks; status symbols like a card file often amusing to those outside the system.
(110) Being thanked for some technical advice must have elevated the
status of the project manager in the eyes of his fellows, for such
direct performances are rare for managers. At the working level,
status is largely determined by the ability to perform technical
tasks—such as legendary feats of debugging.
(110) Status symbols are always amusing—to anyone outside the system. . . . At certain low levels, the card file is a positive status symbol over ordinary programmers, because it implies that its owner cannot leave his important programs unguarded.
Terminal is latest status symbols for programming managers.
(111) Lately, the terminal has become the number one status symbol for programming managers.
A female assistant is the classic status symbol that also asserts biases about menial tasks and gender, and aggravates the sex problem.
(111) One of the classic status symbols from which programming
managers are not exempt is the secretary or the administrative
(111) This association of women with the menial tasks of an office and of good looks with poor brains is the source of one of the more serious social problems in large projects—the sex problem.
Valuing competence over prejudices should deliver more women into programmer and manager ranks.
(112) Each prejudice has its price. In a programming project, the exclusion of anyone from any position on any basis besides lack of competence robs the project of the best possible performance. . . . Possibly the greatest single action to relieve the shortage of programming and programming management talent would be to start treating women as true equals—if indeed they are only that.
Discusses NATO conference on Software Engineering noted by other theorists, citing Aron who finds management the common root cause of project failures.
At the end of 1969, the second NATO conference on Software
Engineering was held, and the tone was already much change from the
one held the previous year. People
beginning to come into the picture, and the reason is not hard to
find in the proceedings. We may quote this comment from Joel Aron as
most clearly representing the problem: . . . We analyzed the reasons
for failure, as given to us by the project managers, and by people
who had performed previous evaluations of the projects. They gave
various reasons behind the failure of the projects, virtually
all of which were essentially management failures.
We ran into problems because we didn't know how to manage what we
had, not because we lacked the techniques themselves.
(113) Over the years, I have had the opportunity to work with Joel Aron as he has crusaded to get people to believe what he says about programming projects.
(113) People are trying to cope with problems they don't understand, and those they don't know they don't understand—in itself a failure of management.
PROGRAMMING AS AN INDIVIDUAL ACTIVITY
From individual level on up programming groups produce different finished products for same goals, designs for requirements.
(119) No matter how similar the structure of two programming groups
might be, they will produce different finished products. In this
section, we shall try to account for some of those differences by
examining factors centering in and around the individual.
(120) Certainly in programming, where every task is different from every other in a multitude of ways, our first investigations would have to be into task differences.
Division of individual differences into categories of personality, intelligence, training, experience.
(120) The individual variations that interest us by be further subdivided into the general categories of “personality,” “intelligence,” and “training” or “experience.”
7 VARIATIONS IN THE PROGRAMMING TASK
PROFESSIONAL VERSUS AMATEUR PROGRAMMING
Differences between amateur and professional programming include ultimate user, which affects planning, making changes, and forgetting; emergence of floss permits development of professional skills by amateurs.
(122) 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 is
(122) Perhaps the deepest differences emanate from differences in the ultimate user of the program.
(122) Because the amateur will be the user of his own program, he has the choice of doing his thinking either before or after programming.
(123) Even more subtle problems can be handled for him because he can think after programming. . . . Only when the programmer himself is defining the problem is this sort of simplification possible, for the professional programmer would at least have to had to leave the terminal and find someone to authorize a change or clarification of specifications.
(123-124) Even if the program is not intended for other eyes at all, the professional cannot quite forget about it the same way as the amateur.
Role of operating systems in hiding work done by the system, like commodity fetishism?
(124) Many years ago, when programming systems were rudimentary, the difference between the professional and amateur was not nearly so pronounced. 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.
Professional has both past experience and future orientation.
(125) Indeed, it is a homily that the difference between the professional 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.
Key for life long programming is learning about the profession, not just particular programming problems.
(125) 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 impediment 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.
WHAT THE PROGRAMMER IS TRYING TO DO
Programs should be designed with definite lifespan and scope of application.
(126) Programs, like any other man-made objects, are designed—or should be designed—with a definite lifespan and scope of application in mind. . . . 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.
Level of care not monolithic.
Suggest lack of professionalism in working above appropriate level of care linked to both incompetence and inauthenticity of working to rule.
(127) 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.
Ambiguous objectives hinder most studies of programming performance and likely cause much variance.
(128) There have been very few studies of programming performance,
but what few there have been all seem to have suffered from a lack of
appreciation for the problem of ambiguous programming
(129-130) But the important result from the experiments is that a large proportion of the variance between programmers on any job can be attributed to a different conception of what is to be done.
Lack of communicating all objectives leads to missed schedules and inefficiencies, but also affect estimates depending on whether goals are emphasized or not.
(130) Consequently, unless we take precautions to see that all
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.
(130) There is a certain danger in communicating objectives: objectives can change estimates!
(131) 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 important enough to resist being sacrificed to other goals.
Parkinson work expansion partially attributed to existence of schedule goals influencing rate of work and also existence of goals whose relevance to scheduling not explicit; challenge to induction that programming projects can never to done on time.
(132) When [C. Northcote] 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 goal 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 understand what fallacies underly the generally accepted conclusion that programming projects can never be done on time.
STAGES OF PROGRAMMING WORK
Fallacy assuming programming is uniform effort requiring set of uniform talents.
(132) Another fallacy which we shall have to lay to rest is that
“programming” is some sort of uniform effort requiring a set of
(132) 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.
Distortion caused by view of programming as processing moving through discrete stages when steps often occur in different orders, or not at all, and iteratively, without sharp boundaries; progress reporting forces categorization, which is reified.
(132-133) Programming is often
described as a process moving from problem 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 to be present, as when we are recoding a
program for a new machine or language. Thirdly, it need to be a
all—and, in actual practice, rarely is.
(133) 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.
Good to deliberately break up work for uniform progress despite daily variations in environment and temperament.
(134) 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.
(134) 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 documentation.
Avoid having all project parts in same stage at the same time, and provide variations for programmers to learn.
(134) The ideal project design,
then, would avoid having all its parts in the same stage of
programming at the same time.
(135) 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 least well. In this way, also, we can ensure that each one will jump at the opportunity to switch to some other task when he runs into a snag.
Fruitful divisions of programming activities regarding testing: error detecting, locating, correcting.
(136) 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 types.
(137) The “patcher,” in other words, must have a “synthetic” mind, as opposed to the “analytical” mind of the “bug-finder.”
8 PERSONALITY FACTORS
The Mad Bomber
Personality reflected in programs.
(142) Personality, being the totality of factors contributing to our individuality, is displayed in everything we do or say. In particular, it is reflected in our programs, and, even more particularly, in how those programs look to the machine operators.
Managers face moral dilemma of peering into private life to determine source of symptoms.
(145) Situations such as our last two examples [toothache and dying spouse] present a grave moral dilemma for a manager, at least in our society where one's “private life” is not supposed to enter into office affairs or be examined by one's manager. However, since there is no way to determine from the symptoms whether the cause lies in the office or out, a manager has no choice but to try to understand behavior that is disruptive to the work at hand.
Alternation of jobs through egoless programming reduces forced adaptation of personality to role, but gives up best fit, yielding potential efficiency for stability; compare to Malabou.
(146) This type of alternation of
jobs is accomplished automatically through egoless programming, for
no person is subjected to unrelenting assault on his particular
personality—the type of assault that forces people into “attempts
(147) Through egoless programming, then, we sacrifice the possibility of having each person always in the job for which his personality best suits him, yielding, in this way, some potential efficiency for security and stability.
CRITICAL PERSONALITY TRAITS
Dominance of personality factors in programmer failures; more likely to make personality mistake than intelligence mistake when hiring programmers as intelligence already factored into tests.
(148) If we look more deeply into the observed dominance of
personality factors in programmer failures, we can easily understand
why we are more likely to make a personality mistake in hiring a
programmer than an intelligence mistake.
(149) Whatever the faults of this preselection in excluding people who might have made great success as programmers, it does have the effect of largely eliminating people of below-average intelligence.
Professional programmers need ability to tolerate week long periods of stressful situations, be adaptable to rapid change, have modicum of neatness neat, be humble yet assertive, and possess a sense of humor; consider all as expressions of necessary flexibility to inflexible machines.
(149) Nevertheless, we can probably
say with assurance that someone without the ability
to tolerate stressful situations
for a period of a week or more is
not good programmer material—given the reality of programming work
(150) Because of the diversity of programming work, people who are not in some measure adaptable to rapid change will probably have trouble as professional programmers.
(150) And speaking of garbage, one of the most easily identifiable personality needs in programming is a modicum of neatness.
(150) Without humility, a programmer is foredoomed to the classic pattern of Greek drama: success leading to overconfidence (hubris) leading to blind self-destruction.
(150) The other side of the coin of humility is assertiveness, or force of character. A programmer's job is to get things done, and getting things done sometimes requires moving around obstacles, jumping over them, or simply knocking them down.
(152) Last among the essential personality traits for programming, we might list sense of humor.
Elasticity needed to work with rigid machines despite folk wisdom that programmers should resemble their medium; seems like a positive sense of flexibility compared to that required by the new spirit of capitalism to adapt to flexible environment.
(153) There seems to be some current folk wisdom which imagines that, because programmers work with rigorous machines, they must themselves be rigid. In effect, the opposite is true, for since the machine is so inflexible, the programmer must be flexible enough to supply the elasticity needed in matching any system's abilities to real world needs.
Psychological profiles from existing positions reflect aptitudes of existing employees, not necessarily what employers really want.
(154-155) Even assuming that the profiles are available with sufficient resolution of job descriptions, do they really reflect what we want? After all, these profiles are obtained by testing people already in the profession, not the people we would necessarily want to be in it if we knew what we wanted. . . . There is, on the contrary, reason to believe that employers, at least, are not at all satisfied with the average programmer they employ. Why then should this group be used as a template into which all programming applicants must fit?
Clever programmers are likely to cheat on psychological tests, which is okay because they will likely possess other desirable traits of which clever manipulation of systems is one expression.
(155) As we know, applications for programming jobs are likely to be a rather clever bunch, so we can assume that a great deal of “cheating” will take place if they are given such tests. But that should not worry us, for if they cheat successfully, they are probably going to have a number of the critical personality traits we desire—adaptability to sense the direction of the test, ability to tolerate the stress of being examined by someone they don't know under assumptions they cannot challenge, assertiveness to do something about it, and sense of humor enough to enjoy the challenge.
PERSONALITY TESTING OF PROGRAMMERS
Mayer has produced surveys using popular tests like the Strong Vocational Interest Blank.
(156) David B. Mayer (1968) has provided a useful survey of some of the results with the Strong Vocational Interest Blank and other testing instruments, and the reader with a stronger interest in the Strong Interest Blank than we shall satisfy should look there for further illumination.
Tests are costly and hard to justify over simpler intuitive methods, X-factors related to aptitude and personality items extracted from interviews.
(157) Since tests cost money to administer and to have scored, the burden of proof of usefulness rests on those who propose that a test be used in preference to simpler, more intuitive methods. Mayer refers to an “X-factor” which can be extracted from simple interviews, which he suspects is related to aptitude. My own interviewing experience tends to weight my “X-factor” more to personality items.
9 INTELLIGENCE, OR PROBLEM-SOLVING ABILITY
Psychological set and distance can be impediment to error location activities; syntax highlighting and other visual cues of the interface help counteract by offering machine response.
For certain types of error location activities, psychological set
a major impediment. Numerous experiments have confirmed that the eye
has a tendency to see what it expects to see.
(162) Related to the concept of “set” is the concept of “distance.” Not all misreadings are equally likely, regardless of the set of the reader.
(163) One of the first lessons the novice programmer learns is to make careful distinction between his handwritten “zero” and “oh,” if someone else is keying his programs.
Carelessness in choosing symbols increasing as side effect of successful automatic error detection; mnemonic symbols induce torpor.
(163) No doubt, the rather extensive success of automatic methods of
detecting errors has lulled many programmers into carelessness when
(163) Mnemonic symbols are particularly susceptible to inducing a torpor in the program reader.
Affect of incorrect comments due to psychological set.
(164) The whole idea of a comment is to prepare the mind of the reader for a proper interpretation of the instruction or statement to which it is appended. If the code to which the comment refers is correct, the comment could be useful in this way; but if it happens to be incorrect, the set which the comment lends will only make it less likely that the error will be detected.
SOME DIMENSIONS OF PROBLEM SOLVING
Difficulty of problems often measured by time spent solving, although often the solution comes quickly once the overlooked, problematic factor is discovered.
(165) Lacking any objective
measure, we often judge how difficult a program is by how hard a
programmer works on it.
(165) It will always be difficult to appreciate how much trouble we are not having, just as it will always be difficult to appreciate a really good job for problem solving. Once the problem solution has been shown, it is easy to forget the puzzlement that existed before it was solved. For one thing, one of the most common reasons for problem difficulty is the overlooking of some factor. Once we have discovered or been told that this factor is significant, working out the solution is trivial.
Key to intelligent behavior involves flexibility manipulating assumptions and applying formulas to solve problems.
(165) Overlooking a factor in a problem is just one special case of
assumptions leading us astray.
(166) Intelligent behavior, then, does not consist in eschewing assumptions, but in being sufficiently flexible to manipulate assumptions as the occasion demands. In other words, being intelligent is not having some magic formula which one can apply to every problem. It is, rather, having a number of “formulas” and not being so much in love with one that it cannot be dropped for another.
FACETS OF PROGRAMMING INTELLIGENCE
Importance of memory in programming.
(167) Memory helps a programmer in many ways, not the least of which is by enabling him to “work” on problems when he does not have all his papers in front of him.
Still trying to test programming aptitude; most merely correlate to success in programmer training.
Widescale floss practices permit automated tests of status for programming aptitude (Boltanski and Chiapello).
(170) The possibility of administering tests to select programmers
had long bewitched programming managers, but over the years nobody
has ever been able to demonstrate that any of the various
“programmer's aptitude” tests was worth the money it cost for
(170) The closest thing we have to a validation of a programmer's aptitude test are studies which show that people who scored high on the test were better students in the ensuing programmers' training. When it got down to the nitty-gritty of actual programming, however, there was no correlation—or even a slight negative correlation—between test scores and rated performance.
IQ tests measure ability to take tests; slow and steady more important in programming than timed completion.
(170) In fact, as one wit put it, intelligence tests measure the ability to take tests. . . . Slow and steady may not win the race, but programming is not a race.
IQ and school tests also emphasize arbitrary, short-term memory, whereas selective memory pays in real life; could this practice lead to overall decline in intelligence?
(171) Another typical distortion of intelligence tests is in the emphasis they place on short-term—rather than long-term—memory. . . . But in “real life,” it is selective memory which pays—the ability to forget the unimportant and retain the important over long periods. Not so in school, however, and so we have the IQ test and the school grades going hand in hand—off in a different direction from anything we are interested in.
APTITUDE TESTS FOR PROGRAMMING
Relate PAT and difficulty measuring programmer performance to Boltanksi and Chiapello tests of status.
(171) Probably the foremost among
these is the so-called PAT, or Programmer's Aptitude Test. Actually,
this is not a single test, but an unknown number of variants on an
original test made up one afternoon by a group of programmers in
IBM's New York Scientific Computing Center sometime before 1956, and
administered there to all job applicants and interested visitors. One
of the reasons for the profusion of variants is that the test has
been so widely used and so unprotected that nobody knows how many
people have taken it, or, in particular, which people have taken
(172) For example, the best correlation found in these studies was 0.7 between the PAT and supervisor's ranking. What does 0.7 correlation mean?
(172) One of the reasons for the popularity of the correlation is the way it seems to overstate the case, since the number used is always larger than its square.
(172) There really is no instrument today for measuring programmer performance—or reducing it to a single number, in any case. Consequently, there is nothing really reliable with which to correlate the PAT. It may even be that the PAT is a marvelous predictor of programmer performance, but the supervisors are not themselves sufficiently trained to know it.
Examination of structure of PAT reveals deficiencies.
(173) A little examination into the
structure of the test itself might give us some hints as to what is
wrong with it, now that we know that much is
wrong with it.
(174) Another section of the PAT is arithmetic reasoning, but I have never had anyone who has been able to explain to me why programmers have to be good at arithmetic.
(174) The one thing that programming doesn't seem to be in today's world is geometric.
Best test seems to be on the spot skills assessments.
(176) For a programmer who claims to have experience, why not just have him sit down and write a small program or read and interpret a set of specifications, sketching out his approach to implementing them? Why not, indeed? Perhaps it is because we so rarely read programs that this action never occurs to us, or perhaps it is because when we intend to hire an “experienced” programmer, we deem ourselves lucky if even a single applicant shows up.
Good programmers are made, not born, so emphasize creating them rather than selecting them; we can make good programmers by adjusting personality, work habits and training.
(176) “Verbal ability” is as good a measure as we have of academic success in programming, so Dijkstra's intuition is probably a good one. But for actual programming performance, on commercial programs rather than “toy” programs, we lack any aptitude measure at all, except perhaps for general intelligence. For myself, I believe that intelligence has less to do with the matter than personality, work habits, and training. These things, unlike intelligence, can be changed by experience later in life, which turns the problem form one of selecting programmers to creating them. In other words, good programmers are made, not born; therefore we should turn our attention to the manufacturing, or training process.
Humor directed to reader in question for managers about overpaying for an ideal programming aptitude test: compare to equivalent rhetorical technique employed by Kurzweil.
(177) 3. Would you spend $5000 for the package in the ad [for an ideal programming aptitude test]? Or $100 per test? If not, why not? If so, have you been reading this book?
10 MOTIVATION, TRAINING, AND EXPERIENCE
Training and experience improve performance more than attempting to adjust personality or intelligence.
(180) But even though personality can be changed, and intelligence
can be raised somewhat, real improvement in performance has to come
from training and experience.
(181) This residue, after all the other factors are taken into account, is called “motivation.”
Doodling a lover instead of name of programming language used to suggest cultivating love of programming the ultimate motivation.
(181) When the letters were read off in sequence, the spelled S-A-L-L-Y-S-A-L-L-Y. What better illustration could we give of the “inner directing force” which “most of us mean by motivation.”
Increasing driving force motivates performance to a peak then drives it down.
(182) One of the best known and accepted results of motivation research is that increasing “driving force” will first increase performance to a maximum, beyond which addition of further driving forces will quickly drive performance to zero. The rapid fall-off in performance is especially observable in complex tasks, which is why it is so important for programming. . . . Pressing a programmer for rapid elimination of a bug may turn out to be the worst possible strategy—but it is by far the most common.
Top reported motivators are salary increases and bonuses, more personal involvement in task planning, promotions, and more time for quality.
(183) Among software programmers at one large shop, we found that “a salary increase and/or bonus” would “make a large effect on the results my manager would see in getting me to work at a sustained fast pace or keeping me diligently at work.” A very close second, as we already expected from social psychology, was “personal involvement in planning of our task.” Then, tied for third place were the two items--”a promotion” and “more time to give my work a personal touch of quality.”
Motivation studies produce contextual results.
(183) Even if these responses truly reflect differential strengths of outside forces, they represent those strengths in a particular circumstance at a particular time.
Love of programming is the biggest motivator.
Humor expecting that this book will become successful in motivating love of programming so that so many students will student the psychology of programming as for some to so doodle instead of fantasizing about their lovers.
(184) Anyone who has ever seen a programmer at work—any wife or husband of a programmer who has ever tried to interrupt a terminal session or a conference over a bug—knows that programming itself, if the programmer is given a chance to do it his way, is the biggest motivation programming. . . . Someday, I suppose, I will pick up a used copy of this book and find that somebody has circled various letters to form F-O-R-T-R-A-N-F-O-R-T-R-A-N.
TRAINING, SCHOOLING, AND EDUCATION
Confusion between schooling, education and training hinders educational progress.
(185) One of the confusions standing in the way of educational progress is the confusion between schooling and education. Another is the confusion between education and training.
Necessary training to acquire specific skills to use technologies may involve trivial content.
(187) Now, why is it so important
to get across such trivial material, anyway? Unfortunately, although
the intellectual content of the material is not great, failure to
learn it absolutely impedes further progress in learning to use the
operating system. Which brings us to our second distinction—education
versus training. Roughly speaking, by “education” we mean
acquisition of general principles and skills, and by “training”
we mean acquisition of specific skills.
(187) But more important, education may be impossible without certain training as a prerequisite.
Example of difficulty acquiring skill in JCL syntax blocking operating system education.
(187) In summary, then, the difficulty of acquiring skill—training--in JCL syntax creates a barrier that blocks further progress in operating system education (and incidentally creates an elite group of JCL “experts” upon whom other programmers remain slavishly dependent). This barrier cannot be removed by lecturing about it, but it can be removed by putting the learner in a situation where the machine keeps giving him the experience he needs.
FORCES AGAINST LEARNING
Propensity for learning in children seems innate, though undirected; adults impeded by negative forces such as fear of others witnessing failure.
(188) To a surprising degree, the only time we fail to learn is when
there are negative forces set up against it. . . . If we could
observe children learning, however, we would see that any child
really left to his own devices will learn vast numbers of things—not
necessarily the things we want him to learn, but vast numbers all the
(189) With adults, however, the barriers to learning have usually become internalized, and the average adult learns very little if left to his own devices.
(189) Most often, however, the fear is not so much of failure itself, but of having other people witness the failure.
Private learning environment using a terminal counters fear of observed failure, hinting at how personal computer revolutionized learning programming.
(189) To the extent that this observation applies to the learning of programming skills, we might expect that initial learning of, say, a new programming language would be be done when cloistered with a terminal—and when no record is kept of mistakes.
Beginning learners must master mechanics, like when playing pinball.
(189-190) For beginners, or amateurs, the difficulties with syntax, keying, and such auxiliary operations as job control usually far outweigh any deeper difficulties that might arise from subtle semantic points or from the problem itself. . . . Careful observation of terminal use by programmers in different stages of development and working on different types of problems will be necessary if we are to design systems that are best for initial learning and best for later use.
Ease of learning versus ease of use seldom evaluated; need to focus on extensibility of techniques.
(190) Precious little of the controversy over diverse programming languages and systems ever touches on the distinction between ease of learning and ease of use. There is no particular reason why a feature that is easiest to learn will be easiest to use in the long run. The important concept here is that of extensibility of a technique—is it applicable to situations other than the one for which it was first learned?
Competence in one language or dead-end technique often impedes learning new ones; consider Rosenberg discussion of Python written like Java.
(191) For the programmer who has mastered certain dead-end techniques (or dead-end programming languages), new learning requires that he give up, at least temporarily, some current satisfaction. . . . Just as the traveler is embarrassed by the way little children speak better French than he, the experienced FORTRAN programmer feels his power slipping away when he has to ask one of the trainees about some simple syntactic point in PL/I.
Direct impediments to learning of fear, expectation of failure, reluctance to admit weakness accompanied by indirect impediments of knowing what to learn or how; the latter have been institutionalized by absence of everyday programming instruction in school.
Link criticism of Papert undirected exploration to indirect impediments of not knowing what or how to learn.
(191) The fear of new things, the expectation of failure, and the reluctance to admit weakness all have a direct retarding effect on learning, whether in a formal classroom situation or on the job. Other problems arise indirectly, most often from an inadequate perception of what has to be learned or how to go about learning it.
Problem of under or overestimating difficulty of problems arising from unfamiliar situations, often by poor teachers giving wrong impression of the difficulty of the subject matter.
(191-192) When face with a problem arising out of some unfamiliar
situation, there are two general errors we can make—either we think
the problem is harder than it really is or we think it is easier than
it really is. A poor teacher is not usually poor for lack of mastery
of the subject matter—subject matter is commonly in books or other
sources, which the students can peruse for themselves. The poor
teacher may give his students the impression that things are too
easy, perhaps by being too smoothly prepared so that they do not see
the difficulties underlying his examples. Or, he may choose
intentionally simple examples to highlight certain points and, in so
doing, give the impression that in real problems things always seem
to fall into place.
(192) On the other hand, the same teacher had been guilty of making things seem too hard for other students. At the end of one lecture, finding himself with an extra ten minutes, he attempted to show them a problem he had been working on in his own research. . . . These students were discouraged from even trying the homework.
HOW TO LEARN PROGRAMMING
Prepare for learning programming by knowing personal assets and liabilities, favored modes of perception, media use habits, learning by doing or discussing with others, and work habits.
(193) The first step in learning
how to learn anything is to learn your own assets and
(193) This individual attention is precisely what the self-taught student gets automatically, if he but has the self-sensitivity to use it. For instance, every modern theory of education recognizes the existence of favored modes of perception. . . . Most people have an awareness of whether they favor auditory or visual presentations for learning, but few use this information in charting their own educational plans.
(194) The individuality of the learner is not only reflected in his passive acceptance of information from a book or lecture, but also in the activity he performs while using these media.
(194) Another important dichotomy is between people who learn by doing—by working problems, writing programs, and so forth—and those who learn by by discussing problems with other people.
(194) One final area in which idiosyncratic learning methods should be studied is that of work habits.
(195) Indeed, even in schools the quest for efficiency is often carried beyond any reasonable need. Why, for instance, must all students be forced to work on the same type of terminal, the same type of coding pad, or with the same type of pen or pencil?
Learning as active pursuit entails taking broad look when programs are running and specific lessons when not; suggestion of break between engagements for reflection.
(195-196) When learning to program, there are two times when one
should actively pursue learning—when the program runs and when it
doesn't run. When it runs is the time to step back three paces and
take a broad look at what has been accomplished. . . . It might be a
good practice for management to give the programmer a day off when
his project is “finished,” not so much as a reward but as a
change to get a little perspective.
(196) When our program does not run correctly, we have the opportunity to learn more specific lessons.
test cases for active learning discovering problems, developing
feeling for the critical case.
(196) If, after a reasonable amount of time trying to understand the failure of the new technique, he has had no success, he should proceed with his “fix,” if he has one. At the same time, he should construct a test case that will enable him to discover why his original approach failed.
(197) Possibly more important, however, is the chance that by the mere act of constructing the test case we shall discover the problem.
(197) In the construction of “learning cases,” the programmer has to develop a feeling for the “critical case”--that is, the case that is just like the case at hand except for one critical difference. Through the contrast between these two cases, he learns precisely how much discrimination he must make—neither more nor less.
Improving improvement by training programmer to use tools for further learning rather than get embedded in morass or detail or hate the tools.
(197-198) To implement such an active program of learning, the programmer must already know quite a bit. If, for example, he does not have sufficient proficiency with his programming language to make the construction of a critical case a relatively simple and foolproof affair, he will quickly become embedded in a morass of detail, which he cannot possibly handle on his own. It should, therefore, be the goal of formal educational programs to train the programmer to the point where he can use his tools as tools to further his learning. Instead, we all too often find that the formal education has merely served to inculcate in the programmer a hatred for his tools.
Schools of programming resemble general education in reproducing medieval practices; thankfully the computer itself is an innovative teaching system.
Notion that knowing how to learn is key still to learning programming invites undirected methods of computer assisted instruction like Papert proposed; what are other failure paths emerging as technologies change?
(198) The education business is still essentially medieval in its
practices, so why should schools for programmers be different?
(198) The one factor that saves us in the computing education business is the computer itself—ever silent, ever patient, ever teaching the programmer who has but the skill to learn. Perhaps we should set as a goal for our schools merely to leave the students alone, so that they do not turn off to learning before they get on the other end of that log with the real teacher of us all. It my be expensive, it may be inelegant, it may be old-fashioned, but for programmers, computer assisted instruction (but not CAI!) is still the best.
Worker hating tools points to poor management again; compare to Latour on using obsolete tools for critique.
(204) Working with defective or poorly designed tools, even the finest craftsman is reduced to producing inferior work, and thereby reduce to being an inferior craftsman. No craftsman, if he aspires to the highest work in his profession, will accept such tools; and no employer, if he appreciates the quality of work, will ask a craftsman to accept them.
11 PROGRAMMING LANGUAGES
PROGRAMMING LANGUAGE AND NATURAL LANGUAGES
Hockett 13 design features of human natural languages begins with vocal-auditory channel, from which programming languages differ as natively written.
(207) The first of thirteen features which he lists is the use of a “vocal-auditory channel.” . . . Programming is generally a manual operation—we laugh when someone asks us to “say something in FORTRAN.” It is a written language, and in spite of its resemblance to other written languages, it differs from them in not having a speech system behind it.
Prevalence of chalkboards, now whiteboards to make it easier to talk about programming languages, relates to rapid fading feature.
(207) One effect of not having a spoken form of a programming
language is a possible slowing down of language innovations, for the
spoken form of the natural language is most often the source of new
language forms. Another effect is the difficulty with which we can
talk about a programming language without a blackboard or pencil and
paper. Every programming office should have a blackboard, chalk, and
(207) The second of Hockett's features is “rapid fading.” We need many erasers because what we “say” about a program on a blackboard does not erase itself the way an utterance does.
Programming shares with prayer opposite of design feature of directional transmission and broadcast reception.
(207) The third feature is “broadcast transmission and directional reception,” which means that we speak more or less in all directions at once, but we can detect, when listening, form what direction the speech is coming.
Interchangeability not shared in the translation from human readable programming languages to machine language and the ensuing responses, especially when misunderstandings occur.
(207-208) Probably the really important difference between
programming languages (of today) and natural languages lies in
Hockett's fourth design feature—interchangeability. . . . When we
talk to our computers, unhappily, we are usually speaking in
different tongues. Here, at least, for all their other faults, the
machine languages have the upper hand, for at least a dump looks a
little like the stuff we put into the blasted machine. Not so—not
nearly so—when what we put in was FORTRAN or COBOL. How truly sad
it is that just at the very moment when the computer has something
important to tell us, it starts speaking gibberish.
(208) At the extreme of this problem is the case of the man who can read COBOL programs but cannot write them. Probably, he cannot discuss them, either, which makes for most difficult communication problems if he is, say, a programming manager.
Programming languages measure up with natural languages in the remaining nine features Hockett enumerates.
(208) In Hockett's remaining design features, programming languages do seem to measure up to natural languages—actually going beyond them in the exhibition of such features as productivity, the ability to express something that has never been expressed before.
Bruner six functions can also be identified in programming languages, with qualifications, being largely referential and connotative; development of OOP extends.
(208) [Jermone] Bruner
gives six general functions of
natural language—emotive, connotative, referential, metalingual,
poetic, and phatic. Although we can identify each of these in
programming languages, their relative importance and frequency of use
is quite different.
(209) A programmer would not really be a programmer who did not at some time consider his program as an aesthetic object.
(209-210) The prose of programming consists largely of referential and connotative parts. . . . But here we should note that, although both are common in natural and programming languages, the universe of discourse is much, much smaller in programming.
Metalanguage utterances now formalized for many programming languages.
(210) Metalanguage utterances—talking about language—are of primary importance in programming, especially in the learning process, when programming such things as compilers, and when designing and defining programming languages. Until recently, programming languages differed from natural languages in that they relied exclusively on natural language as a metalanguage—with the possible use of a little mathematics.
PROGRAMMING LANGUAGE DESIGN
Each new language reveals flaws of previous ones as well as shifting standards.
(211) We do not know whether the language designers are geniuses, or we ordinary programmers are cripples. Generally speaking, we only know how bad our present programming language is when we finally overcome the psychological barriers and learn a new one. Our standards, in other words, are shifting ones—a fact that has to be taken into full consideration in programming language design.
Evidence of concurrent synaptogenesis and technogenesis in development of computing machinery.
(211) Whenever a man is confronted with a new machine, he is forced to choose between making some adjustments himself or adjusting the machine to narrow the gap between what is desired and what exists. Although machines, and especially computers, are adjustable, the time scale for them to be changed is generally much longer than for a person. Programming languages are attempts to adjust the raw computer to better fit human propensities and limitations, but they too suffer from a long update cycle.
Flexibility of humans required to adjust to inflexible machines.
(211-212) Humanists often contend that machines tend to dehumanize people by forcing them to have rigid personalities, but really, the contrary is true. Because the machines are rigid, the people who use them must—if they are to be successful—supply more than their share of flexibility. . . . Relationships in which one party does all the giving or all the taking are not fully human, and tend to produce personality distortions in one or the other.
Desire for teaching common programming principles not tied to particular languages, though schools prefer artificial instructional languages, which creates problem of equivocating amateur and professional principles in language design.
(212) Perhaps this situation could be improved if we could enunciate
and teach certain principles that are not tied to particular
languages, so that even the beginner would have some less relative
measure to hold up against the language he is learning. . . . the
schools seem devoted to teaching how to program in a single simple
and artificial language.
(212) But when the language designers begin to believe that the principles underlying the design of an amateur's language are the same as those upon which a professional's are based, then we have trouble.
Need to observe programs being made, however programmers seldom reflect on their activities; contrast pessimism of Kittler to promise of critical programming.
(212-213) To understand the psychology of programming languages, we shall have to do more than read programs—we shall have to observe programs being made. . . . One reason for these complexities is that the programmer himself seldom knows why he does what he does—which is a general problem in the study of any human behavior.
Programming as communication between alien species.
(214) In is a psychological difficulty which prevents us from writing our problem specifications directly in machine language. Let's face up to it: people don't think the same way that computers do—that's why we use computers. Programming is at best a communication between two alien species, and programming languages with all their systems paraphernalia are an attempt to make the communication simpler for one of those species.
Give up trying to program in real, natural languages; acknowledge programming languages contributing to Tower of Babel but goal should be adjusted to consonance between the mode of expression and the mind of the expressor.
(214) To make progress in programming languages, we must first give up the holy grail of trying to program in “real” languages, for programming languages can never be the same as human speech. We may then transfer our quest to making programming languages more “natural,” not in the sense of being identical to English or some other culture's contribution to the Tower of Babel, but in the sense of a consonance between the mode of expression and the mind of the expressor.
12 SOME PRINCIPLES FOR PROGRAMMING LANGUAGE DESIGN
Psychological principle of uniformity applied to programming languages: predictable actions and syntactic constructions.
speaking, the principle of uniformity in programming language design
might be stated thusly: “The same things should be done in the same
way wherever they occur.”
(220) Another important aspect of uniformity is that the same syntactic construction should not mean different things in different contexts.
Recognize both physical and psychological ambiguity, for example confusion over right-to-left resolution in APL, although programmer choices over variable names more typical, such as using language keywords and choice of mnemonic names.
(222) What needs
to be done about ambiguity is to recognize that there are two
types—physical and psychological.
(223) Ken Iverson, the inventor—the developer—of APL, once told me that APL's “right-to-left” rule for resolving ambiguity was “more natural” than the rules used, say, in PL/I. . . . From an introspective point of view, I can sat that I have never entirely come over to a right-to-left way of thinking, after writing perhaps 400 APL programs.
(223-224) Not all of the blame lies with the language designers—individual programmers can be far more guilty of this sin. For example, choosing keywords as variable names means that the name is used in a nonuniform way in the program, which certainly confuses the task for anyone trying to read the program.
(224) But the major source of programmer nonuniformity remains the choice of mnemonic names.
Benefits of chunking possible in programming by offering more than one way to express the same thing via iteration, subroutines, and data structures; hints at future advantages of OOP.
In psychology, this information processing ability of human beings
that combines several small units into one large unit, which is just
as easy to handle as its individual parts, is called chunking.
(225) By providing the user with alternative ways of expressing the same thing, however, the language designer gives the programmer a chance to do another kind of compression.
(226) Iteration, of course, is the most basic of the compression steps possible in programming—it was known to Lady Lovelace, and without it modern computers would essentially not be possible. Functions—such as SUM—were also a concept known to our first programmer and, although they are not conceptually as important as iteration, they are probably more important from a psychological and practical point of view.
(226) Another source of compactness—newer, in use, but perhaps ultimately more powerful than iteration or subroutine definition—is data structuring.
Example of compression of inferential steps from higher level results implicit in lower level operations, linking chunking to procedural rhetoric.
(227) Another way in which appropriate data structures lead to
compression is by causing lower-level operations to have higher-level
results. For instance, if we are processing a sorted file in
sequence, the assumption that the records are in order permits us to
make inferences about missing records which would otherwise require
(227-228) As there are more and more possible cases, the burden of remembering which is the default can become greater than simply writing the complete specification.
LOCALITY AND LINEARITY
Synesthetic and sequential memories applicable to arrangement of information by programming languages in terms of locality and linearity, which may be achieved though well chosen literals.
A properly designed programming language can help the programmer in
the same way that a good memory can—by keeping the relevant
information close at hand.
(229) Two types of human memory that interest us in this regard are the so-called “synesthetic” and “sequential” memories.
(229) In a program, the concept of “locality” corresponds to synesthetic memory, and the concept of “linearity” corresponds to sequential memory. By locality, we mean that property that obtains when all relevant parts of a program are found in the same place—one the same page, perhaps.
(230) The ability to use literals is a big help, because all that we need to know about a literal is contained within its name. The use of well-chosen mnemonic names can have the same effect, if it helps the reader to remember what he needs to know about the variable without referring to the place it was declared.
Example of non-locality in PL/I ON-unit to obtain linearity, which experimental evidence suggests is easier to handle than branching or looping sequences; consider implicit form of GO TO in event-driven GUI forms programming as factor in complicating understanding.
(231-232) The ON-unit of PL/I represents a particularly interesting case of non-locality, because the basic function of ON-units is to permit us to obtain linearity. . . . Experiments with problem solving in programming-like situations indicate that a series of decisions arranged in a strictly linear sequence is typically easier to handle than a branching or looping sequence. Experience with programming languages seems to bear this out, for programs with numerous GO TO statements or other branches are notoriously difficult to understand or debug.
High-level language features mask nonlinearity of machine level organization from programming language level presentation.
(232) Many higher-level language features can help us mask the nonlinearity of the typical stored-program machine. The IF statement, which allows the statement to be executed to be attached to the IF; the DO or BEGIN, which allows us to group several statements as one under the THEN or ELSE clause; the logical connectives, which enable us to group decisions under one IF statement; the iterative DO, which permits us to eliminate explicit branching; the array operations, which enable us to eliminate explicit iterative DO loops; the ON-unit, which permits us to handle the exception condition without even mentioning it, or even thinking about it—all these and other features help to banish the nonlinearity from a program.
TRADITION AND INNOVATION
Consonance of new languages with other programming languages and rules of natural language crucial for learning and debugging; example of confusing rules for blanks in FORTRAN, spelling in general, and advantages of noise words in COBOL.
(233) By making a programming language
in some sense consonant with the other languages the user is likely
to know, we may simplify his entry into its strange new world.
(233) When the programming language is not in consonance with these natural language rules for blanks, it may be more difficult to learn, or at least more difficult to debug.
(234) Another area in which programming languages could be more consonant with natural languages is spelling.
(234) Noise words in COBOL are one example of flexibility which permits the programmer to achieve some additional feeling of consonance with English.
Psychological phenomena of proactive and retroactive inhibition occurs when languages differ slightly, like slight syntactic differences between C, Perl, PHP.
(236) If the languages are slightly
then the psychological phenomenon of inhibition
occur. . . . Proactive inhibition occurs when the similarity of
earlier learned material interferes with the learning of later
(236) The retroactive inhibition also depends on the similarity, but it works on the previously learned language. Thus, typically, the FORTRAN programmer who has learned PL/I finds it difficult to go back to writing FORTRAN programs—and not just because some time has elapsed.
Examples of language adaptability including definition of functions and data structures, compile-time facilities, and dynamic code generation at execution foreshadow OOP.
(236-237) One familiar example of such adaptability is the ability to define functions and other subroutines. Another is the ability to define new data types—structures and lists, for example. Some languages permit the definition or redefinition of operators, but these are, after all, just another type of function. Finally, there are languages with more elaborate metalanguages—compile-time facilities, for instance, or dynamic generation of code at execution—which can permit changing the entire face of the language.
Caution that too many adaptive devices close off programmer from peers due to enhanced role played by system substantiating meaning.
(237) Programming is not just communication between one man and a machine. Other people will probably have to read and understand the program; but if the use of adaptive devices is too extensive, the program may be as closed to them as is the private language of a schizophrenic.
SPECIAL-PURPOSE, MULTIPURPOSE, AND TOY LANGUAGES
Critical to limit universe of discourse when designing special-purpose languages.
(238) Limitation of the universe of discourse is so important for the design of special-purpose languages that it should be the first and most carefully considered step.
Claims programming languages shape thought processes; example of ineffectiveness of COBOL programming teams building online systems.
(238) One reason why the limitations are not as obvious to users as
they are to nonusers is that the programming language does indeed
shape thought processes.
(239) To the extent that special-purpose languages act as limits to thought in this manner, they are harmful to the user who potentially has larger problems to solve. The situation with COBOL is particularly instructive.
(240) However, the fact that COBOL was successful in getting nonprofessionals to writing programs in the sixties is proving to be an impediment to progress for the seventies. A crew of COBOL programmers is not, in general, an asset upon which an installation can build, say, on-line, fast response systems.
Fisher Fundamental Theorem of Natural Selection cautions that special-purpose languages may produce unadaptable programmers, which must be taken to heart regarding languages used for learning programming; can the same argument be made concerning the equivalent of special-purpose languages in the procedural rhetorics required to operate complex applications?
In fact, this is another example of Fisher's Fundamental Theorem of
Natural Selection. The professional programmer cannot afford to get
into the trap of being so adapted that he is not adaptable, but we
don't necessarily know in advance who is destined to become a
professional. Only by studying the ways in which special-purpose
languages adapt to their special circumstances do we have any hope of
understanding what will be involved in reshaping thought processes if
it is necessary to create a professional from an amateur or
(241) let's stop churning these languages out of our foreheads like full-blown goddesses and develop them in an environment where sound behavioral principles can be used in their design and testing.
High rate of programming language invention in early 1970s necessitates turning theoretical attention to dialogic aspects, realizing it is the study of human behavior, contra Ong, not just symbol manipulation; supports Suchman and others who emphasize situated, contextual factors.
(242) If my extrapolations are correct,
in 1972 programming languages will be invented at the rate of one a
week—or more, if we consider the ones which never even make the
literature, and enormously more if we consider dialects.
(242) Only when the theoreticians turn to the “dialogue” aspects of programming “language” will they finally be forced to recognize that they are note students of symbol manipulation, but of human behavior.
13 OTHER PROGRAMMING TOOLS
Psychological studies neglect programming tools.
(246) Yet these tasks are even more neglected from the psychological point of view than are programming languages. In the following sections we shall try to suggest how certain insights could be used to better the design of tools for debugging, for management of operations above the program level, and for documentation.
PROGRAM TESTING TOOLS
There are no small errors or relationship between size of error and problems it causes.
(247) In reality, there are no “small” errors, since even a “single hyphen” can result in disaster. The nature of programming being what it is, there is no relationship between the “size” of the error and the problems it causes.
View testing in terms of confidence and challenging social tendency to believe things are as people want them to be.
(247) The ideal
testing tool should give us confidence in our program exactly
proportional to the confidence it deserves, so that we neigher pass
on a program containing errors nor continue probing a program which
is error free.
(247) It is the nature of people in our society to believe that things are as they want them to be, so a program testing tool must struggle to show us things as they are.
Simulating bugs difficult; depend on uniformity, locality and compactness of program.
(248) Although we
cannot introduce program bugs which simulate real bugs as well as we
can simulate real aircraft on a radar screen, such a technique could
certainly be employed both to train and evaluate programmers in
(249) Thus, the best possible testing tool must be based both on a language and a program structure with a high degree of uniformity.
(249) In a similar way, we can argue that lack of locality and lack of compactness make a program more difficult to test. But is there some way a testing system could measure the uniformity, locality, and compactness of a program?
Bias on early data returns, reluctance to regression test following small changes countered by automatic test suites; problem of volumnious results addressed by summary indicators (Rosenberg).
well-known psychological bias in observation is the overdependence on
“early” data returns.
(251) One such system in use today is particularly designed to counteract the temptation to skip retesting when a “small” change has been made to the program. If the test cases are stored in the system and can be rerun automatically on demand, the programmer is less likely to skip the retest. The typical system of this sort, however, produces vast amounts of output. It is hardly useful to rerun test cases if nobody looks at the results of the rerun.
Problem of lock in during debugging.
(251) As simple as this sounds, that is how difficult it is to get the programmer to look in a different place, once he has “locked in” on the wrong one.
Common reaction to the seminar is shock at extent personal experiences of office life resembled examples and even extreme caricatures drawn out for instructional emphasis.
(277) A typical remark made a year after attending a seminar is: “It was pleasant enough talking about those things, but then I began to see what was going on at the office. Wow!”
In early 1970s no hesitation to equivocate machine and brain operation by sharing metaphors; interesting that Weinberg deploys them to draw attention away from technical details to the psychological component.
(277-278) So rather than be concerned so much about that computer operating system, the reader who has really been touched by this book will start to work on the operating system he carries around in his own central processing unit—his head.
In the final pages of the epilogue to his famous Psychology of Computer Programming, Weinberg warns of the danger of banality of evil through unwitting use of programming talent, though made in ironic, innocent ignorance of the real involvement of IBM in the holocaust with which my tale opens, that Lanier argues lurk in siren servers; is this a reflection of the need for a renewed critique and distancing oneself from technology?
(278) Because computers are such fascinating beasts, because programming is such a game, such a joy, we who program computers are in danger of becoming the unwitting pawns of those who would use our toys for not-so-playful ends. Can there be any doubt that if Hitler had computers at his command, one of the first application would have been keeping closer track of Jews and Gypsies so that all who should have gone to the ovens did go to the ovens?
Bad systems can be built by well intentioned people.
(279) But it is naive, I now realize, to expect that bad systems cannot be built by people with good hearts.
Tyranny over liberty seems to be the default trajectory of the specific milieu in which our computer revolutions have occurred, in spite of the good intentions of those we salute as the architects of the information age.
(279) We stand at the brink of a new age, an age made possible by the revolution that is embodied in the computer. Standing on the brink, we could totter either way—to a golden age of liberty or a dark age of tyranny, either of which would surpass anything the world has ever known. Perhaps no individual's efforts will make any difference in the result, but we must never cease trying, for then the result is sure to be tyranny.
Weinberg, Gerald. The Psychology of Computer Programming. New York: Van Nostrand Reinhold Company, 1971. Print.