Joel Spolsky recently argued against teaching comp-sci courses in Java, saying schools do a great disservice to students and future employers by not teaching C pointers, recursion, and functional programming. I agree on most points, but I must argue that the average school teaching C/C++ isn’t doing that great of job, either.

In my day, the Duke CS department taught C++. The data structures course covered what you’d expect, including pointers and recursion. Joel speaks of your program saying “segmentation fault” when you struggle with pointers, but here’s the rub: I’m pretty sure most students dink with their program until it stops segfaulting and produces the right output, but they still don’t understand pointers.

Pointers

Certainly I didn’t master pointers my first year in school. It was during my second year when a master programmer, Ryan Martell (co-author of Bungie’s Marathon games), gave me several hours of his time to explain how things really worked. He showed how various pieces of code compiled into assembly language, how the stack and heap work, and exactly how pointers and dereferencing work. It was a revelation–finally, everything made sense.

Since then I’ve helped younger friends struggling through comp-sci classes. They’d send me C code that was a mess of asterisks and ampersands, and when I asked them what they were doing, it was clear they simply didn’t know. They understood pointers as a concept on a whiteboard, but not how to use them in practice.

There’s a certain subset of pointer skills that students just need to know cold. Consider this code:

int* foo()
{
    int buf1[10];
    int *buf2 = new int[10];

    for (int i = 0; i < 10; i++)
    {
        buf1[i] = i;
        buf2[i] = i;
    }

    // ...
}

What’s the difference between these two buffers? Where is each allocated? Why could you safely return buf2 from a function but not buf1? Any CS student should be able to answer these offhand.

Recursion

When I learned recursion, it seemed that most of my peers “got” it, too. What they didn’t get were the gotchas. Question: why can’t you use recursion on a data set of arbitrarily large (or unknown) size? Students should know the answer offhand. [Update: see comments about tail call optimization below.]

Object-Oriented Programming

This is a tough one. I agree with Joel that perhaps OOP masters are born and not made. In industry I’ve seen junior programmers who take to OOP like a duck to water, and others with years of experience who still don’t get it.

But schools must attempt to teach OOP. We need to teach it, however, with the perspective that you don’t “know” or “don’t know” how to design object-oriented software. It’s a continual learning process, and doing it well takes both concentrated study and years of experience. Even those who understand basic concepts like is-a/has-a won’t necessarily get finer points like the costs/benefits of inheritance versus object composition. I’d argue that you can’t truly appreciate the finer points until you’ve worked on real projects for a while–years, not days or months–and seen how designs stand up (or fall apart) as a project evolves over many versions.

Debugging

It appears that many (most?) schools don’t teach students how to use a debugger. It seems so obvious as to be absurd: the debugger is an invaluable tool for figuring out why, where, and how your program isn’t behaving. I also consider it a valuable learning tool: you can use gdb as an interactive shell for exploring what’s in your buffers and what pointers are pointing to.

Style

This is perhaps a debatable point, but have you looked at the code written by most college students? It’s an awful, just truly awful mess. I cringe when I look back at mine, too. Universities need to grade code with the standards they grade English papers. It’s not enough that the compiler understands it–the code should also be readable and consistently formatted to an exacting style guide. Life in industry would be so much better if junior engineers (and senior ones, too) would just write clean code.

Revision Control

Revision control is a topic my CS teachers never touched, yet it’s absolutely essential to the day-to-day work of any competent software engineer. Please, please, will somebody start teaching students basic code management practices?

And So On…

Of course it’s impossible to teach a student everything–at some point they need to get into the real world and learn the rest as they go. But it does seem like the average comp-sci major (from a JavaSchool or C/C++ school) is left ill-equipped to work on projects of any consequence.

When it comes down to it, a well-versed engineer should be able to tackle anything thrown at them. If you don’t fully understand pointers, how could you ever write a device driver? If you can’t use a debugger, how much time do you need to waste before your employer starts to think you’re incompetent?

If you’re a student now, it’s your responsibility to master at least the things Joel mentioned and get exposure to the topics I’ve added here. I’m sure I’ve missed some critical points, too–please do us all a favor and add them to the comments below.