Teaching is not easy. Especially when it is a subject like computer science. It’s very easy to get too theoretical and teach all the concepts, theories and techniques while not saying anything about how to apply all of that to writing practical working software. At the same time it is equally easy to teach only simple programming and in the process turn the theoretical aspects into drudgery which students only learn because it’s part of the degree requirement. Teaching computer science is all the more complicated because for all it’s innate fun and the enjoyment one can get from it, computer science is hard.
Joel Spolsky in one of his most famous blog posts blasted modern computer science curricula at almost all colleges for dumbing down computer science. In particular he criticizes the use of Java as a first programming language. Joel believes that computer science courses are no longer hard enough. in the old days (read 10-20 years ago), computer science were designed to be hard, the intro courses were designed to weed out the students who weren’t dedicated and smart enough. He claims that modern courses do not teach students the fundamentals of pointers and recursion and ill-equips them to work outside their comfort zone.
When I first read this post almost two years ago, I was…. enthralled. Here was someone actually saying that computer science should be made hard. It was probably the heretical nature of his article that enthralled me. I had been learning Java in school for almost a year and had developed a strong dislike for it. I should say at this point that my computer science course was not taught particularly well. My teacher had been doing C++ for years and it was obvious that he was not particularly comfortable with Java. Though the concept of object-oriented programming was introduced and we learned the advantages of it, I don’t think I really understood it. And I felt the whole business of writing classes with main methods and such for the simple programs that we were doing very tedious. I did well in that course but didn’t like it much. The dislike of Java stayed with me for quite a while, another reason I liked Spolsky’s article so much. A few months later as I read the first few pages of Structure and Implementation of Computer Programs, I understood why Spolsky spoke so highly of it and the course it was written for. By that point I had come to the realization that almost all intro computer science courses in the world were complete and utter rubbish with the exception of MIT’s 6.001.
But all that was more than a year. Since then I’ve gone through my first college CS course (though I skipped the intro course), I’ve programmed more in both Java and Scheme and other languages and I’ve read far and wide about computer science and programming. The result is that while I still argue with Spolsky in principle, I’ve come to realize that the issue is far more complicated. It’s certainly true that there is far, far more to computer science than programming. It’s not easy to realize that when you’re dealing with the complex framework and syntax that Java and most other languages give you and most intro computer science courses carefully hide away the powerful theoretical architecture that forms the foundations of computer science. Why? Because to gain the power offered by this theoretical architecture you have to pay the price of intense dedication to learning things that are far more unfamiliar (and hence perceived harder) than most other things that you are ever likely to learn.
Computer Science is hard and most people don’t like doing hard things. Making computer science easy helps to keep people in the department who would otherwise become Econ/history majors (yes I personally know more than a few people who have done so). And you need people in the department if you’re going to have a department. Of course, even if the intro courses are easy, the more advanced ones are not quite so. It would be really interesting to see how easy you could make operating systems or programming languages. If you want to take an operating systems course you’ll have to learn C or C++ and wrap your head around pointers. And no programming language course is complete without heavy recursion (BNF Grammars anyone?) and some amount of functional programming.
But coming back to CS 101, how do you make a course that is easy and interesting enough to make it attractive to freshmen while not giving them a false idea of the difficulty ahead? What tools do you use and how much theory do you teach? Any one of those questions would be hard to answer on it’s own without the added complication that in many places CS 101 is also required of engineering and math majors who aren’t going to take higher level computer science courses. I would personally like a hard intro courses that doesn’t mince words and gets straight to the point of how programming actually works. I think MITs 6.001 is a wonderful idea, which is why I’m teaching myself Scheme and reading through SICP. The things that I’ve learned there help even when I’m programming in Java and I’ve become a far better programmer for it. At the same time I realize that if my college taught a similar course as an intro, our department would only be left with about 5% of students (maybe less). My fellow students are lucky that our professors go out of their way to teach real-world problems and talk about things other than simple object-oriented programming.
One solution to the problem would be make a separate “programming” course for those who are not going to be computer science students. This would allow CS 101 to be a harder theory-heavy course aimed at people who are fairly certain that they want to study computer science and probably have some programming experience already. Students who are interested in computers but are not sure if they want to major in it could start with the programming course and then progress on to the harder course. My college is starting to go down this path with a new course called computational methods, though students from other science departments are still required to take the normal CS courses. I hope that this sort of a division soon becomes standard practice.
Leaving the technical to the sides for a moment, I believe that a good introductory course should also include some aspects of the history of computers as well as references to the outstanding problems in the field (and there are a lot of those to go around). It’s important for students to realize that computers weren’t always as strong and powerful as they are now and that there are still great challenges ahead. I’ll be out of college in three years (and looking to tackle some of those challenges) and so I don’t think I’ll benefit from a restructured curriculum. However, I’m still interested to see what directions education in our field takes.