8.14.0.4

Prelude🔗

🔗

    Developing a Mind Set

    The Context, for the Instructor

    This Book and Its Parts

    Dear Instructor:

    Acknowledgments

What to Teach

Every undergraduate curriculum in computer science comes with at least one highly intensive software course. In this course, students work on a large-ish project; develop several components that must interact; meet several deadlines; and learn to research for building blocks on their own. It is a course that teaches more than programming but not yet software engineering at scale. It is a course on software development.

In a programming course, students write programs that neither they nor anyone else ever looks at again after the grading is done. A course on software development differs in that students must maintain code beyond the first time they deliver it: react to new test cases; fix bugs; add functionality. Ideally, this revisiting of code should happen several times. Software engineering courses should go beyond code maintenance and cover work in teams, meaning it may involve the entire class as one team; work on extremely large code bases, meaning code that students cannot produce in a single semester; work on problems whose solutions require trade-offs, meaning features vs time, central algorithms optimized for space, time, or energy; and perhaps on special industrial topics.

This book is a guide to the principles of software development for instructors, students, and even developers. As a guide to a software development course, its central premises are as follows:
  • software is a message from one developer to another across time;

  • the students’ programming must account for this “messaging;”

  • the instructor must run a semester-long project that creates stress situations (deadlines, rotating partners, switching code bases) so that (1) students demonstrate “design under pressure” and (2) they learn to appreciate what “messaging” implies.

Concisely put, software development is the first course in the curriculum that puts the human being into the center of activity, and doing so, must become a part of the students’ thinking.

Clearly, thinking is the difficult part of software development, especially expressing thinking clearly and reflecting this clarity in the code. This course aims to implement “thinking” as social processes so

  • developers must pair-program to continuously check their thinking;

  • pairs must submit their work for inspections to avoid “pair think;”

  • students must learn to ask hard questions about other students’ code.

In short, the goal of the course is to develop a mindset that coding is a social process of several dimensions: the immediate pair-programming partner; the review panel; the teammate who takes over the module; the future developer who in two decades from now fixes bugs and adds features. Instructors coach students to develop this mindset of programming socially and in a socially responsible manner.

For working developers, the book is a help if they missed a course on software development in their education. While reading the book isn’t the same as working through the project under the guidance of an instructor, developers should be able to relate the ideas to their hands-on experiences with projects.

Developing a Mind Set🔗

The goal is to develop a mind set about software development that focuses on two imperatives:
  • develop software in a systematic fashion, and

  • develop software with, and for, other developers.

While it is easy and good to act responsibly with immediate colleagues—to be “nice” to them—socially responsible software development really means far more than that. It is about treating the colleagues of the near and distant future as respected partners in a dialogue. They are people who depend on our effort to express our “message” systematically, as clearly as possible—so that we don’t waste massive amounts of their time in the future when a bit of investment on our side will help.

In other words, the two imperatives are intertwined. Systematic software development means a lot of hard thinking, which happens in the developer’s mind. No software tools in even the best interactive development environments check the thinking of a developer. They can’t. It takes another human being to make sure the thinking is on the right track, and that this thinking is systematically expressed in code.

On the flip side is the developer who is tasked with fixing a bug in old code or with adding a new feature. Nobody can fix code without some minimal comprehension of the software system’s organization, the purpose of each of its pieces, and the code in the relevant pieces. It takes time to read and comprehend code—often much more time than the fix or the addition itself. Although some emerging software tools can assist with the mechanics of this task, systematically developed code and thinking properly presented as code has a huge advantage here. It reduces the time needed for this critical, and it simultaneously reduces negative feelings toward the creation that this “maintenance developer” has toward the code base.

Students must experience both sides of this coin. On the producer side, they must develop code with partners. Partners must learn to critique each other and to learn from critique from the rest of the class, which represents their team. The partner and the class represent future developers and maintainers. On the consumer side, students must expect to switch partners and to take over someone else’s code base.

In short, changing students’ mindset requires hard work on managing continuous and intense feedback from each other. While programming must happen in pairs, code inspections must be public and must be solo-performances. To motivate the latter, a code inspection starts with “assume your partner has left the team.” Solo presentations check whether each partner completely understands the code base, so that if one of them leaves, the other one isn’t lost. Similarly, some of the students must play the role of colleagues who take over the code. These peers also represent the future, unmet developers and maintainers. It is therefor their task to ask penetrating and potentially unpleasant questions about every aspect of the design and the code. Without exception, such interactions can lead to unhappy conversations. Yet, they are for the benefit of the future developer and for the students’ way of thinking about their profession.

Being socially responsible even in just our profession is hard. Practice makes perfect—or at least good. It is the instructor’s job is to make sure that the practice is done right. This book is also a guide to this job.

image

Figure 1: A core programming curriculum

The Context, for the Instructor🔗

At my current institution, the course sits atop three programming courses. See figure 1 for a dependency diagram. The first course, Fundamentals I, introduces students to the idea that good programming calls for a systematic approach, starting with a careful analysis and description of the relevant sets of data all the way to the creation of a unit test suite. It does not use an existing, “industrial strength” programming language but several languages specifically designed for this audience of novices and an approach that insists on systematic programming. Even though the systematic design idea is about type-driven programming, these teaching languages lack a type system, because a large majority of students end up at co-op and internship positions where they use untyped languages. It is therefore imperative to expose students to the mental discipline of using types for program design even in the absence of a type checker.

Fundamentals II injects two ideas into the curriculum: type checking and object-oriented programming. The goal is to demonstrate that the principles of systematic program design from Fundamentals I apply in the context of a commercially successful language, Java. The programming assignment and the recurring programming project are still quite small.

Fundamentals III scales up the ideas to projects with graphical views, complex controls, and interesting models. The course begins to emphasize the proper design of interfaces and programming to interfaces—all in Java. The course also illustrates the role of logical assertions in interfaces and in code to supplement types, which almost never suffice to describe the true interface of a class. This step points back to the (optional) course on Logic, where students learn to formulate assertions about code as code. If the pace permits it, an instructor of Fundamentals III may also conduct private code inspections with students at the end of a project.

Socially Responsible Software Development, short: SRSD and also known as Fundamentals IV, is the source of the material in this book. It Choosing a Language is the last course where instructors and teaching assistants inspect students’ code in depth. Students get to pick their favorite language and IDE, partly so that they can focus on program design and partly so that they can assess how good they are in the language ecosystem of their choice.

Most importantly, the course is much more about the non-technical aspects of programming-as-thinking than the first three; it is about the social interactions that foster responsible thinking. While students program in pairs in the first three courses, they do so with some instruction but without much supervision. SRSD spends a large amount of time on the social aspect of programming-thinking. Students program in pairs, present their work to their peers on a regular basis, and critique each other extensively. To reduce the negativity, the instructor must teach that one doesn’t criticize the creator of code but only the code.

Practicing social software development in a classroom setting is challenging. I have spent over two decades teaching and refining these pedagogic ideas. Quite a few of them failed. This book collects the successful ones.

This Book and Its Parts🔗

The book consists of five chapters plus a postlude, following this prelude. The different lengths of these chapters do not indicate differences in importance.

Chapter I spells out the most basic truth about software projects: most of them die a rapid death. Yes, it is normal for projects to die. What matters are the survivors. When software survives, it survives for decades—growing, adapting, improving. It is this longevity of software that demands socially responsible behavior of developers to, and for, each other.

Chapter II describes the psychology and sociology of software development. Developers are creators and artisans. Like all other artsy creators, they tend to invest their ego into their creations, which is good because it means they strive for excellence. But, by identifying with their creations, they also tend to consider criticism of their creations as criticisms of their ego. Hence the goal is to develop a healthy balance—a compromise—between pride in one’s software and an understanding of criticism as an attempt to make this product even better. Techniques for learning to critique and to embrace critique are critical so that developers come to terms with this compromise. To this end, instructors must create and yet dampen tensions between developers who present their creation and peers who critique it. The tension is needed to train socially responsible developers who stand up for current and future colleagues, even if only because it could be them.

Chapter III explains how a software system comes about, how to build one, and how to think about their maintainers at this stage already. Unlike the programs students write in the first few courses, a software system consists of many components (packages, modules, frameworks). When a team follows a somewhat traditional development paths, it may create documents that describe the components, the dependencies among them, the construction plans, and the interfaces. Even if the team employs an “agile” or “extreme coding” approach, sooner or later the need for these documents arises. And these non-code pieces exist so that, in the future, developers can easily and quickly navigate the code base, distinguish task-relevant from irrelevant pieces, and properly use components via interfaces. The way to get this right is to have students try, have basics checked, fail, try again, and so on, every week of the course.

Chapter IV .. components .. interfaces ..

Chapter V is about the programming skills it takes to build and maintain a software system in a socially responsible manner. Conversely, ii is about the basics of what reviewers should look out for when they inspect code. While students at this stage are expected to have a basic grasp of programming, this book aims to make code development systematic even under pressure so that the resulting code expresses the reasoning behind itself clearly. Here “systematic” ranges from small things—naming—and small pieces of code (say, 10 lines) over modules and classes to full-sized semester projects (say, 10-20Kloc). The key is to maintain this thoughtful, systematic approach under time pressure, something that most developers suffer from. Without practicing this form of development extensively—in bootcamp fashion—it is all to easy to slip and write code so that “it works,” which we all know is the shortest lie in computing. It works neither in the sense of functioning properly nor as a well-formed message to the future.

The postlude draws a parallel between software development and life, and vice versa. Doing things with the future—short or long term—in mind isn’t just good for software development, it is good for many different aspects of life. Then again, thinking about the cycle of life during software development is a good idea, too.

Dear Instructor:🔗

Note QR symbols in the margins of the book point to supplementary notes for instructors. Check out the two above: one on what universities cannot teach and on why students should use their favorite language. These notes explain how to manage the course: from setting up the project and managing, to dealing with in-person code reviews.

Teaching is hard. Teaching this course is the hardest task you will ever tackle. It will also be the most rewarding one. Good luck!

Acknowledgments🔗