The confluence of two events recently reminded me of an article I wrote back in 2003 about the role of mathematics courses in university computer science education. [Why universities require computer science students to take math, Communications of the Association for Computing Machinery, Vol 46, No 9, Sept 2003, pp.36-39.]
The first event was a request for me to be an advisor on a research project to develop K-12 computer science programs. The second was a forum discussion in my Mathematical Thinking MOOC, currently in the middle of its sixth session.
My MOOC attracts a lot of mid-career computer professionals, who bring a different perspective to some of the issues the course considers. The forum thread in question focused on what is meant by a statement of the form “Let x be such that P(x).“ In mathematics, use of this statement requires that there exists an object satisfying P. If the existence is not known, you should express the statement counterfactually, as “Let x be an object such that P(x), assuming such an object exists.”
Some of the computer scientists, however, instinctively interpreted the statement “Let x be such that P(x)” as a variable declaration. This led them to give an “incorrect” answer to a question that asked then to identify exactly where the logic of a particular mathematical argument broke down. The logic failed with the selection of an object x that was not known to exist. In contrast, those computer scientists felt that things went wrong when the argument subsequently tried to do something with that x. That, they observed in the discussion, was where the program would fail.
It was a good discussion, that highlighted the distinction between the currently accepted view of mathematics as primarily about properties and relations, and the pre-nineteenth century view that it was at heart procedural. As such, it served as a reminder of the value of mathematics courses in computer science education, and vice versa.
The remainder of this post is what I wrote in the CACM back in 2003 (very lightly edited). I still agree with what I wrote then. (That is by no means always the case when I look at things I wrote more than a decade earlier.) I suspect that now, as then, some will not agree with me. (I actually received some ferociously angry responses to my piece.) Here goes.
Some years ago, I gave a lecture to the Computer Science Department at the University of Leeds in England. Knowing my background in mathematics — in particular, mathematical logic — the audience expected that my talk would be fairly mathematical, and on that particular occasion they were right. As I glanced at the announcement of my talk posted outside the lecture room, I noticed that someone had added some rather telling graffiti. In front of the familiar header “Abstract” above the description of my talk, the individual had scrawled the word “Very”.
It was a cute addition. But it struck me then, and does still, many years later, that it spoke volumes about the way many CS students view the subject. To the graffiti writer, operating systems, computer programs, and databases were (I assumed) not abstract, they were real. Mathematical objects, in contrast, so the graffiti-writer likely believed — and I have talked to many students who feel this way — are truly abstract, and reasoning about them is an abstract mental pursuit. Which goes to show just how good we humans are (perhaps also how effective university professors are) at convincing ourselves (and our students) that certain abstractions are somehow real.
For the truth is, of course, that computer science is entirely about abstractions. The devices we call computers don’t, in of themselves, compute. As electrical devices, if they can be said to do anything, it’s physics. It is only by virtue of the way we design those electrical circuits that, when the current flows, obeying the laws of physics, we human observers can pretend that they are doing reasoning (following the laws of logic), performing a numerical calculation (following the laws of arithmetic), or searching for information. True, it’s a highly effective pretence. But just because it’s useful does not make it any less a pretence.
Once you realize that computing is all about constructing, manipulating, and reasoning about abstractions, it becomes clear that an important prerequisite for writing (good) computer programs is an ability to handle abstractions in a precise manner. Now that, as it happens, is something that we humans have been doing successfully for over three thousand years. We call it mathematics.
This suggests that learning and doing mathematics might play an important role in educating future computer professionals. But if so, then what mathematics? From an educational point of view, in order to develop the ability to reason about formal abstractions, it is largely irrelevant exactly what abstractions are used. Our minds, which evolved over tens of thousands of years to reason (largely imprecisely) about the physical world, and more recently the social world, find it extremely difficult accepting formal abstractions. But once we have learned how to reason precisely about one set of abstractions, it takes relatively little extra effort to reason about any other.
But surely, you might say, even if I’m right, when it comes to training computer scientists, it makes sense to design educational courses around the abstractions the computer scientists will actually use when they graduate and go out to work in the technology field. Maybe so (in fact no, but I’ll leave that argument to another time), but who can say what the dominant programming paradigms and languages will be four years into the future? Computing is a rapidly shifting sand. Mathematics, in contrast, has a long history. It is stable and well tested.
Sure, there is a good argument to be made for computer science students to study discrete mathematics rather than calculus. But, while agreeing with that viewpoint, I believe it is often overplayed. Here’s why I think this.
A common view of education is that it is about acquiring knowledge — learning facts. After all, for the most part that is how we measure the effectiveness of education: by testing the students’ knowledge. But that’s simply not right. It might be the aim of certain courses, but it’s definitely not the purpose of education. The real goal of education is to improve minds — to enable them to acquire abilities and skills to do things they could not do previously. As William Butler Yeats put it, “Education is not about filling a bucket; it’s lighting a fire.” Books and USB memory sticks store many more facts than people do — they are excellent buckets — but that doesn’t make them smart. Being smart is about doing, not knowing.
Numerous studies have shown that if you test university students just a few months after they have completed a course, they will have forgotten most of the facts they had learned, even if they passed the final exam with flying colors. But that doesn’t mean the course wasn’t a success. The human brain adapts to intellectual challenges by forging and strengthening new neural pathways, and those new pathways remain long after the “facts” used to develop them have faded away. The facts fade, but the abilities remain.
If you want to prepare people to design, build, and reason about formal abstractions, including computer software, the best approach surely is to look for the most challenging mental exercises that force the brain to master abstract entities — entities that are purely abstract, and which cause the brain the maximum difficulty to handle. And where do you find this excellent mental training ground? In mathematics.
Software engineers may well never apply any of the specific theorems or techniques they were forced to learn as students (though some surely will, given the way mathematics connects into most walks of life in one way or another). But that doesn’t mean that those math courses were not important. On the contrary. The main benefit of learning and doing mathematics, I would argue, is not the specific content; rather it’s the fact that it develops the ability to reason precisely and analytically about formally defined abstract structures.