Bjarne Stroustrup on the Problems With Programming
Hobart writes "MIT's Technology Review has a Q&A with C++ inventor Bjarne Stroustrup. Highlights include Bjarne's answers on the trade-offs involved in the design of C++, and how they apply today, and his thoughts on the solution to the problems. From the interview: 'Software developers have become adept at the difficult art of building reasonably reliable systems out of unreliable parts. The snag is that often we do not know exactly how we did it.'"
I wouldn't take programming advice from a guy who overloads the bit-shift operator to perform I/O.
Crack - Free with every butt and set of boobs
FTFA: "My brief definition is, correct, maintainable, and adequately fast. Aesthetics matter, but first and foremost a language must be useful; it must allow real-world programmers to express real-world ideas succinctly and affordably."
Sounds like Lisp to me.... It's a mystery to me why anyone would voluntarily program in a language that makes the things that should be easy difficult, and makes things like segfaults, which should be pretty darn hard to do, easy enough to accomplish by accident. Yet so many people do it.
"...looking at "average" pieces of code can make me cry. The structure is appalling, and the programmers clearly didn't think deeply about correctness, algorithms, data structures, or maintainability."
Maybe it's because the average programmer is enslaved in company business. They don't have the
time to create masterpieces or art in programming. Instead of that they are forced to create
something adequate in a given time. Happens almost everytime, when science becomes business.
I don't like that, you don't like that, no one likes that, but that's the way commercial industries
are working (at the moment).
Nothing personal, but Bjarne Stroustrup comes real short in the real world department. He has not been in the position of solving real world problems with C++. Someone like James Coplien has. I would be much more interested in the commentary of a front line warrior, than I would from a theoretical preacher.
"To those who are overly cautious, everything is impossible. "
To all those people saying C++ is too dangerous/prone to errors and Java/C## is the way ahead:
Stop blaming the tools and look to yourselves.
C++ is like a sharp scalpel. Yes you can hurt yourself if you're unskilled, inexperienced or sloppy.
Java and C# are like those scissors with rounded ends for kids. Totally inefficent but safe for beginners.
Unfortunately it seems that there are a lot of people out there who like to call themselves programmers but have no actual ability. Java/C## does a good job of removing their need to think and hiding their inate lack of skill which is why they prefer it.
But there's a reason why surgeons don't use plastic scissors. The same applies to good software engineers.
Well in my experience they had me learning C on Unix, then Bjarne Stroustrup (along with another professor) taught us C++. I must say that learning a programming language from the creator isn't the best way to do so, as he will begin to go into the extreme detial of how a pointer in C++ works with no regard for the fact that it might be too much information for the first week of class. But it is a great way to scare the ever living piss out of freshmen in college that are considering to become computer engineers.
Actually, I like VB. I believe it's good for what it's for- RAD and if properly used (as applies to any tool). But too often its seen as some kind of panacea, at least in this part of the world, for IT education. It's probably the power of the Microsoft brand (if not the product(s) ) at work here...
VB is a rapid prototyping environment. And just like an RP machine, it makes a flimsy product that you can send back to the drawing board without much expense. But you don't ship a product you've made on an RP machine -- it's crap. You take your prototype, and make a real product out of it using sturdy materials. Same goes for VB. You make something that works the way you expect, then you make it work in a real language. Good thing about VB is that you can replace pieces at a time with DLLs compiled from C++. If that isn't a part of the VB curriculum, it's a waste of time.
The KISS principle is totally lost on that guy.
The moment you have 2 people doing C++ on 1 project, at least 1 person will be faced with code written using features they just don't understand. C++ has features to spare.
Think you know C++? No, you don't. Heck, the compiler developers are often unsure.
This is a recipe for disaster, as we often see.
C was hard enough. Few people truly understood all the dark corners. (sequence points, aliasing rules, etc.)
C++ is addictive. Everybody wants one cool feature. C code is somewhat easy to convert. Soon you're using enough of C++ that you can't go back, and hey, more is better right? The next thing you know, some programmer on your team got the wise-ass idea to use Boost lambda functions (for no good reason) and you find yourself with 14 different string classes and... you have a mess that no one single developer can fully deal with.
Of course surgeons don't use plastic scissors. But how often do you need a surgeon? Most of the time you need a cheap tailor to make you a suit. And that's when scissors come in handy.
C++ can do wonders when used by highly experienced people. But most of the time, it is more cost effective to get entry level coders and use PHP/Java/C#/whatever. You will get a (somewhat) working product cheaper and possibly faster. And time to market and cost is often more important than maintainability/quality.
And don't get me started on 3rd party C++ libraries. You'll need tons of them to move a finger, and you'll spend more time finding/eavluating libraries than coding. This problem is getting worse for other languages too...
--Coder
The problem with C++ is Stroustrup. Specifically, it's that, as what's now called "C++0x", the next revision, got underway, Strostrup insisted that C++ had no major problems - it just needed some cleanup. This was after a decade of trouble with buffer overflows and related safety issues.
C++ is unique in that it has hiding without safety. No other major language is in that space. C has neither hiding nor safety; Java has hiding with safety, as do almost all languages which postdate C++. This is not fundamental to a compiled language; Modula 2 and 3, and Ada, had hiding with safety. Nor is it related to garbage collection, inherent problems of an efficient, compiled language, or the needs of systems programming. Providing backwards compatibility with C while bolting objects onto the language led to safety issues that were never overcome.
Most of the problems with C stem from the "pointer equals array" model, the basic source of buffer overflow bugs. C doesn't even have a way to talk about the size of array arguments (well, C99 does). Dangling pointers are also a problem but a secondary one. C++ tries to paper this problem over with collections, but far too often, collections have to expose a C pointer to get something done. At that point, size information is lost. Right there is the biggest single problem with C and C++.
The C++ revision committee is dominated by people who want to do l33t things with templates, things nobody will ever do in production code but, they think, are really cool. There's a whole "generic programming" cult of abusing the template mechanism to do computation at compile time. Millions of users suffer from unnecessary program crashes, and the US is more vulnerable to malware and cyber-terrorism because of this focus. It's as if the IEEE committee on power transmission standards was dominated by people who were into making big sparks.
Stroustrup could have insisted on actually fixing the safety problems. But he didn't.
(I'm writing this as someone with over ten years of experience in C++, doing everything from protocol stacks to game physics engines to real-time programming. And after ten years, I'm fed up with the mess. This should have been fixed years ago.)
The problem with programming is that too many people that lack the talent are in the programming business. I know because I work with many of them. They are not detail oriented, they don't think strategically, long term, etc and just make a mess of code. They only want to fix the problem they need to fix without worrying about the effect it will have on the system, etc. This is what causes bad programs. Programming is easy enough that any moron can make something work, but to make something continue to work requires an engineering understanding, and this is something most people don't have. It's unfortunate.
Exactly.
C, C++, Java and god forbid VB should be prohibited by law for university courses and any person teaching them during the first 2 semesters in CS should be prosecuted for child abuse. Pascal (even without the object oriented extensions) remains the best language for teaching the first years in CS. Once students are past their data structures course and know how to deal with linked lists, pointers, objects hashes and the like you can switch to C, C++ or Java with minimal fuss. Before that its outright criminal. In fact the total amount of hours spent till the point when the students can produce something that will pay their daily bread will most likely end up being less than the required when teaching directly in C/C++.
There was a very good article on the subject by Joel called The perils of Java schools and I tend to agree with it 100%. In fact I will extend its reasoning further to C and C++. Probably the most important part of teaching a data structure course is to teach it in a language that has a clear syntax and "one way to get it right" for pointers, linked lists and the like. C and C++ are insufficiently clear and unambiguous. Java simply does not allow you half of the things you need to do in that course.
Many people advocate for the usage of Java and especially VB from the perspective of "look how fast can I learn to program in these". That is irrelevant as far as university courses are concerned. What is relevant is will the student learn to produce literate, commercially viable code or not. If he has been subjected to VB - never, Java or C++ - not bloody likely, C - it may work but it will be anything but readable for the first 10 years of his career.
Baker's Law: Misery no longer loves company. Nowadays it insists on it
http://www.sigsegv.cx/
I don't think the main issue is which language you start with. What's important is that you teach people multiple paradigms and multiple languages, so that they are aware of them and their strengths and weaknesses.
Please correct me if I got my facts wrong.
Ok, then please explain why Open Source projects are full of flaws just like commercial products. Are all the geniuses exclusively employed by companies that stifle greatness and everyone else is doing Open Source? Please. Programming greatness is rarely achieved... anywhere. The problem developing for profit is that you need a product to profit from. That means you have to ship something that is imperfect just to stay in business and make a living. The problem developing on your own for free is, again, that you need to make a living and really don't have the kind of time to produce greatness (assuming your are capable). Either way, it comes down to resources. One can rarely get enough outside of work and one can rarely get enough AT work. Same problem. Business drives development just as much as it stifles it.
-matthew
"THERE IS NO JUSTICE, THERE IS ONLY ME." -Death
I disagree. Programming isn't something you learn from someone else. Programming is something you learn by yourself. Of course, you can get excellent help/lectures/tips/advice/insights/whatnot at an university for example, but my point is that in the end you have to sit down and think and then write some code (and figure out why it doesn't work) by yourself. I would say it doesn't matter if you start with Visual Basic or Pascal; if you haven't got the ambition/derive/whatever to really sit down by yourself and figure things out, you will never be a (good) programmer.
Many of the points in the interview implied that software was simply soaking up all the hardware performance, and perhaps we could squeeze more out of the software. I completely agree, except ...
s /NoSilverBullet.html
http://www-inst.eecs.berkeley.edu/~maratb/reading
The problem is that the software is an order of magnitude slower than it needs to be because the hardware has increased in performance by 2 and 3 and 4 orders of magnitude. If we had held the software to the same standards as we used to back when the hardware cost more than the programmers, it would be more efficient - but would only be able to make use of a couple megabyte of RAM and disk. The looseness of current software is part and parcel of harnessing the hardware. The hardware didn't just allow us go loose with the software we wrote - it allowed us to use abstractions which were measurably less efficient, but which had the side effect of allowing us to harness the hardware in the first place.
As a pair of trivial examples, take arrays and dictionaries. When I ask interview questions like "Design a hashtable" or "Reverse a linked list", many candidates have to actually step back and think about the question! 30 years ago, designing a good hashing function was the mark of true talent, and gains were to be had by selecting the linked-list scheme which best suited the problem at hand. These days, many people don't really know why you'd use a map versus a hash_map, or a vector versus a deque. And, for the most part, they don't really need to.
You want Lisp. Hear me out.
Of course, the character syntax is superficially different. Operators use infix notation ("(+ 1 2)" is analogous to "1 + 2"), and have identical character syntax as function calls ("+", an operator in Lisp jargon, may be implemented as a function).
If you can sleep at night after that, your can define own higher-level language syntax that looks exactly like any other Lisp syntax. Lisp is extremely flexible in its naming of functions and variables (symbols). If you'd like, you could define an operator named .= as a function: (.= string new-character-strings ...) would modify the given string object, string , in-place, appending each specified new-character-string to the end.
Recognizing the downside to modifying random strings in-place, perhaps you'd rather have your .= operator assign a newly-instantiated string to the variable referenced by string . You could, by writing the operator as a macro. The macro would act like a function, taking as input each "raw" argument—symbols and lists, the structure as they appear in your program, before evaluation—and returning as output replacement Lisp code to evaluate in its place. So that your .= operator form of (.= out "lalala") is semantically equivalent to (setf out (concatenate 'string out "lalala")) (like out = out . "lalala"; in other languages).
It's not just simple textual substitution. You can use any function or macro in your macro definition to transform your input arguments into whatever replacement code you'd like. I'm using macros in Common Lisp to generate recursive-descent parsers based on a grammar production expression: the following form defines a function named obs-text that takes a string as input and returns a list of matches found as output:
(defproduction obs-text :* CR :* (obs-char LF :* CR :*) :*))
(LF
This function is defined in place and evaluated and compiled immediately by the Common Lisp implementation.
Macros can be abused, but they add a tremendously powerful capability of abstraction not possible with many other languages.
Sometimes code is bad because the programmer is not very good (vast majority of cases).
I hear this quite a bit and I think it's probably a flawed assumption or at least to simple a statement to describe the truth. The vast majority of developers can't be below average or the average would drop. What we can say is that a good portion of developers seem to have a poor grasp of basic software development skills. What we need to ask then is why.
In my experience there seems to be far more variation in skill level between software developers than I have seen in any other profession. Perhaps this is simply because I am only familiar with software development and there is the same spectrum width in other professions as well but I somehow doubt it. I suspect, however, that software development is actually a very very hard process that only a small number of people truly have the mental discipline for. Since that number is less than the number of developers required we need to do something to make software development easier for the masses of developers. This is similar to the way cabinets were made. The master cabinet maker would produce the top and front and the less skilled (apprentice) would produce the frame (since it's easier).
I used to have a better sig but it broke.
yes, for Rapid Application Development. However that is *not* the point of studying computer programming.
While a good coder knows when to re-use code. A coder incapable of originating complex code is little more then an automaton.
I'm sick of the 'don't re-invent the wheel' argument being dragged out and used to justify people not studying properly, or for that matter, not teaching properly. I was lucky, I attended a course where most lecturers believed that students should code their own assignments.
Examples being recursive functions, sorting functions, Dijkstra's shortest path algorithm, stuff like that. However I have recently had to cope with people being given exactly the same type of assignment, and being allowed to download pre-built classes for them! What, I ask you, is the point of that?
>> C++ defines container classes which cannot overflow.
>> Try using them next time you write some C++ code.
>
> No, the STL defines container classes, and they suck
> just as badly as the C++ language itself. Performance
> goes out he window unless you spend inordinate amounts
> of time ensuring that all the classes you put into the
> containers are setup to avoid multiple copying. This is
> a major pain in the arse, as different implementations
> of the STL have different semantics, and "accepted best
> practice" is to not to hold a copy rather than a
> reference to an object in a container
On the contrary -- the GP is quite correct. First, the STL ist not called the STL anymore for ages. It is part of the C++ standard library. And that's what it is -- a STANDARD. Compilers that do not follow the semantics described IN the standard are plainly broken and should only be used with care, if at all. But this is always a problem with languages that are implemented by a lot of people. Java for example is simple, because there are only vert few implementations in existance, and most probably 95% of the people using Java uses the one done by SUN. I think only very few use gcj for example.
Also the STL is not that complex as you think and it really is efficient, if used correctly. But that is the case for any library and any tool. Furthermore one can always put pointers to objects in a container, which is the same as using a reference. And if you want to have some safety there, use a smartpointer -- there is nothing complicated about that. The discussion here really shows that C++ is indeed a COMPLEX language and that indeed it is NOT UNDERSTOOD by many of us here. But I think those who have worked with it for some years and REALLY UNDERSTOOD some of the more complex topics of it, will admit that C++ is a powerful, efficient and elegant language. There is no all-purpose language that is ALWAYS simple, efficient and elegant. This just can't happen. But C++ fits a lot of purposes well. For example for many occasions I write small python programs when I need to do some parsing, conversion or small calculations. That's totally great! But I also use C++ for larger programs, because it offers a vast amount of libraries and ideas. Not having to implement my own partition, sort, find or vector every time is really helpful. And those algorithms even run very fast on all my self-created types.
[--- PGP key and more on http://www.root42.de ---]
I think that students should start with C, move to pascal, then onto perl/python/lisp, and after that C++, or perhaps java (even though I hate that language, and I've had to teach it, so I'm not blindly critical). A smattering of php wouldn't be bad.
nice.
I don't object to java being taught, just the use of premade code to replace having to do stuff yourself.
Do ensure you widen your skillset well beyond java though, single language knowledge is a bad idea. Knowing several and specialising in one is better, since you can move to different languages as the need arises with ease.
Anyway... I think the problem may be that VB is too easy to use. People who would not be able to write the makefile for their 'Hello World' program in C++, are able to write working but very rickety/ flimsy VB programs.
I happen to make a living as a computer consultant. This means I get to see a lot of different organizations and their in-house software... This means a LOT of VB code... And of that VB code, a lot (maybe 90%) is written by people who may know their business but don't have a clue about programming. I can definitely see how that would create the reputation that VB programmers are bad, but not how it makes the LANGUAGE bad.
As for stability, I can promise you that some of my VB programs are a hell of a lot stabler than the memory-leaking SEGF/GPF-ing C++ hacks they replaced. In case you didn't know - it's perfectly possible to write shitty C++ code too. It's just that you have to get above a certain level to even get the compiler to work, so most of the would-be self-made computer wizards turn to something easier instead.. Like VB.
The big question here is: Is it better to have a flimsy but functioning VB program or a defunct makefile? I'm not sure of the answer myself. A defunct makefile is a 5-minute job to fix, whereas some of the VB messes I've seen would literally take years to get straightened out. (I hate people who think they can program just because their $h!+ compiles.)
It's better not to encourage the belief that one language can be good for everything. Students invest themselves in that belief quite strongly anyway just because of wishful thinking.
They also acquire the belief that unfamiliar syntax is a serious barrier to learning a new language. Forcing students to learn a few languages with different-looking syntax might help. The superstition seems to be reinforced by the fact that their every attempt to learn a new language lasts about two weeks, so giving them brief exposures in a class about programming language concepts would only reinforce it. Better to teach a language by making it the official language of a certain class and requiring that all programs for the class be written in it.
That's a good question. The purpose of a programming language is much the same of that of mathematical notation, which is to allow you to think at the level of abstraction of your problem while not wasting time with irrelevant details. Modern calculus notation gives university freshmen the ability to solve problems in a few hours that baffled the greatest minds of history for thousands of years.
Note that this doesn't mean that you don't have to think when learning a mathematical language. The concepts of limit, derivative, and integral are difficult to grasp at first, but once you understand them, they offer powerful mathematical methods that allow you to think about the problem at hand and not the notation you're using.
Can computer science make similar claims? The jump from assembly to FORTRAN was a tremendous improvement in productivity, but FORTRAN to C or C to C++ produced small to no productivity improvements, perhaps in part because you have to think more and more about the language. We should be looking for a language that may require thinking to learn, but that once when learned offers powerful methods at a high level of abstraction that allow you to think about the problem without being distracted by the language.
I would suggest that we look at languages like Haskell, Scheme, or Smalltalk, which do require that we learn concepts like currying, higher-order functions, monads, and type classes, but which offer a higher level of abstraction and greater consistency than languages like C++ or Java.
Not enough is made of the sheer obfuscatory nature of C++. C was already somewhat cryptic, but at least it was small. C++ is cryptic and large, and that's really a bad combination. At one point in the interview Stroustrup recounts that half the programmers he polled who said they disliked C++ then admitted they had never programmed an application using C++. He calls that prejudice. I call it perfectly normal human behavior; if you begin to study a language and quickly discover it to be a load of tailings, then you will be disinclined to program applications using it.
That was my experience anyhow. I began studying C++, and at some point I stopped and asked myself, "Why must I endure this? Surely there must be better options." And I was right.
I really have to grit my teeth when Stroustrup talks about C++ "winning" against competing languages. C++ is successful for the same reason that COBOL and Microsoft Windows have been successful: because they happened to appear in the right place at the right time, and were promoted by the right people, to become entrenched. Once entrenched, the world was saddled with them for decades to come. It has nothing to do with their inherent qualities or advantages, it's little more than random chance.
"Coding it? Why? Only to prove to yourself that you can do it! I did it when I was younger. "
No No no no no!
To learn it in the first place! Weren't you paying attention? You even demonstrated my point by saying 'I did it when I was younger'.
Yes, you did, so did I, would I re-write something when someone had a better implementation than me? Perhaps, if I wanted to learn how to do it, but not if I needed it soon, or had reasonable assurance that the existing implementation was better then I could do myself. However I have yet to move into a new area of coding without getting my feet wet by implementing some of the code used in that domain myself, just to know what I was talking about.
What's more use, a programmer who has learned about a thing, then produced on his own an implementation of same, however basic, or one who studied it just to pass an exam and never built it in the real world?
C++ vectors *can* be used safely, but the library designers used traditional, easy-to-read syntax for unsafe access and verbose, hard-to-read syntax for safe access. They clearly meant for unsafe access to be the norm and safe access to be used in special cases. I'm a C++ fan, but in this case they screwed up badly.
it's not-so-strongly-typed variables, funny rounding rules and so on
I know they're like [pagan] Gods to an awful lotta people in the CS community, but The Founders of The Art, guys like Kernighan, and Ritchie, who had the chance to insist that a declaration actually mean something, but hesitated, and hemmed and hawed, and got all wishy-washy, and finally decided [really deferred a decision until it was too late to make a decision] that a declaration could mean any-damned*-thing that the implementor wanted to interpret it to mean, well those guys, those pagan Gods of the Founding Arts, seriously - someone should take them out behind the toolshed and whip their asses** [if not shoot them outright].
So now, fast forward 30 or 40 years, and we've got:
And then you go to do something in VB, or in Javascript, and you get shit** like
or, what's even worse,
and you end up having to write shit**** like
and you scream at your computer, "YES, THESE ARE NUMBERS, NOT CHARACTER STRINGS, YOU GOD-DAMNED***** COMPILER/INTERPRETER/SYNTAX/PARADIGM/NIGHTMARE OF A SACK OF SHIT******!!!!!"
PS: There is a special circle in Hell******* for the sonuva bitch******** who dreamed up the idea of interpreting variable types on the fly...
*Pardon my French.
**Pardon my French a second time.
***Pardon my French a third time.
****Pardon my French a fourth time.
*****Pardon my French a fifth time.
******Pardon my French a sixth time.
*******Pardon my French a seventh time.
********Pardon my French a final time.
From the article:
How often have you worked on a prototype or demo, only to have the time/expense budget slashed because management decided you must be almost finished when they see a demo GUI?
How often have you encountered copy-paste-edit code replicated throughout a system because no one had the time to refactor the replicated code into a reusable module?
When did you last have the time and budget to clean up that rushed prototype via refactoring before the next phase was in crunch mode?
How often were you told you can't refactor code because it's already been tested and put into production?
How many "silver bullet" tools have you tried over the decades, only to find that they're marketing hype and often increase the total workload instead of saving time? (e.g. Now you have to maintain UML models as well as the code and database schemas.)
As long as the "push" is to get it done faster regardless of long-term costs, crap code will continue to churn.
I do not fail; I succeed at finding out what does not work.
Me too, though this was purely coincidental because where I went Pascal was not a pre-req for C. But when I finally got to my C course, which by the end of the year had a dropout rate of 50%, it was relatively smooth sailing. I already knew how to program from my Pascal course, and heck, even the syntax was close enough. This is from someone who took CS courses just as a curiosity, I actually wanted to be an electrical engineer. I say that to make the point that I had no prior programming experience, and yet after just one semester of Pascal, I was ready for C. Pascal is the perfect primer for C; I dare anyone to name a better language for that purpose.
blah blah blah
Grrr.
If that's a computer science course, or any other degree that purports to teach fundamentals, that's so wrong it's not even wrong.
You have to learn the fundamentals, not use ready made components. Indeed, I'd advocate at least some assembly language programming, because this forces you to think HOW the machine actually does things. It needn't be x86 or anything particularly fancy - but something that will at least teach the student on an absolutely fundamental level what happens when you get a buffer overflow that starts overwriting the stack.
Oolite: Elite-like game. For Mac, Linux and Windows
I think they should learn computer languages in the order that they evolved: assembler first, then FORTRAN, then Pascal (as the ALGOL representative), then C, then Smalltalk. Maybe throw Lisp in there between FORTRAN and Pascal (even though I believe it's older than FORTRAN). Actually, C is kind of a step backwards from Pascal (limited scoping and no built-in I/O), maybe just tack that on to the last couple of weeks of assembler.
And let's not forget that students should really be studying computer science, not programming. They shouldn't learn how to do a binary search, they should learn why it's such a powerful technique. The implementation falls out naturally from the description. Likewise for trees of various flavors. Teach them how to identify the language features that best support the algorithms they need, and let them figure out which language is most appropriate for themselves. After all, any language they learn in college will be out of favor by midpoint in their career anyway (or earlier, for those of us that learned Pascal...), so better to teach them how to learn a new one from the start.
Just junk food for thought...
What separates the good from the bad in the real world is context. Some guys are great at setting up wikis, installing automated testing harnesses, and designing test cases. Others are good at talking to customers and managers. Others are good at debugging and profiling. Others are good at cranking out boilerplate implementations of business logic. Others are good at sitting alone in an office writing diagrams and mathematical equations, designing out redundancy. Others are good at understanding other programmers' minds and produce great APIs and documentation.
Almost everyone is hopeless at one or two of the above, and some people are brilliant at one or two but hopeless at the rest. A guy who is brilliant at one thing is going to fail in a three-person startup where the other two people are nontechnical. Likewise, a versatile, Perl-scripting sysadmin may be a crackerjack developer for a small company, but hopelessly outclassed when placed in a specialized role in a big development group.
Lisp should definitely be in there. Heck, start all the students on Common Lisp and we won't have everyone thinking all languages need to look like Algol.
While I'll agree that those things are very useful to know, I'd have to say that it depends on what they plan on doing with the training. Computer Science, as a discipline, has a markedly different focus than Software Engineering.
I've heard it said more than once that good software developers in commercial environments come mostly from engineering backgrounds rather than mathematical or computer science backgrounds. The key difference is in the repeatedly emphasized end goals. Engineering students are taught very quickly to think in terms of tradeoffs and utility. Theory focused students are trained to think in terms of ideal structures.
Both have their place - no engineering would work without the carefully worked out theory. However, I think where I'd diverge would be in the more theoretical training such as the various tree types and such. Those come into play in relatively small subsets of actual programming practice and modern languages generally have ready implementations.
What seems to get slighted most, from what I've seen are flexibility, reliability, maintainability and good software engineering practice. There should be intensive coursework that emphasizes these elements just as much as theory. As Stroustrup said, those are precisely the things that are hardest to build in but are the most critical.
While you can bash the tools as much as you want, the point remains that the majority of the fault for bad programs lies with the programmer.
.S files created by your compiler? Do you even know what they are? Could you load an object file into a disassembler?
Just as an adept sculptor can build a beautiful (though somewhat rough) art piece using a chainsaw, so can a good programmer make do in situations where he is forced to use the wrong tool for the job.
Namespaces can be simulated with a good naming convention.
OO can be accomplished in a procedural language.
Technologies can be married together, and even replaced in part with other technologies at a later date (it's called refactoring, folks!)
I currently program exclusively in Java. I learned from the ground up (Analog electronics -> Digital logic -> Machine code & Assembly -> C -> C++ -> other OO languages & scripting languages, AOP etc)
I'd love to have multiple inheritance in Java, but I hate the fact that you can't rebind a reference in C++.
I'd love to have real properties and closures supported by the Java language proper, but I make do with standardized boilerplate code in the meantime.
I love the quick UI building you can do in VB, but I certainly wouldn't want to write business logic with it!
Access is great for building quick and simple systems, and does its job well, but I'm not going to store 10 million records in it!
Nothing beats the speed of a library written in assembler, but I'm certainly not going to write database access code in it!
Perl is a great tool in the right hands. In the wrong hands, it is the worst disaster ever, and the first thing I get rid of when I take over support of a project (except for 10% of the time when the previous programmer was competent).
I've seen horrendous code in every language I've ever encountered, and it's always a result of the programmer not understanding what he's working with. My personal opinion is that you shouldn't be programming unless you understand at least one layer below where you're working.
Do you know how to examine a core dump? How about interpreting a Java HotSpot dump?
Do you understand how the technology you're working with interacts with the operating system?
Do you know how the auto-code generator deep within the script overlay you're using actually works? Have you even once looked at the intermediate output?
How about the
What will you do when something goes wrong with it? Give up?
Do you follow the generally accepted practices used in your domain? Do you even know what they are?
Do you know what domain driven design is?
Do you understand when it's a bad idea to use inheritance? (Answer: most of the time)
I could go on forever. The point is that good programmers find the right tool for the job because they understand how it all works. Hackers do it fast, but forget to make it readable or maintainable. Bad programmers just plain do a bad job and make things shitty for everyone.
That's a stupid progression to take. First of all, they'll likely never use Pascal. It hasn't been used on the Mac in well over a decade. Delphi is basically dead. It really doesn't offer anything over C.
When you get them studying so many languages, they'll never become competent with any of them. You'll end up with a shitty C programmer, a shitty Perl programmer, a shitty Pascal programmer, a shitty Common Lisp programmer, and a shitty Java programmer.
It's better just to stick with C++ and Common Lisp (or Scheme). C++ will give them a real-world language that is suitable for a wide range of embedded to desktop applications, while Common Lisp will expose them to functional programming and other critical concepts missing from C++. So now you end up with a well-rounded student who has had the time to focus only on a small number of languages, thus becoming proficient (hopefully) in both. At that point, they should be able to pick up languages like Java, Objective-C and Python within a day or so.
For those of us working in the "gutters" - embedded systems stuffed into the sometimes gludgy real world - only a language like C++ will do. A polished user-level GUI app running atop layer after layer of abstraction can be written in something slick and aloof like Java, Lisp, or some nifty obscure language. ...but for those of us writing specialized critical apps running on minimal hardware and dealing directly with the real world, we need something that has only the thinnest layer of abstraction, is comprehensible and predictable, and will reliably affect reality.
Sneer at "gutter"s as you like. Your house/apartment has them, your business/school has them, you don't notice them when they work, but they are quietly everpresent and designed by someone who had to think about them and use specialized tools to make them - and life would be less pleasant without them. Ditto for lots of C++ apps. You don't really expect a Java VM running on your toaster, do you?
Can we get a "-1 Wrong" moderation option?