Joel Spolsky is a crotchety old man

Sunday 1 January 2006This is close to 18 years old. Be careful.

Joel Spolsky’s latest essay is The Perils of Java Schools. He explains in detail why he thinks teaching computer science with Java is a bad thing. It basically comes down to not learning about pointers or recursion. He laments the state of computer science education, and fears for the entire industry as a result.

At least Joel has the good sense to start the piece by making fun of himself for griping about “kids these days”. He has his knickers in a twist for no good reason.

One of the things that caught my eye about the piece was that Joel attended Penn, and discusses a course there called CSE 121. As it happens, I also went to Penn. I suspect it was a couple of years earlier than Joel, but not many. I didn’t take CSE 121. I wonder if it was offered, because it doesn’t sound familiar, but looks like an interesting course.

So I never had the legendary Intro To The Theory Of Programming Languages Using Lisp course that so many people find so fascinating. But I took another course that is germane to the discussion, Intro To Assembly Language.

I don’t think CS students today are being taught assembly language. Should they be? I don’t know. Is it useful? Yes, at the very least for debugging. Working in C++, there have been many times when dropping into disassembly in the debugger was the only way to see what was really going on. I’ve had debugging sessions with engineers with recent Master’s degrees from MIT where I started poking around in disassembly and registers, and as far as they were concerned, I might as well have been speaking in tongues.

(Side note about the Assembly Language course at Penn: we were taught PDP-11 assembly language, and did all our work in it. The final project was to write a 6502 emulator for the PDP-11. But Penn didn’t have a PDP-11; all the projects were run on a PDP-11 emulator on a Univac mainframe! Needless to say, the 6502 programs we tested our emulators with ran very slowly!)

Assembly language can be very helpful, but if you’re working in Java (or Python or Ruby or PHP or Perl), there isn’t much call for it. So should it be taught? Hard to say. Understanding it will definitely give you a deeper understanding of what’s really going on, and many areas of software engineering still require its use. But if students don’t take a semester of assembly language, they can take a semester of something else instead, something that may be more helpful in the long run. UI design? Finance? There are lots of things I never learned in college that would be handy now.

Why does Joel pick out pointers and recursion as the two gatekeeper concepts? Because he found them difficult? As Tim Bray points out, Java is perfectly adept at recursion, and concurrency may be a more important and difficult concept to master in any case. The emphasis on recursion in Lisp languages is a bit over the top, and doesn’t carry into other programming cultures. Why do people think it’s so important for software engineering? Don’t get me wrong: I love recursion when it’s the right tool for the job, but that is just not that often to warrant Joel’s focus on it as a fundamental concept.

While we’re hunting around for tough concepts that separate the men from the boys, what about the one that got Joel and I into a tussle two years ago: Exceptions. He doesn’t like them, basically, because they confuse him. Is this any different than a Java guy not liking pointers? Yes, you can avoid exceptions and use status returns, but you can also try really hard to avoid pointers. Does that mean you should? So Joel’s got the concepts he likes (pointers and recursion), and laments their decline, but doesn’t seem to notice that there are newer concepts that he’s never caught on to, which the Java kiddies feel at home with.

Joel draws an analogy to Latin and Greek being required by universities in 1900. Good point. This is where the “kids these days” arguments always fall apart. By digging back even further into the past for helpful analogies, the old timers don’t even realize the trap they are falling into. Joel didn’t learn Latin or Greek at Penn, and neither did I. Neither did 99.99% of the software engineers working today. Which means Mr. 1900 would look at every single one of us and consider us unfit for professional work. But we are not. We are fit for the world we find ourselves in.

Education changes, and the world changes. Which is the cause and which the effect? Perhaps it’s a bit of both. In any case, the colleges produce graduates, who go into industry, and produce software. Some will be good at it, some will not. This is how it has always been. In my experience, most of what is truly helpful in writing software didn’t come out of a text book or off of a blackboard. So much of the day-to-day work of writing software is completely missing from curricula anyway, why worry about it? You want a good software engineering education? The final project should be to take some other kids’ project from last year and adapt it to do something he didn’t even consider. Then the result gets passed on to another kid next year. That would be an education!

The Java kiddies will learn to write software. Some of that learning will happen in college, some will happen on the job. Joel learned on Pascal, a language specifically simplified for teaching. When I started at Penn in 1980, the first course in the computer science curriculum was Introduction to Programming in, you guessed it, Pascal, because Pascal was trendy for teaching in 1980. Java is trendy now. The industry survived Pascal and its students, and it will survive Java.

And you know what? Twenty years from now, the Java kiddies will be the old timers, and they’ll probably be lamenting how computer science is being taught in 2026. So it has always been, and so it will always be. Geez, old-timers these days!


I was wailing on Joel over at Scoble's blog. What a dick that guy is.
Good points. Joel has always elited himself using features from C--it seems like he's been reading some Scheme books lately, and since several of them go overboard with recursion, he can add recursion to his litmus test.

Honestly, I don't think academically that pointers are that hard--it's when you get a bunch of different people working on a big system together that use them where it gets to be serious. His tests don't account for that. They become more like Jeopardy questions testing exposure and recall.

As for the recursion stuff, does anyone find that hard? Closures, continuations, concurrency, memoization and solid design are WAY harder than pointers/recursion, and probably better separate the men from the boys.
That Joel doesn't pick very good examples doesn't invalidate his point. It is important that CS students learn many different abstractions and concepts so that they can think effectively about real-world problems.
Well said. I totally agree with you.
Doesn't it seem significant to you that pointers are a very important part of how modern computers work, and that by not learning them modern students essentially only know how to work in software sandboxes that they are given rather than being able to work with arbitrary hardware sandboxes?
Your point, times change, education changes, doesn't hold water with me. Where I work, we're interviewing woefully underqualified college graduates these days.

We end up hiring the best of them, and my full-time job is basically teaching now.

For the record, we do program video games, which involves quite a bit of to-the-metal. But it's not much different from any other embedded system programming job.

As David said, unfortunately, Joel picked some poor examples. And, I'm not a huge Joel fan, I think he's generally overrated; but, in this case, his point remains strong.
"Java is perfectly adept at recursion"

By which you / tim bray mean that java requires tail call optimization? Didn't think so . . .
I'm seeing similar reactions from a lot of "old timers". Apparently Joel's love affair with pointers and Scheme (Scheme?!) as a way to separate the 'true' developers from the 'X For Dummies' posers isn't universally shared.
I think what the real point of his essay was how difficult it is to interview someone on Java.Students never learn things like
strcpy ,strncpy or doing some string operations. While Java may provide handy APIs for these I would really like to test someone on these aspects (which are related to pointers btw) and its not possible with Java.
Java is the way of the future. Kids should not be taught pointers and recursion, they should be taught how to construct if statements and how not to fail CS courses.
I would suggest that if you had spent more time reading the essay you're trashing than constructing an essay of your own with which to trash it, you would have noticed that Spolsky endorses things like the teaching of pointers and recursion in Scheme in a course like A&S's Structure and Interpretaiton of Computer Programs because they make for better programmers, both by weeding out the losers and pushing the students who remain. He never once in the essay argues that pointers and recursion should be taught because they are so incredibly useful (although he does mention that without the understanding of those two concepts, you will be unable to work on some of the most interesting things in your field). In fact, this fundamental assumption upon which you base your entire essay is explicitly contradicted halfway into Spolsky's article.

On a related point, you also missed the intention of the "Every educated person knows Latin should be a requirement" example, again assuming the direct opposite of what was said. He wrote "Are pointers and recursion the Latin and Greek of Computer Science?". And then, if one dares to read further, you realize he answers this very question: no.

Joel's essay to which you link contains an argument that is lucid, well-thought-out, and rational. The argument in your essay can be completely demolished by reading one paragraph of the essay that you decry. In light of this, and the fact that Spolsky is speaking from the experience he's had of having to staff a company from the pool of available programmers, whereas you are arguing from a much more theoretical standpoint, I think it's much less likely that Joel Spolsky is a crotchety old man then that you, on this matter at least, are simply a crochety young one.
This really feels like an essay about a point that's been missed. Joel said: "Java is not, generally, a hard enough programming language that it can be used to discriminate between great programmers and mediocre programmers."

He's not the only one who misses "the good old days", but that's not the point, and his problem is an entirely current one. You seem to have missed that, instead focusing on the literary device he used to point it out: he needs a practical means of quickly ascertaining the capacity for "systems thinking" in a candidate; a way to separate the guy who can crank out code from the guy who can think about code.

It's not about language advocacy, or whether recursion is a tougher concept to wrap your head around than list comprehensions, or whether Java is better than Ada. It's a shame you didn't pick up on that.
Joel's point is that there are things you have to know and be able to understand in order to realistically be a good programmer. You don't need all that information much these days but if you don't know it, it's like driving blindfolded. It's the leaky abstractions thing (google for it!): in order to truly understand what you're doing, even when programming in Python or Java, you have to know what's happening underneath because you're going to (indirectly) bump into it sooner or later. Assembly language experience hasn't been a requirement for general programming in the last 10-15 years but computing still all boils down to that. (And logic gates and transistors!) So much for living in a JVM ether!

Compare it to a general medical doctor: it may seem that what they do most of the time is using a stetoscope and a couple of other instruments, looking up drug names in their medicine bibles and writing prescriptions. So why not teach medical students just that and leave all the difficult stuff to the others, like older doctors who already know more? Or, as an airliner pilot: theoretically, (almost) all you need to do these days is crank up the thrust, pull the stick and click the autopilot on. If that doesn't sound trustworthy, why would you trust a programmer whose perception of reality is a virtual machine?

I'm not sure how much culminates on pointers and recursion but every good programmer I've known hasn't had a problem with them. They're not that difficult even if you don't use them daily. The difficult stuff comes later, and if you claim you know that you sure as hell shouldn't have a problem with pointers and recursion.

As a professional system designer with 15 years of experience, I'd certainly hear my warning bells ringing if someone would apply for a job and didn't know pointers and recursion. How would I know if he knows the difference between the stack and the heap? What if he ends up using polynomial time algorithms where any other sane developer would find (or just "know of") linear or constant time solutions? Or if he has no idea of memory management, as he has been garbage collected all his life? Joel is at least partially on right tracks that if your candidate proovedly knows recursion and pointers, he's got at least one foot safely on the ground.
vivek said: Students never learn things like
strcpy ,strncpy or doing some string operations. While Java may provide handy APIs for these I would really like to test someone on these aspects (which are related to pointers btw) and its not possible with Java.

Two things:
1) This is 2006. Nobody should be spending any time futzing around with string manipulation as there are plenty of string manipulation facilities either builtin to the languages that are used now or they are readily available in libraries. Think of something else to ask your interiewees. String manipulation questions are so '90s (no, '80s); they only serve to give the interviewee the impression that programmers at your company have to waste a lot of time reinventing the wheel.
2) If you really insist on asking such questions, there really is no reason why you can't ask someone to write something like strcpy in Java (you just need to preface the question with something like: "pretend that civilization has been mostly destroyed and you have a computer with a Java VM, a java compiler, but no string libraries...".
The reason people use Java and not C is that Java makes them more productive, same with VB etc. non-elite programming languages. The above poster is obviously agreeing with this.

That's why they are not as good for making the distinction between a really smart person and a not-so-smart person as pointers are. Actually, because they are not, they are used everywhere.

All of Joel's points remain valid in my eyes. You just created new arguements out of his, and discussed them.

Thanks for writing anyway.
...because elite schools think that teaching practical skills is better left to the technical-vocational institutes and the prison rehabilitation programs. You can learn mere programming anywhere. We are Yale University, and we Mold Future World Leaders. You think your $160,000 tuition entititles you to learn about while loops? Source

Isn't a lot of software development happening in Java?

If so, replace the expression "practical skills" with "Java" in the aforementioned sarcastic extract from another Joel's essay.
"concurrency may be a more important and difficult concept to master in any case."

Concurrency is difficult to get right in Java. Most Java developers are taught to encapsulate state in objects, but not to encapsulate state to threads. The typical Java developer writes concurrent code using way too much shared state, which is very difficult to comprehend.

Shared state isn't so much a problem in different languages, such as Sheme, where state is thought of differently. Concurrency isn't considered an exceptionally difficult problem in these languages.

Knowing alternative high-level programming languages is important for selecting the right tool for the job. Really innovative developers know how to play the strengths and weaknesses of the language and import concepts from one language to another when it makes the solution simpler.
Java in theory is more productive than C++. Web development in theory is more productive than desktop applications.

However, I did the same application in both three. C++ with wxWidgets won hands down.

The reasons? Java has at least three string classes. wxString is a single class easy to use and presumably faster too.
Gui stuff is easy with wx C++. Network is as easy as with java. The date/time picker is a joy to use in wxW. Java GUI requires inner classes and a lot of framework code that doesn't really translate in functionality, but is there just to fight against the language limitations (everything must be a class).

And in the web application, I had to use a lot of source files, that essentially are all the same (missing lisp macros there). And I had to debug the date/time picker because JavaScript is different in every browser and sometimes just doesn't work. That was the most time consuming part of all the coding. JavaScript debugging.

No, I didn't had to use pointers all the time, objects in the stack are easier. No templates either. C++ templates are uglier than anything bad that Java has.

In fact you're more efficient with a subset of C++ and the right library than with full C++, Java, or plain php. And the end result is far easier to use and more aesthetic.

But as always, managers won't listen.
I think one of the points that gets so lost on students these days (and what I thought Joel understood) is, it's not the programming language of choice that's important; rather, it's the set of concepts that a given language stresses. Java is incredibly practical, in part because of its abstraction, and also in part due to the incredible number of libraries. it's important, however, for students to understand what's going on under the hood, and java is not the language that best demonstrates that.

It's also, however, the way that Java is taught. Pointers do exist of course in Java, they're just managed. But there are times when you have some control over them- say for example, using a WeakHashMap instead of a HashMap will release objects in a hash when they aren't referenced elsewhere. A student not familiar with pointers wouldn't understand this. It's impossible for a class in C++ to get away from this, but professors who use Java rarely spend much time worrying about something like this.

I agree with you to a point as far as Exceptions go, in so much as I disagree with Joel that OOP is all about memorization. Polymorphism isn't just a something found in an OOP programmer's glossary. However, I think OOP concepts are pretty abstract, not nearly as concrete and low-level as pointers. And I will agree with Joel that problems in OO design don't result in broken code, whereas problems with pointers are much more apparent. So if you have to cut your teeth on one language or another, it should be one that doesn't let you get away with mistakes.
Maybe another metaphor similar to Latin would be long division. Kids aren't learning long division anymore. I think that's fine. It's an interesting and sometimes useful algorithm to learn, and it teaches you something about division. But it's less and less useful, and there's other more useful algorithms to learn, and other ways to understand what division really means. I think pointers are similar; their usefulness is diminishing, and there's better ways to learn about references and indirection than C-style pointers. It's not like the idea of an indirect reference has disappeared.

*If* the schools aren't replacing pointers with other useful concepts, then that is bad. But I don't think that's the case.

That said, recursion is actually a much more fundamental concept, and it would be most disappointing if students graduated without understanding it well. They might stop teaching long division, but it's no good if they stop teaching division itself.
I agree with Joel's main point -- that school's are dumbing down the curriculum -- but it is superficial to suggest an understanding of "pointers and recursion is directly correlated with the ability to be a great programmer" (Joel's quote). I'll go a step further. I don't think it is even possible for undergraduate CS departments to separate the potentially great programmers from the mediocre ones. That's not really their job.

One reason is that some of the best future developers aren't even in the CS program. One of the best developer's I've worked with got a degree in Mechanical Engineering. Another got a degree in Biology. Personally, I got a degree in Civil Engineering. I learned pointers and recursion on the job. As I remember learning those concepts wasn't nearly as hard as studying Fluid Dynamics, understanding phase diagrams in Geochemistry, or reading Gravity's Rainbow.

Joel said, "You need training to think of things at multiple levels of abstraction simultaneously, and that kind of thinking is exactly what you need to design great software architecture." I don't think it is a matter of training. The ability to think architecturally is more of an innate ability. A CS program can only begin to manifest this ability in it's students. To really separate the kids from the adults, you need to wait three to five years after undergraduate school.
Abstraction pooh pooh. Abstractions are useless in vacuum. You don't teach kids the abstract concept of what a fruit is. You start with something concrete, like an apricot. Then, a few other kinds of fruit, and eventually, the abstract concept of fruit comes into being. This is precisely why CS juniors find learning higher order abstractions first so difficult.
The essential issue that Joel raises is what is the nature of Computer Science and what is the core knowledge that someone trained in this field (i.e. issued a Degree) is expected to know. Computer Science isn't about learning computer languages or even about computers (the tools used in this business) - rather it might better be considered an abstract form of engineering since it deals with ("black-box") abstractions - in effects expressing algorithms ("how to" methods). In addition it is very much about understanding how to deal with all of the complexity associated with such abstractions. Understanding pointers, interation, recursion, data structures, procedures, etc. are all part of the general knowledge needed for Computer Science. Concrete implementations of these abstactions is also a part of this knowledge expected to be understood by someone with a Computer Science degree. No single computer language, because of its own specific programming idioms, is going to be able to express all of these concepts well - certainly not Java. That is why learning multiple computer languages, C/C++, Lisp/Scheme, Assembler/MIX, etc. is absolutely essential to a good education in Computer Science.
The other issue that is being passed over is that 99% of coding work these days does not require a brilliant programmer. So while it may be true that CS grads are just mediocre... does that really impact anything?
A distinction that has not been made strongly enough here (though Roger gestures towards it) is the one between CompSci and Software Engineering - which are related roughly as mathematical physics is to civil engineering. My concern in sorting out recruitment candidates is not have they been exposed to low-level concepts; but whether they they can solve problems efficiently.

Me? An ex-mathematical physicist who cut his teeth on good solid scientific Fortran IV (no pointers or recursion there).
Steve: thanks for the physic/engineering analogy, I think that helps get at one of the big issues here.
I'm a student at University of Washington and would like to mention some of the things that are being taught here in CSE courses. It's not specifically relevant to Joel's discussion of Java-only schools, but I figure it might be useful in painting a bit of the picture of what some of us are learning before everyone thinks that kids these days ignore everything that isn't Java ;)

CSE 378 is Machine Organization and Assembly Language. It's a required course for both CS and CE, and while it's not really a course about how to be an awesome assembly hacker, we do write some programs in MIPS assembly and learn about how a processor works at the register level.

CSE 341 is Programming Languages. It varies what languages are covered, but when I took it, we had to do assignments in SML, Scheme, and Smalltalk. The class was more about programming language concepts and paradigms with the use of specific languages merely as examples and to get some practice and drive home the fact that we better learn how to learn new languages quickly. Recursion was used so much that I began to see mundane things like taking a sheet of paper from a stack and passing the rest of it on as a recursive function ;)

It's true that our introduction for programming courses are taught in Java and that there is no required course that teaches C. Many assignments are given in C anyway with a little bit of extra time and help for the first assignment for you to frantically learn C in all its pointy glory, heh. CSE 303 does cover C, shell scripting, and using Linux. It's a "highly recommended" course that I hear the department is considering making a requirement.

My opinion? Java-only seems to be an odd way to go, and I think it unnecessarily restricts the scope of a computer science education, and thus, some of the versatility of someone who graduates only knowing Java. I don't think their education is necessarily watered down, though; there are plenty of difficult problems and valuable contributions to make working at a higher level than C. I don't think computer science could progress so far without being able to abstract lower levels away and working in a ways that allow you to ignore them. It's the same in many fields of knowledge.

If all CSE educations were Java-only, then I'd worry about a Foundation Empire-esque collapse where there's no one who understands how some lower layer of technology that they depend on works. I don't really see that happening right now, though.

Steve mentions a good point. While there is huge economic pressure for computer science programs to churn out excellent programmers, that's not really what computer science is about. You could be an extremely good computer scientist and hate working with computers if you enjoyed working in computational theory. I think I'm just rambling now, so I'll shut up.
well, i don't agree with you because you have lost the "angle" from where the Joel was looking at Java. Joel said it is very difficult for him to differentiate between good programmers & poor ones because they have not learnt C, they just know Java. with Java you can not tell the difference between a good programmer & the bad one, with C you can. Joel got a scale marked with "pointers & recursion", now if you don't know C but other languages, it means that Joel can not test you :-( he needs a different scale & that does not mean you are a poor programmer

in other words, good programmers do understand "pointers & recursion" & they *do* carry that special part of brain which separates them from the herd of average programmers, now if they don't know C, Joel can not test them on his scale, they need to be tested on a different scale and by saying this Joel did not say that they are not good programmers. got the point?

i tried Java once, a long time ago, when i did not even know
what is Sun Microsystems :-), i knew only one word "Windows", sorry 3 words, Microsoft & Bill Gates too ;-) .

Java is a crap, same i say for VB. it is just a massively marketed brand like Windows. With Windows you can not tell the difference between a users possessing /common-sense/ & a user possessing /non-sense/, you are /stuck/, it will take a lot of time to figure that out BUT with UNIX (or any "Linux based GNU system") you can, you don't have to talk a lot. now that does not mean if you don't use UNIX you do not possess common-sense. actually, to sort that out, i have to forget about UNIX scale and talk from a different angle BUT with UNIX, you are enlightened :-) , try that for yourself. now, i spoke from experience.
So I'm about 3 years late to the party, but hopefully you're still reading comments on this one...

"Exceptions. He doesn't like them, bascially, because they confuse him"

I don't buy this. He goes into some detail as to why he doesn't like them, and I find myself mostly agreeing with him, so I suspect I'm as confused as he is. If you could shed some light on my confusion by arguing some points it further detail it'd be appreciated.
I think Joel's main problem is he went to college in the days of "Computer Sci is just Computer Sci & Programming", where as these days, Comp Sci covers a huge range, from OS programming, web programming, databases, etc, etc. Folks going into Comp Sci can branch into so many facets, and not all of them require his fundamental "C" learning. Heck, a person can go into Java & Web programming, and never care about pointers and crap. Folks can go into database administration and warehousing, and not care about C programming. Knowing more across he board gives you a broader perspective. And remembering my work with development environments, it's good to know that IDE's and things don't always write the most optimial (or lean) code. So, it's good to be able to dig down and tweak things as needed. But, he's lumping all "kids these days" into the same boat. It's like lumping all "Business Admins" these days into the same boat for not knowing Macroeconomics. Some are more accounting oriented. Others more marketing oriented. Others more systems / reporting oriented. We are in a time of specialization, b/c we can afford to have specialists instead of jacks-of-all-trade. I used to find Joel's writing intersting, b/c he had a good grasp on the people aspect of software engineering. But lately he seems to just ramble on about conferences and other crap he's whoring out. He seems less a source of information and insight, and more of a walking billboard.
I have been reading all the comments and let me just point out an interesting observation I made. For a novice coder like me, the original article, this post and each comment swings me between camps, leaving a lot of confusion behind.

Anyway the point I would like to make is you guys are talking about the effect this has on the elite programmers from MIT and Stanford. But when this kind of easy to learn/teach phenomenon reaches the lower level colleges this issue becomes more apparent. I think even if 90% of the IT jobs today don't require smart programmers, 'simplifying' down the course it only making it worse.

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
Comment text is Markdown.