Wednesday, January 04, 2006

Java vs. C

Joel Spolsky, recently wrote an article talking about the dangers of letting CS courses in universities move to Java from C, Scheme or Lisp. I'm not sure I agree with that point of view entirely.

His basic claim is that "Java is not, generally, a hard enough programming language that it can be used to discriminate between great programmers and mediocre programmers." The reason? From his point of view, the Gods of programming are those who are familiar with two main things - pointers and recursion. Since Java doesn't have pointers and most Java courses or programs don't bother about recursion, he thinks dumb people can find it easy to write in Java. He believes C or scheme or lisp is needed to "weed out" the dumb programmers.

Here's my perspective - as a programmer, I am quite comfortable with pointers. I just rewrote (ported) a piece of MATLAB code to C, line by line, and since it was full of matrix operations, it was full of pointers. I have implemented pointer-based hashtables, written geometric collision-detection code using pointers and grids of pointers; and I was happy doing it. I've even done some assembly language programming on DSP chips. That was tough, no doubt about it, but given that I did it when I was basically a novice, its not all that bad. I've been programming on Java rather irregularly (I'd much rather code in C++ any day), but I've done complex projects like compiler design or AI implementations in Java. And I still find it hard to design and write a good program in Java.

Here's my take on pointers. They're boring. I use them all the time, and yes, your program will segfault and give you weird errors. Most people believe that debugging that requires some kind of great depth in understanding. It does not. All it requires is patience, attention to detail and caffeine. Its a process of following the thread of reference changes until you find the bug. You learn from your mistakes when your mistakes are in concepts or fundamentals. With pointers, mostly the mistake is you incremented the wrong value, or added something when you should have subtracted. Nothing very profound.

I must admit I missed Joel's point about recursion. Probably thats because I don't know Scheme or Lisp, which deal very specifically with recursive programs. I've implemented identical recursion routines in C and Java (depth-first search and dynamic programming problems come to mind) and the difficulty level has been exactly the same.

There is no doubt that using a lower-level language results in more frequent errors. But is a good programmer one who works on the most error prone language? Even an expert C programmer will screw up at times, and probably more than an expert Java programmer, because pointers are inherently error-prone. If all you want is for a programmer to be able to write difficult code, why C? Why not ask all the schools to train people with punch cards and machine language programming? Clearly we don't want to do that - we know we can eliminate a lot of errors by using higher level languages. And then people talk about knowing the basics. Sure, an implementing a linked list using pointers does illustrate the concept behind it. Any CS 101 course (including that in a Java School) will do the same, and the "bright" kid should not need to painfully work at pointers to understand what the relative merits are of various data structures. In my C class my professor reminded us, "You should all implement a pointer-based linked list. Exactly once in your life. After that, use the libraries."

Joel speaks of 6.001, an extremely tough course at MIT that bad programmers are very likely to drop out of. When I met CS undergrads during my stay in MIT recently, they spoke of 6.170 (which is taught in Java) being as tough as 6.001. While Java and C can be used for the same purposes the intent of each language is different. I think people who program in Java are much more proficient in thinking about high-level, large scale software design (enterprise databases for example) and C coders are much more comfortable with aspects of low-level programming (the Linux kernel). So if you want to judge how smart a Java programmer is, asking him about pointers and recursion is perhaps a bad idea; asking him about OO design and looking for the right answers will probably work better.

The bottom line is that training in Java and C gives you slightly different skill sets and I don't think its fair to say that Java is too dumb a language to judge a good programmer by.