Wednesday, July 30, 2008

Perils of Thinking Java is to Blame

In 2005 Joel Spolsky wrote an article The Perils of Java Schools. The main point of the piece "is that Java is not, generally, a hard enough programming language that it can be used to discriminate between great programmers and mediocre programmers. " He goes on to list two of the characteristics of C that make it a good touchstone for a programmer's skill: pointers and recursion.

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.

I'm not quite sure why he picked recursion, since the "recursive powers" of Java and C are pretty much identical--neither supporting tail recursion--so that leaves pointers.

My first minor disagreement with Joel's thesis is in that he feels pointers are a difficult enough topic to identify great programmers. Here is a great 5-page paper written by John Tsiombikas that clearly presents pretty much everything you need to know about C pointers. Basically, compared with pretty much any of the other topics in a rigorous undergraduate engineering education--differential equations, linear algebra, Fourier transforms, discrete mathematics, orders of growth, etc.--pointers are downright cake. It's not that they're trivial, but next to the hard stuff they're pretty simple.

That leads me to the biggest issue I have with the whole anti-Java movement: blaming the language for a perceived decline in the quality of CS graduates, and for an inability to distinguish good and bad programmers who program in Java.

I used to be able to tell the smart kids because they could rip through a recursive algorithm in seconds, or implement linked-list manipulation functions using pointers as fast as they could write on the whiteboard. But with a JavaSchool Grad, I can't tell if they're struggling with these problems because they are undereducated or if they're struggling with these problems because they don't actually have that special part of the brain that they're going to need to do great programming work.

Does that mean in the old days if a candidate knew C pointers he got hired without further ado? Hmm. How about asking the JavaSchool grad a question that tests his intelligence and programming acumen without being tied to an implementation language? Ask him to write some code in whatever language for an insertion on a red-black tree. I'd pit my army of "red-black hires" against the army of "C pointer hires" any day. And if red-black trees are too snooty (which they probably are) then heapsort or mergesort will probably do; and if mergesort is too snooty, then you should stop complaining about JavaSchools altogther.

It seems that people are blaming the quality of students on the language in which they are taught rather than the declining standards of computer science knowledge to which they're held. And students also are coming to view Java as the source of feelings of dissatisfaction with their education, for instance here.

Java does not need to hold back a programmer in the least!

Want to see some hardcore, low-level programming, like implementing an optimizing, JIT-compiling virtual machine? How about implementing one in Java? Yes, the Jikes RVM does just that, producing a self-hosting competitive performance JVM with pretty much everything, even GC, implemented in Java. Once you write a native-code compiler, whatever its implementation language, the whole world of systems programming is at your reach.

MIT's undergrad compiler class is taught in Java. The lecturer, Saman Amarasinghe, whose research specialties include compiler optimizations, computer architectures, and parallel computing, is certainly no n00b who chose Java because he didn't think his students could handle pointers or because he didn't know better. In my earlier days, when I was a C zealot, I asked him why he chose Java and he said it was because dealing with memory ownership (that is, which subsystem "owns" and thus has to free memory allocated on the heap) in a compiler was such a hassle that using Java let the students implement better compilers in the time allotted to them. Not a language bigot.

Even operating systems: take a look at JNode.

How about Donald Knuth's take on languages? (This interview is found here.)

Knuth: All through my life, I've always used the programming language that blended best with the debugging system and operating system that I'm using. If I had a better debugger for language X, and if X went well with the operating system, I would be using that.

[... Goes on to describe the horrors of the IMP language at Cray...]

It was not a great language or compiler.

However... it was still my language of choice, because it fit that operating system perfectly. The arrays would be named in a way that you could easily see in the debugger, and you could know where the storage was being allocated, you knew what was going on, and you could actually get your program running reliably, because IMP blended with the operating system. You couldn't do that with any of the other languages. You might be writing with a better language, but you would get your work done a couple of weeks later, instead of getting answers. I used IMP.

His superlative knowledge of data structures and algorithms and mathematics makes implementation language a less important aspect of his work. He'd have no qualms about using Java if its tool support were the best--and often it is. (Though admittedly he'd use a WEB compiler for Java so he could continue his practice of Literate Programming). Remember that he chose Pascal to write TeX and Metafont--and he said that he avoided the use of pointers because they weren't as portable as the other parts of Pascal (see section 3 of TeX: The Program).

In the end, what matters about a program is what it does, and how quickly and correctly, not in what language it was written.

So basically, don't blame students' degrading quality on Java - if you feel like blaming, maybe blame colleges for not being more demanding in their coursework. And if you're an employer, just put a little more effort into designing a better technical screening process. But are JavaSchools even in their unflattering sense a bad thing? Do we have fewer brilliant programmers now than we did a decade ago? Or just more mediocre ones? Would the brilliant programmers take the somewhat tedious CRUD webapp jobs that our Internet age has created a demand for?

Addendum:

From the discussion on Reddit, I learned of a cool book, "Elements of Computing Systems: Building a Modern Computer from First Principles", which teaches you the levels of abstraction from "NAND gates to Tetris". Knowing all of that will certainly give any programmer low-level perspective, and anyone who finishes it will have about zero trouble understanding pointers, I am sure. Incidentally, the book's accompanying software is in Java...

Wednesday, May 28, 2008

From Marcus Aurelius's Meditations

As he took examples of the good in life from others, so may I take them too:

Decency and a mild temper.

Integrity and manliness.

Generosity, simplicity of living, avoidance of the habits of the pampered.

To learn from good teachers, and to hold this at high value.

To tolerate pain and feel few needs; to work with my own hands and mind my own business; to be deaf to malicious gossip.

To avoid empty enthusiasms; to tolerate plain speaking and have an affinity for philosophy.

To want betterment of my character, not to be seduced by the music of rhetoric, and to want the same. To not deliver my own moral sermons or to paint a glorified picture of the ascetic; to avoid pretentious language, and to write and speak in an unaffected style. To offer ready conciliation with those who have taken or given offence, as soon as they are willing to join me. To read carefully, and not take comfort in my own superficial thoughts or those of others.

Moral freedom, and to be guided by reason. To stay steady, not having my character be molded by the facile hands of circumstance. To be patient in explanation and in listening to the explanation of others.

A kindly disposition and an intuitive concern for my friends. Tolerance of both ordinary people and the extremely opinionated.

Not to leap on mistakes or to pedantically correct those who make inconsequential errors.

To see and understand the effect of suspicion, caprice, and hypocrisy in managing others.

Love of family, truth, and justice. To value freedom and equality, philosophy, beneficence, optimism, confidence, and frankness.

Self-mastery and a constancy to not be unduly affect by passing whims; good cheer in myriad circumstances; a balance of character, gentle and dignified; an uncomplaining energy for what needs to be done. Being well-intentioned in all I do. Never to be downcast or cringing, or brooding upon anger or suspicion. To be forgiving and truthful, and to choose rectitude. To never be belittled and to not consider myself superior to others.

Gentleness, and a firm adherence to decisions made after full consideration. No vain taste for so-called honor; stamina and perseverance; a ready willingness to listen to anyone with a proposal for the common good. To give common courtesy, to be focused and persistent in deliberation when such must be, to never be satisfied with first impressions or leaving a question prematurely. Foresight in long-term issues and unfussy control of details. To put little worth in acclamation or flattery, to be tolerant of criticism; to avoid superstitious fear and obsequious courting of the public opinion. To have a sober steadfastness, and no obsession with vulgar or newfangled tastes.
      To enjoy the comforts of life without pride nor apology, to not take them for granted nor regret their absence. Not to be a fraud, impostor, or pedant, but rather to strive for a mellow wisdom and mature experience, able to take charge of my own affairs.
      To have a high regard for genuine philosophers, yet to have no hard words for others. To be sociable and have a sense of humor, though not taken to excess; sensible care of my body, neither vain nor valetudinarian, but neither neglectful, so that a healthy constitution leaves little need for doctors or medicines.
      To have a ready, ungrudging deference to those with some special ability, and to support those with a talent in a field. To resume life and work quickly, vigorously after any illness or pain. To not live an unduly secretive life.
      To not be consumed by care of comforts or building houses or acquiring possessions; to not be particular about food or clothing, or youthful beauty.
      To not be harsh, relentless, or impetuous; to not panic but rather treat everything with its own allotted time and thought, unhurried, organized, vigorous, and consistent in all. To regulate abstinences and enjoyments where some may not have the discipline to abstain nor the happiness to enjoy.
      Strength of character--endurance or sobriety as the case may be--and a full and indomitable spirit, in health and illness.

Good grandparents, good parents, good siblings, cousins, and fellows, good teachers, good family, relatives, and friends - to maintain peace with them all. To not be corrupted, nor feel the need to fancy outfits, jewelry, decorations, and the other trappings of pomp, but to maintain the highest dignity in whatsoever station may fall to me.
      To live life in accordance with nature and the common good.
      To give thanks for health, mind, those who love me, my fellows, and fortune's favor.