I agree with Solar about learning C++ early on -- it's a great way to learn about how the machine actually works, and how that relates to programming in a higher-level language. However, I think stopping there would be a mistake. A good introduction to programming should include a survey of other programming paradigms. If Lisp is too weird for beginners, maybe a hybrid OO-functional language like Scala would be more appropriate.
In ten or so years, however, I think teaching C++ will be like teaching people to speak Latin. Sooner or later we're going to stop programming computers like they're sequential Von-Neumann machines and move on to a more parallel programming model. Sequential CPU performance has hit the wall -- we'll have no choice. However, I'm sure that even with this change there will be some middle-of-the-road language that can express higher-level ideas while still allowing you to program to the bare metal, and that language will take on C++'s role as a fancy macro assembler.
Speaking as an experienced software developer
with a CS degree, I agree that the quality of CS grads seems to have dropped in recent years since I graduated. I think this has a lot to do with the move from C++ to Java in the curriculum. It's no good to teach just the high-level or just the low-level. To really excel, you have to understand the entire stack, from digital logic (or transistors if you're really gung-ho) up to very high-level functional languages.
I don't think a CS degree is necessarily meant to keep you
out of programming. IMO programming is just the most detailed form of design, but it's still design. As the level of abstraction in mainstream languages increases, people will need more theoretical background knowledge to use them effectively. CS gives you the vocabulary to understand and explain such concepts with fewer words:
- "closure" instead of "a function invocation and its environment wrapped together"
- "Lambda expression" instead of "the body of an anonymous function declared directly at the point of use"
- "O(n^2) time" instead of "as the number of items being processed increases, the time it takes to process them increases on the order of the square of the number of items"
- etc....
It's just like design patterns -- a common vocabulary for expressing complex ideas quickly.
BTW Solar, in C++ terms a "closure" would be the result of using something like boost::bind or std::bind1st/bind2nd.