Saturday, October 4, 2008

I, Programmer: the Three Laws of Software Engineering

When teaching the third year undergraduate course on software engineering at the University of Victoria, I begin by asking students if they can define the topic of study, software engineering. Many of my students are in a formal engineering degree program; others are computer science majors within the Faculty of Engineering. Surprisingly, they struggle to offer a satisfactory definition of what it is they are studying.

So we start with engineering, which I take to be the building of useful tools for humanity. From this it must follow that software engineering is, by means of computer programming, the building of useful software tools for humanity. But isn’t that just programming? And how is this different than computer science? As we shall see, it is all about the assumptions we make about how the programming is done.

A common public misconception is that computer scientists design and build computers, when in fact that is the job of computer engineers. Computer science is about software: the mathematics of computation, and the science of abstraction. Eminent software engineer Fred Brooks suggests that the scientist builds things in order to study, whereas the engineer studies in order to build things. He further postulates that by any reasonable criterion, computer science is engineering. However, the folk wisdom is that computer science is to software engineering as physics is to electrical engineering. This is only half-true, for if it was completely true then most practicing electrical engineers would have a degree in physics and not engineering.

Who are the software engineers that write all those software tools we enjoy using on a daily basis? Typically, it is not formally trained engineers. The vast majority of computer science graduates are the ones that end up in careers as software engineers, writing practical software applications for other people to use. This anomaly led to a minor controversy in North America regarding the use of the title Engineer to describe what it is exactly that computer scientists do for a living. In fact, I can probably expect an injunction from one or more of the governing bodies of Professional Engineers for my improper and publicly misleading use of said protected noun in the title of this blog.

Whatever. The truth is, you wouldn’t want to hire any kind of Professional Engineer to create a software tool for you, your neighbor, or even your neighbor’s dog. They simply don’t have the requisite background knowledge and thus would invariably screw it up, blame you, then tell you how much harder their degree was to complete because they had to take physics.

More about this in later blog entries when we discuss the evils of self-taught programmers. For now, let’s summarize.

1. Software engineering is
  • the multi-person construction of multi-version software; and,
  • the name given to the branch of computer science whose research focus is the application of engineering rigor to the problem of building large, complex software systems on time and on budget.

2. Software engineers work in project teams, building programs for other people (the end-user, client, or customer) to use. Software engineering is therefore a social activity: programmers regularly interact with each other, and sometimes (if permitted) with the customer. Good communication and social skills are required.

3. Programming is the solitary activity of writing a computer program. Rather than complete programs, software engineers write small units of code that are combined with the code of other software engineers to create large, complex programs.

4. Computer science provides the knowledge and tools used by software engineers to effectively do their job. To be a good software engineer you need to know more about computer science than is taught as part of any of the traditional engineering specialties (e.g., electrical, mechanical, even computer).

My definition of software engineering (the multi-person construction of multi-version software) is generally attributed to David Parnas, who was actually my professor back when I was an undergraduate at the University of Victoria. Dr. David Lorge Parnas, the man who in 1972 invented the concepts of information hiding, encapsulation, and abstract interfaces, and thus drew the roadmap of modern best programming practices, was certainly the most famous professor I ever took a course with at UVic. I thought it was pretty cool that twenty years later I was teaching the same course at the same institution, using a textbook with an entire chapter devoted to his now famous case study in software design (the KWIK index).

My girlfriend at the time, Lynda, succinctly distilled the entire curriculum of Parnas’ class down to one law: design for change. She remarked that he could have saved us a lot of time if he simply had showed up for the first class and apologized for his lack of teaching skill, but explained that it did not matter because all he really had to say was “design for change.” He then could have handed over the actual work of instructing us on how to put that idea into practice to his competent graduate student and teaching assistant Gord Stuart. (I would later teach with Dr. Stuart at Camosun College. He pretended to remember me.)

David Parnas is undoubtedly a man of great intellect, and one of the most influential professors I have ever met. I still recall the exact moment when, sitting in the dark programming lab in the basement of the Clearihue Building completing a lab assignment for his course, I grasped the elegance of using another programmer's code only through the abstract public interface. I know that must sound silly or, like most great ideas, obvious in hindsight. But what my current crop of undergrads liked hearing about wasn’t the brilliance of his ideas so much as stories about what kind of professor he was. They wanted to know, did Parnas suck?

I first heard of the legend that is David Parnas while on a co-op work term. One of my managers – a jaded, humorous old mainframe programmer at the Ministry of Forests – referred to him as “feisty” and a sufferer of “little many syndrome”. He also insisted that when I returned to school that I take Parnas’ course on software engineering. I was only 20 years old at the time, and didn’t yet know anything about height and its effects on the male psyche; indeed, I can’t really say that I noticed people’s height at all, as everyone tended to just be shorter than me. Short or not, my take is that Parnas simply believed that he was right about everything and didn’t leave room in his mental universe for other opinions, or for very much else other than solving the world’s software engineering problems. He didn’t even know who Bobby Orr was, which should have immediately made him ineligible to work in Canada. This lack of cultural awareness meant that Dr. Parnas lacked street credibility with us, despite his repeated use of the punch line “after he regained consciousness” to describe how he dealt with public dissenters of his one true way to write software.

The great irony is that David Parnas wasn’t a good team player. He was a star programmer and an egoist; an ego-surfer before there was anything to surf. He was also a man of principle, exemplified by his refusal to work on the US Strategic Defense Initiative project. He carried a hanky and liked to blow his seemingly always congested nose during his lectures. I think he was slightly autistic. I liked him.

Superficially, the lower middle-class, suburban, provincial twenty year old students in his classroom (me included) couldn’t relate to him – we didn’t know many people who went to high school in the Bronx, or people that worked in Holland with Edsger Dijkstra, or programmers who wrote documentation in first-order logic, or who wrote cockpit software for the US Navy A6 fighter plane. Nor did Professor Parnas seem to worry about relating to us. He never drew on the board or used any visual cues to convey his ideas. Our textbook consisted of a photocopied spiral-bound collection of everything he (and only he) had ever published, much of which was impenetrable given our lack of intellectual maturity and professional experience.

Despite our immaturity and unbeknownst to us at the time, David Parnas taught us much of what we would eventually need to know about software engineering. In particular, he laid the foundation for a painless transition from procedural to object-oriented programming. After all, classes in an object-oriented language are simply a means of enforcing encapsulation, and object-oriented design looks to decompose a system into modules that each hide a secret (its implementation) that is likely to change. As well, I find myself time and again returning to his concept of the uses hierarchy as a means of defining project milestones as subsets of the complete system.

Parnas’ definition of software engineering tells us both what we should do, and how we should it. The science of software engineering is all contained in the two multis that make up his definition.

Multi-person: the software is written by a team of programmers. Each programmer writes modules (independent compilation units, or generally what amount to classes in an object-oriented language like Java) that are combined with modules written by other programmers to form complete systems. Before any programming begins, the system is designed by decomposition into these modules so that the work can be done in parallel by members of the team.

Multi-version: the software will change over time. Each module should hide one design decision behind an abstract interface. The modules interact (call each other) only through these interfaces since they are less likely (than the implementations they hide) to require modification as the software undergoes transformation due to evolving requirements, new features, and bug fixes. This will reduce the complexity of making changes to the software.

In other words, design for change. Just like Lynda used to say. It is such an important concept that it should form the foundation of our Three Laws of Software Engineering.
  1. A software engineer must design for change.
  2. A software engineer must obey orders given by his or her manager except where such orders would conflict with the First Law.
  3. A software engineer must protect his or her own continued employment, even if this conflicts with the First or Second Law.
As anyone employed for more than five minutes in our industry can attest, managers are always giving orders that lead to conflict with the First Law. The unending pressure to ship the next release of the software means that the Third Law dominates. At this point the software engineer can do one of two things: stick to principles and risk getting fired; or, cut corners and meet the deadline. The art of software engineering is to know when to violate the First Law, and to do it in such a way as to minimize its impact on those who will come to look upon the source code after you have long since moved on to another project.

END NOTES

The difference between science and engineering in the context of software is explained by Fred Brooks in his ACM Allen Newell Award acceptance lecture, “The Computer Scientist as Toolsmith II,” Communications of the ACM, 39 (3), 1996, pp. 61-68.

The definition of software engineering is found in the title of the David Parnas paper “Software Engineering or Methods for the Multi-Person Construction of Multi-Version Programs,” in Programming Methodology (eds. G. Goos, J. Hartmanis), Lecture Notes in Computer Science 23, Springer Verlag, 1975, pp. 1-11.

Dan Hoffman (who followed David Parnas to the University of Victoria) and David Weiss have compiled a greatest hits collection of papers that Dr. Parnas has published over the years as Software Fundamentals: Collected Papers by David L. Parnas, Addison-Wesley, 2001.

The three laws and the title of this entry are of course intended to pay homage to the short stories of Isaac Asimov.

The Lynda I mention was Lynda Wong – a sweet, funny, smart young woman who effortlessly made people smile. It was the spring semester of 1986 when we took CSC365 with David Parnas. We fell out of touch the following year after we broke up, but I was shocked and deeply saddened when I heard of her death in 2006. I wish I had treated you better, Lynda.

0 comments: