Saturday, January 28, 2006

Which language for teaching Computer Science?

I may be the last software geek on the planet to have read it, but Joel Spolsky's "The perils of Java in schools" resonated with me. Spolsky's premise is that Java isn't "hard" enough to weed out the competent from the incompetent software talent. For that, Spolsky claims, concepts like pointers and recursion are required. If a student can't digest and master those two facets of Computer Science, he or she shouldn't be a CS major. Spolsky notes:

...[the] real value [of these concepts] is that building big systems requires the kind of mental flexibility you get from learning about them, and the mental aptitude you need to avoid being weeded out of the courses in which they are taught. Pointers and recursion require a certain ability to reason, to think in abstractions, and, most importantly, to view a problem at several levels of abstraction simultaneously. And thus, the ability to understand pointers and recursion is directly correlated with the ability to be a great programmer.

Nothing about an all-Java CS degree really weeds out the students who lack the mental agility to deal with these concepts.

So why does it resonate with me? Is it because I was weaned on Intel 8080 assembler and then graduated to a high-level language: x86 assembler? That was a joke (believe me when I tell you that writing a "Space Invaders" game in x86 assembler for the Sanyo MBC550 -- which I did for fun in the eighties -- is no walk in the park).

Is it because I probably wrote somewhere around a half a million of lines of C code for FASTech and Alpha Software? Or hundreds of thousands of lines of C++ for extremely large organizations in my gigs as an IT consultant ("no JVMs need apply... we want performance, dammit! We need... ISAPI!")?

I'm not really sure. I love Java as an O-O teaching tool. There's no better set of tutorials on the planet for object-oriented programming than Sun's walk-throughs. But Java has always seemed like a toy to me. The layers of abstraction between the bare metal of the machine and me -- the developer -- seemed onerous and unncessary. And it didn't help that Java performance in the early days was, at best, weak.

The old JVMs were also problematic. Just when you least expect it, they'd decide it was time to garbage-collect. And then you'd watch the CPU spike. There was no predictability and no instrumentation on the JVM to help. Even today, if you need to escape to the bare metal, Java requires a strenuous escapement layer called JNI. 99% of the time, sure, you don't need to get to the bare metal. But for that 1% of the time when you need absolute performance or access to a low-level capability...

Bottom line is that Spolsky is right. Java is not challenging enough to teach both the low-level and the high-level concepts of software engineering. But there's also a problem with teaching C or C++: the really good developers aren't teachers... they're working in industry somewhere. I believe it's exceptionally hard to become really skilled at C/C++ unless you work with it for years. My guess is that mastering C requires at least a year of non-stop, real world development. C++ (with appropriate libraries such as STL, MFC, or equivalent) takes at least another year.

Suffice it to say that most teachers won't be able to reach this level of mastery of the language. So what's the answer? How about assembler? That gets you to the bare metal... teaches you CPU architecture... can be used to teach recursion. Plus: pointers come included... for free!

Email or call your Computer Science school today and demand that assembler be taught to all CS majors as the introductory class. Now that's a weed-out class!

Assembler, dammit, assembler! Young whipper-snappers... ***grumbling noises***

No comments: