For as long as I've been paying attention to computer science as an academic field, people have been arguing about how to design an undergraduate curriculum. To what extent is CS a branch of math, or of electrical engineering? How should academic CS be tied to industry? To what extent do we teach good-programming skills like modular design or "design patterns" or abstraction (which has apparently been discovered yet again and dubbed
the "Don't Repeat Yourself" principle by the Ruby people), and to what extent do we teach more academic subjects like computability, rigorous asymptotic analysis and the like?
I found today that O'Reilly's OnLamp website recently ran
an opinion piece on the subject. If you take even a glance at it you'll see that the author is very much an industry-only guy and it's tempting to just say that if he thinks diplomas from DeVry are more useful than ones from MIT then it's just his loss. But though I think this article betrays its author's fundamental misunderstanding of what a computer science education is all about, and as much as I think some of the `academic' skills he denigrates are actually quite a bit more useful than the `practical' skills he praises (hey, I'm a PL person, I think
every problem is a compiler problem!), I'm going to go out on a limb and say he's got a good point. More specifically, I think his list of things that CS departments ought to be teaching probably contains more good ideas than bad ones.
The way I read it, his list breaks down into two major categories and a little miscellany. The first major category is what I'd call programming competence, which he addresses with the items:
- The basics of Programming
- Problem analysis
- Basics of good code architecture: Loose Coupling, etc.
- Testing, Debugging, Performance, Re-factoring
- Code Reading
- The importance and tools of Planning
- Patterns and Anti-Patterns
- OO Design, Interfaces
- Architectures: client/server, SOA, P2P, etc.
What these things have in common is they're all skills that have nothing to do with particular problems but only with managing the general difficulty of writing a program, particularly a big program that needs to exist for a long time. That isn't usually thought of as a core CS topic, but it should be: computer science is fundamentally the study of how to best systematically solve problems. The academics have traditionally decided that 'best' means 'using the smallest set of resources possible,' but in situations where resources are relatively abundant and programs live a long time I think it makes more sense to define 'best' as 'most maintainably'. Therefore I see no reason why topics like abstraction shouldn't be considered as fundamental to computer science education as efficiency is.
The second major category is what I'd call modern programming cultural awareness. I'd include these items:
- Real world Databases
- A 'Big' language or two (Java, C#, C/C++)
- A scripting/'agile' language or two (PHP, Perl, Python, Ruby)
- XML (DOM/SAX, XSLT/XPath, etc.)
- Internationalisation, Localisation, Encoding, Unicode
- Interface Design, Usability, Accessibility, HCI
- Security
- Common Protocols (TCP/IP, HTTP, SMTP, FTP)
- Source control, change management
- The typical Software lifecycle
- Metadata, Information Architecture, etc.
These are all about learning the state of the art in industry for solving various problems. I certainly don't think a CS undergrad should focus on this — that's what industry is about, after all — but I can't say I'd be that happy graduating a CS undergrad who didn't know anything about any of them. To the extent that computer science is an engineering discipline, its practitioners ought to have a working knowledge of the great feats of engineering that have already been done, and ought to be conversant in the language the engineers use. As a programming languages researcher, I'm not a big fan of C++, say, but it's so much a part of the culture that it was absolutely useful for me to have learned it.
And then there are some miscellaneous items. I certainly agree that anyone with a bachelor's degree ought to learn about
Grammar, punctuation, concise and clear writing but in general these points are kinda silly. And of course this list leaves off practically the entirety of what computer science is traditionally about, and I don't want to give anyone the impression that I think we ought to replace all our algorithms and computability classes with lectures about design patterns and Unicode or that SAX vs DOM ought to replaces P vs NP. And please don't take me to mean that I basically endorse this guy's view of how CS departments ought to be. But I do think that academic CS and the programming industry benefit very little from each other's existence, and that's a shame. Physics, biology, and even psychology enjoy a fruitful exchange of ideas between their industrial and academic branches — computer science should too, and I think those of us in academia can do our part by trying to understand the industry programmers even when they don't seem to understand us.