What Should We Teach?
Scot Drysdale, Dartmouth College


The report Computing Curricula 1991 was an important undertaking that makes at least two things clear:

1) There is more to teach about Computer Science than can be reasonably covered in four undergraduate years. This is in spite of the fact that topics that are likely to be very important in the future - parallel and distributed computing and networks, to name a couple - do not get the attention in this report that their future importance is likely to demand. Other topics - e.g. the World Wide Web - have been developed since the report was written, so are not mentioned at all. We cannot keep adding topics to the curriculum without de-emphasizing or combining others.

2) The computer science community had no agreement on the best ways to teach this information or to package it into courses, either for our majors or for non-majors. In fact, we have had strong disagreements even about what the introductory courses should look like. When Curriculum 91 was being written there were a number of experiments with different approaches to the introductory courses (breadth-first, functional language first, object-oriented language first, closed labs, etc.). Can we now say which of these seem to be the most promising approaches? Can we find consensus on one or a few of them?


What Should We Teach and How Should We Organize It?

If we cannot fit everything we want to teach into the undergraduate major, what is essential? The committee that wrote Curriculum 91 struggled with this question, and broke the field into a set of knowledge units. It then tried to specify which of these units every computer science student should know. This was an important contribution, but it did not go far enough. Some valuable and cherished topics will fall out of this "central core" as time goes on, to be replaced by even more important ones. But it is more important to look at how we organize this material.

The report Computing as a Discipline by Denning et. al. pointed out that many of our courses are organized around artifacts rather than principles. The artifacts are very important - they provide concrete examples of the difficult problems that must be solved and prove the value of the theory devised to approach these questions. Historically the development of major segments of computer science theory and practice arose from the need to construct particular complex artifacts like compilers, operating systems, and data bases. But just because a topic arose in the context of a particular artifact does not mean that this is the best way to teach the topic today. For example, the question of dealing with concurrent access arises in courses dealing with operating systems, data bases, networks, distributed algorithms, parallel architectures, and programming languages.

A more sensible approach is to organize our courses around concepts, with applications brought in to motivate the need for the concepts and to show how the concepts are able to solve practical problems. The appropriate theory can be taught in this context. Many people have suggested that this is a good idea. The difficulty question is how to get to this point from where we are. A lot of things conspire to keep us in the status quo.

First, there are good textbooks and courses designed for the current curriculum. Artifacts provide motivation and a very useful organizational framework for courses devoted to them. Organizing around principles (using artifacts as examples and introducing theory as needed) seems much less concrete. Furthermore, such a change would require changing almost every course in the curriculum and writing an entirely new set of textbooks.

Because our discipline also tends to be organized around artifacts at the research level (look at the titles of CS conferences and journals!), it is not clear who will do such a reorganization, even if we agree that it is wise to do so. Instead of one expert designing a course and writing a text in his or her field of expertise, we need generalists cooperating with experts in several fields to bring everything together. A syllabus designed more or less on this approach has been attempted in The Carnegie-Mellon Curriculum for Undergraduate Computer Science published in 1985, but this book has not had much impact on undergraduate CS programs.

In spite of the difficulties, this approach seems worth pursuing. The recent efforts to create a multi-course breadth-first introductory sequence have given us some idea both the amount of effort that such an approach would require and some of the advantages and pitfalls of such an approach.

Instead of a breadth-first approach, I suggest that we should be considering a "breadth-middle" approach. The introductory sequence teaching programming, basic software engineering, and some basic ways of structuring data could be taught similarly to the way that it is now. Much of the material now somewhat artificially separated into architecture, operating systems, programming languages, compilers, data bases, networks, algorithms, and theory could be taught as a multi-course "core".

Such a project would be a large undertaking, requiring organization, funding, and a fairly large number of cooperating computer scientists with various areas of expertise. It would require a change in the way that most of us think about the field. But recent developments are blurring the traditional lines, anyway. Understanding the World Wide Web (particularly topics like Java applets running safely on host machines) requires understanding topics that currently are studied in networks, distributed computing, programming languages, graphics, and operating systems. It seems a good time to consider such a reorganization. If so, how do we proceed?


What is the Role of Programming?

Ralston and Shaw, in a CACM article entitled "Curriculum '78 - Is Computer Science Really That Unmathematical?", pointed out quite correctly that the equation "Computer Science = Programming" is incorrect and is "mistakenly believed by so many outside of the discipline." However, I fear that in some of our experiments in introducing computer science to majors and especially in service courses that we have gone too far in the other direction. We have tried to teach about computer science without teaching about programming. I think that such approaches are doomed to failure. Computing the Future quotes Donald Knuth as saying:

CS&E is a field that attracts a different type of thinker. I believe that one who is a natural computer scientist thinks algorithmically. Such people are especially good at dealing with situtations where different rules apply in different cases; they are individuals who can rapidly change levels of abstraction, simultaneously seeing things "in the large" and "in the small."

One of the major contributions of computer science to general education is to develop this ability to think algorithmically, which includes the ability to organize complex tasks into understandable pieces. The way that these skills are both developed and tested is in writing programs (or their equivalents). A student who has not grappled with a problem whose solution can be organized in several different ways, has chosen one of those organizations, and then has struggled with unexpected consequences of that decision, does not really understand an important part of what makes computer science challenging and interesting.

I certainly do not advocate spending a course teaching the syntax of a programming language. The questions of decomposition, organization, and "algorithmic thinking" are what are important, and object-oriented languages give us a good way to introduce these concepts and concerns in the first course. (I do not, however, enjoy using C++ for this purpose, and hope that Java or some other language will better serve this need in the near future.) Programs need not be written from scratch. Libraries and/or the use of higher-level languages can reduce the amount of overhead needed to create an interesting program, but getting students to design and write such programs should be a goal of any introductory computer science course.

This is true even of a non-major "service" course with the goal of giving an overview of computer science. In this case the programming language could be Hypercard or a scripting language or some other high-level language, but it is important that students deal with questions of how to structure and organize a fairly complex application.