In Perils of a poor Computer Science Education — Part I, I said that I basically agree with Joel Spolsky in his post, The Perils of Java Schools. I do, but I can’t give the impression that this is the only path to being a great developer.
At UC Berkeley, the classes used Scheme, assembly, other languages, and primarily C. The very first course was nearly all functional programming using Scheme. I think using Scheme had three main purposes: to teach recursion (duh), to expand the students view into other programming models, and take the hot-shots down a peg — it leveled the playing field (a little). Most of the rest of the program was C. Here we used C for nearly everything including, of course, the complex data structures. Yes, lots of pointers.
So were the Scheme, C, and pointers necessary to help me become a developer of production-quality code? How often have I written a hash table for production? Rarely, but I’m way better at what I do because I know how to implement a hash table, and heinous balancing trees that I can’t even remember the names of, and how to debug at the machine level, and what a functional language is, etc.
That said, managed or scripted code is the way to go for 90% of the applications written today. Pointers aren’t so important and the data structures are covered by the frameworks. Clearly this kind of coding doesn’t demand the old-school Computer Science graduate. Merely great C#, Java, PHP, etc. developers run the gamut from important role-players, team members, to team leaders, etc.
I think the most important thing you can learn as a developer is to be flexible. Think outside of the constraints of the languages and tools that you use. If it helps you to learn a different language to enable this, do so. If it helps to go deeper into the runtime environment (e.g., deeper into the CLR or the Java runtime or the compiler / assembler, etc), do so.
Flexibility — that is the practical lesson of the Computer Science program.