"Can you imagine -- the Berlin Wall breached! Free elections in Poland and Czechoslovakia! The Soviet leader proclaiming freedom of religion while visiting the pope! The Romanian dictator getting frosted on Christmas Day! Bush found the whole sequence of events unbelievable, dizzying, even a little bit frightening -- and yet, unquestionably, the fat lady had opened her mouth and was hitting high C."
-- Jamie Malinowski
"Gee," the president marveled in his trademark nasal whine and 1950s sixth-grade vocabulary, "it seems like it was only yesterday that their Premier was making trouble all the time and saying he was gonna bury us and stuff, and now their whole darn evil empire looks like it's coming apart. Just look at what's happened with their Mac products and Turbo Modula-2 and Turbo Basic. And what was that business at the SD '90 conference about Wallsoft's C compiler? Why'd they let a competitor speak at their press conference? Well, they must have got some bad Perrier down in Scotts Valley.
"It's pretty neat for us guys, that's for sure," he told Steve "Wally" Ballmer, his squeaky-voiced confidante. "Now maybe the press will talk about that instead of always picking on us about our problems here at home or our problems with our so-called buddies at IBM." Blood brother oaths sworn in the childhood of the industry didn't seem to mean much in these grown-up days.
Chastened by this thought of the challenges that still lay before him, the president frowned at his long-time friend. "Gee. It's tough being big, Wally," he said.
Having joked about bugs as drugs in my February "Flames," I was interested to see that familiar DDJ author Do-While Jones was speaking about debuggers as a drug at Miller-Freeman's Software Development '90 in February.
"When you get sick," Jones said, "you should take medicine until you get well. Then you should stop." When your software is sick, he reasoned, you should use a debugger to find the problem. When you find the problem, you should put the debugger back on the shelf.
Debugger abuse, Jones says, comes from using a debugger when the program really isn't sick. Sick programs include those inherited in a messed-up state from someone else, and your own programs when they quit working suddenly, perhaps due to a change in the hardware or compiler or operating system. If something like this isn't wrong with the program, you shouldn't use a debugger, he says, because you will get hooked, starting a cycle of abuse: Dependence on a debugger makes for weak programmers who write sick software that can't be debugged without a debugger.
His point is that you usually don't need a debugger, that your knowledge, skills, and insight into the structure of the code constitute the best possible debugger. But you can't use your knowledge of the structure of code that has none. Writing well-structured programs is the prerequisite to rediscovering "the lost art of debugging."
"As Jones describes it, the lost art is one of analyzing data flow. In a hierarchically structured program, modules at one level invoke modules at the next lower level, passing data to them, typically as parameters, getting data back, possibly as function values. Debugging a program consists of examining this data flow. The techniques he describes shouldn't be a revelation to any DDJ reader, but the kind of rigor he promotes in their use is perhaps uncommon.
You can test the data flow into and out of a module by writing a driver for the module. The driver sends selected data to the module and examines the results. This tests the module in isolation, but doesn't reflect its interaction with other modules.
For this, you need an integration test driver that calls the module one level higher than the modules you want to test. Data values are fed to it in order to check the interaction of the modules it invokes.
Finally, you can substitute a diagnostic module for any module in your program. A diagnostic module has the same name and parameters as the real module, but has a body that is simple and diagnostic. That is, it isn't so complicated that it could reasonably be a source of errors, and it does nothing but give useful information on the data-passing structure of which the module is a part.
In making his point, Jones used the word "hacker" to refer to one who pokes at the problem more or less at random until finding a fix that works. The word has a range of meanings, some good, some not, and this use is a legitimate use from the pejorative end of the word's meaning range. It was interesting, then, to find that he espoused a distinctly hackerish philosophy in another talk at SD '90.
This was a discussion of the difference between engineers and computer scientists. Most of what he said was uncontroversial: Engineers are typically better educated in the physical sciences, computer scientists better grounded in a variety of programming languages. But the key differences, he said, are philosophical. Computer scientists and engineers have different ideas of economy; engineers are trained to look at the whole system, while computer scientists see the hardware as the platform, that is, as a given; computer scientists want to apply the best algorithm for the task (and are better equipped to do so), while engineers let the task dictate criteria for acceptability of an algorithm.
Jones is an engineer, and presented the engineering approach as the more hackerish, the more ad hoc of the two: Solve the problem no matter what. Here are some of the kinds of ad hoc, hackerish things Jones was saying:
Flexibility is a good trait for any software developer to cultivate. Do-While Jones is a Department of Defense engineer, like many who push bits for a living. One speaker at SD '90, William Roetzheim, speculated that half the software engineers in America were now or would be at some time in the future writing to DoD specs. Well. I don't relish the thought of anyone losing his or her job, but I am skeptical. This would not seem to be the best time to begin learning Ada.
"Stop talking of war cause we've heard it all before. Why don't you go out there and do something useful?"
--Sinead O'Connor
The image: The development team as bureaucracy, ideas trampled under political arguments, progress held up by mandatory progress reports, brilliant developers brought down to the level of their feeblest teammates.
The reality: The same thing, all too often. There appear to be excellent reasons to fear and to loathe the development team, and to long for the freedom to just write the damn thing. We all know the stories of the lone programmers who created masterpieces. It may be unrealistic to think that large software projects can be done any other way than through development teams, but it can be an inviting fantasy.
And yet, there are the stories of the team that worked. And most have even experienced that golden time, when the team fed off each others' talents and the result was a collaboration none of the participants could have done alone, and that all were proud of. OK, maybe it was only the Pringles can sculpture that we built on the Dean's front porch when we were freshmen, but when it comes to that sense of shared ownership of the work, is building Pringles can towers any different from writing for Presentation Manager?
The toughest problems usually turn out to be the ones involving other people. What we suspect seems to be true: Group dynamics may be the most important factor in software development group success. As Richard Cohen, speaking at SD '90, said "software development productivity is more strongly affected by people- and team-related issues than [by] any other variable under the management's control."
And teams are increasingly going to be where it's at. Programming in the large is -- err -- getting bigger. Ken Orr maintains that coding skill grows less and less important as the project gets bigger. "For people trained in good software engineering approaches, writing individual programs that aren't very large or complex is not a critical skill. On the other hand, the planning, architecture, requirements, and design of large suites of data files and programs (programming in the large) are critical skills [and] will become more so. The need for software engineers will remain acute, but increasingly these people will be writing systems, not programs."
If programming in the large is the task of the future, team programming is the paradigm of the future. Cohen nailed down what may be the essence of how successful teamwork feels: "A real team," he said, "is one in which the group feels common ownership of the problem and its solution." Many speakers at SD '90 talked about problems involved in team programming, managing software engineering projects, programming in the large. I didn't catch all their talks, but after the conference I sifted through the proceedings and my notes, and found that many of them dealt with the search for ways to achieve that sense of common ownership of the work.
It's an important search. Changes are afoot, SD '90 speaker Tim Twinam says, and the customer may well start calling more of the shots. The free ride of the Trappist technician may not end this year, but there is an inherent instability that will some day shake out.
Vern Crandall and Larry Constantine have given some thought to the group structures conducive to good teamwork. Crandall, who worked at Novell, claims that fresh thinking is required in this area because most of the old answers, the software methodologies, including Orr's data-structured system development (DSSD), were developed for MIS development work, not for commercial software development. "We need a product-oriented approach," he said.
He lists some of the issues that are unique to or more important in commercial software development than in MIS:
How do you achieve this? Crandall has some suggestions: No individual team should be larger than six people. Products should be staggered, not sequentially released. Testing and maintenance are skills; hire testing and maintenance engineers, not testers, and pay them as much as the development engineers. Most of the existing models for a product life cycle are too long; you need to run in parallel as much as possible. In particular, software development, testing, documentation, and human factors (such as screen design) must run in parallel. This demands a lot of communication and a lot of freedom of movement, and that demands careful structuring of the teams.
Larry Constantine is a pioneer in the development of structured programming and structured design. He gave three talks at SD '90, and in one of them defined what he calls the "structured open team." It's apparently what Crandall is describing. "The structured open team uses formal structure to increase internal flexibility and adaptability while maintaining simple, external interfaces and behavior. Internally, it is structured to function as a tight-knit, closely integrated team of professional equals with clear differentiation of functions only as necessary for effective functioning." One of the key aspects of the structured open team is the default assignment of responsibility. Responsibilities can be shifted around as people's skills and knowledge and interests (and the changing demands of the job) require, but there is always a default assignment of responsibilities to ensure that nothing falls through the cracks.
One of the key steps in developing a software product is testing. Testing is naturally more complex in multiprogrammer projects, but Crandall turns up a surprising fact: Few schools offer any training in testing. Roetzheim, though, pointed out that testing is an important element of DoD specs. Maybe more programmers will be using DoD specs than I speculated earlier. Some companies today write to DoD specs in certain circumstances even when not doing Defense work.
But the most compelling point to come from these talks is that it is the human issues that are critical. Cohen listed some of the human traits that any software development team must deal with:
It was P.J. Plauger who sounded the contrarian note. There is always danger in accepting the common view uncritically, and there seems to be some sort of common view of good software management emerging (which is not to say that good software management is emerging). Plauger offered, for the stimulation of software management thinking, his contrarian list of software management heresies:
Drugs, Bugs, and the DoD
Taken together, the talks make a point at a higher level. On the one hand, structure your code so that you can debug it by hand, and structure your approach to debugging. On the other, get the job done, meet the target launch date, satisfy the client. Together, the talks say simply, suit the tactic to the task. Every programmer should have a rich collection of ways of approaching a problem -- a full set of intellectual tools. Structure is essential but so is flexibility.The Big Challenge of Programming in the Large
What's The Secret?
At least six groups of people must all work together well to make the project come off: Marketing, software development, software testing, software maintenance, documentation, and human factors. This is a complex, interrelated system of individuals with different skills and interests, all pushing to meet a common deadline that is invariably too tight. Crandall claims that flat and network management structures don't work in such an environment. He points out, furthermore, that software developers are creative people and that rules, regulations, and restrictions need to be kept to a minimum to avoid stifling their creativity. He hails the benefits of consensus management in maintaining the flexibility needed to let creative people solve problems together. But the flexibility and creativity can cause the developers to get off track, so a lot of supervision is necessary, as well as a lot of encouragement and direction. He thinks that a hierarchical structure and an emphasis on accountability, challenge, and expectation is ideal.
The last point is a particularly good one for managers to keep in mind: People do care about quality and will work harder and better when they feel they are working on a product they can take pride in.
Plauger justifies these heresies convincingly, but I think they are more useful if you are allowed to supply your own explanations.