Twenty Years of Dijkstra's Cruelty
WatersOfOblivion writes "Twenty years ago today, Edsger Dijkstra, the greatest computer scientist to never own a computer, hand wrote and distributed 'On the Cruelty of Really Teaching Computer Science' (PDF), discussing the then-current state of Computer Science education. Twenty years later, does what he said still hold true? I know it is not the case where I went to school, but have most schools corrected course and are now being necessarily cruel to their Computer Science students?" Bonus: Dijkstra's handwriting.
While the handwriting is a novelty (and the PDF is actually small for a PDF), I question how long that server is going to last.
Also (and yes this is nitpicking), I must contest this:
Edsger Dijkstra, the greatest computer scientist to never own a computer
I submit for consideration Alan Turing who may have designed the ACE and worked on the earliest computer (The Manchester Mark I) although never really owned it or any other computer. I think a lot of people identify him as not only a hero of World War II but also the father of all computers.
My work here is dung.
They made us do mostly Java, even though a number of us could do C or C++.
I'm a high-school student and I know that most people here can't even pronounce his name.
Regardless of the state of Computer Science, what most students studying the subject really are after is software engineering. The world doesn't need more people arguing over P=NP; it needs people who can build (and manage projects to build) software systems which solve real-world problems.
A slashdotter who didn't build his own computer is like a Jedi who didn't build his own lightsaber.
When I took my C++ Data Structures course, our final was 36 pages long. We had to hand write our code answers. That was cruel. That was in the ol' year 2000.
No single raindrop believes it is to blame for the flood.
I agree that teachers disconnected from reality are bad, but the alternative is even worse. Look at what too much bitching got us: they teach JAVA as the primary programming language in universities nowadays! How sadistically cruel is that?
Sounds like a typical computer science professor. Mine usually couldn't use a computer at all. And yes, mine were generally very cruel. Giving examples that months later they figure out were wrong, making us code with pen and pencil, teaching fake assembly languages and fake operating systems.
I'm glad I left, cause I can actually now use a computer, unlike much of the coders I come across. If you like computers, don't go into computer science. That is for people who enjoy math and theory.
The aim of a really good degree (as opposed to a lecture driven box ticking one) is to be cruel, you want to feel that your head is going to explode and that your subject really is an absolute bitch.
Then you graduate and find out the real world is easier than the theory.
Cruelty is important in a good education to make you achieve in the real world. An easy flow through degree gets you the cert but gives you unrealistic expectation of how hard the real world can be.
Personally my degree was a mind bending bitch of mumbling lecturers and impossible (literally in some cases) questions that covered everything from quantum mechanics "basics" and abstract computing theory through to how to dope a transistor.
It was cruel, it was unusual... it was great.
An Eye for an Eye will make the whole world blind - Gandhi
Ofcourse I can write a line of code!
Behold, in al its glory:
printf("hello world");
I think we can keep recursing like this until someone returns 1
There's nothing exceptionally wrong with Java as a starting language, though I may be biased since that's what we had. In any case, my uni has now switched to Python, which is probably even better.
True confidence comes not from realising you are as good as your peers, but that your peers are as bad as you are.
Edsger Dijkstra, the greatest computer scientist to never own a computer...
So, his Macintosh wasn't a computer?
"You cannot simultaneously prevent and prepare for war." -- Albert Einstein
I agree with that, but it isn't only in CS courses that programming should be taught.
The problem I see in current engineering and sciences courses is that they don't teach numerical analysis. Engineers and scientists today try to do everything in matlab or excel, except for those that do postgraduate courses, who often try to do things in fortran.
Programming languages are tools that anyone involved with advanced uses of computers should learn to use. If you are a professional you should know how to use professional tools.
Dijkstra's Cruel Font link, so we at least get something recent(-ish) out of this article.
cat > hello.c
printf("hello world");
^D
gcc hello.c
hello.c:1: error: expected declaration specifiers or '...' before string constant
hello.c:1: warning: data definition has no type or storage class
hello.c:1: warning: conflicting types for built-in function 'printf'
While there are a number of things this gentleman has correct, there are also a number of dreadful errors here. Two examples: he subscribes to the belief that the Middle Ages were "poor fools" and he denies that Arithmetic is the derivative of physical problems -- one apple and one apple can be written 1a + 1a = 2a.
http://www.allen-poole.com/
I'd have to say in recruiting software engineers I have much more of a problem with theory-light code monkeys than I do with non-coders that are well-versed in CS theory. With the former you wind up with people who can't leave whatever language they're most familiar with and don't really understand why what they're doing works (cargo cult programming). It's easier to teach good coding practices in the field than it is CS theory.
My technical interviews aren't full of riddles or obscure CS theory questions, but I ask a series of pointed questions to see if the candidate has a good familiarity with the various language families (not just particular languages), common data structures (they should at least have encountered them, even if they need to look them up to implement them), and can talk in terms of pseudocode and algorithms instead of just library functions and language idiom. Language experience is a plus, but definitely not required.
"The problem I see in current engineering and sciences courses is that they don't teach numerical analysis. Engineers and scientists today try to do everything in matlab or excel, except for those that do postgraduate courses, who often try to do things in fortran."
Maybe in computer engineering they might but I learned mathematical analysis right off the bat and no it wasn't post doc. It's kind of hard for one to call themselves an engineer and not know that.
Shai Schticks:"You don't make peace with friends, you make peace with enemies"
Java is not the best choice, but it is a wiser one than C, for example. The guy has to forget a little about memory management and pointer arithmetics on his first steps. After he has some experience with programming he can get into low level details
I had professionally worked with a couple of languages, which includes Java and python. That being said, I see strengths on both languages but I think python is a better choice for introductory courses.
One thing that I believe is very important is to make them program in more than one language. CS majors should understand that there is no silver bullet. Each language has its place and time and a good professional have to be ready to handle more than one tool.
-- dnl
I'm grateful that I have a computer science degree, it has enabled me to have a deeper understanding of all the things I administer on a day to day basis. It is nice to know how spanning-tree actually works on my switches, and how databases actually use data structures to store and retrieve data.
I'm not designing and building these systems, I'm installing, using, and maintaining these systems. Do I need a CS degree to do this? Hardly.
If you like installing and maintaining computer systems, but hate math and theory - don't go for a CS degree. You will be better served by doing your own research/training, getting some certs (RH, MS, Oracle, Cisco...etc) and if you are so inclined, maybe a 2/4 year IT Management degree.
If you want to build the products that people install and use (software more complicated than a web page or login script, hardware, firmware for embedded systems...etc) you will need to endure the math and theory that a CS degree requires (and possibly an Electrical Engineering/Computer Engineering minor as well).
-ted
I study at the university of Eindhoven, where dijkstra was professor. He certainly left his mark on the curriculum here with constructing programs by proof by using hoare triples and much more.
A lot of the staff here see him as sort of a role model, with the same proofs, handwriting and abrasive personality.
But now the last year most of those subjects are being removed, or reworked to something more manageble. They where so disconnected from reality (proving horners scheme in so many ways gets old quick).
Dijkstra's quote "Computer Science is no more about computers than astronomy is about telescopes" is in my opinion just wrong. Astronomers need to use a telescope and understand its operation.
As opposed to IS students, who can write reams of code but have no idea what's actually going on?
Dijkstra was a genius and made many contributions to Comp. Sci. But his suggestion that a program (really a program design) should be accompanied by a formal proof has problems at both ends of the development cycle: how do you prove that the formal specification is what the customer wanted, and how do you prove that the code actually implements the design?
I've seem automatic testing products that claim to do both, but in order to make them work you have to specify every variable and every line of code as the "requirements", then compare what the tool thinks the result should be to the output of the program. And yes, the vendor suggested that the business analysts write the formal requirements; you can imagine how well that worked.
There's nothing exceptionally wrong with Java as a starting language
Yes, there is. It insulates the student from some concepts that are important and because it's so aggressively object orientated even the standard "Hello World" program requires quite a bit of glossing over by the teacher.
As a result, it tends to get waved away as "magic" or "this will be explained later" but there's so much waved away that the students get disconnected. For instance, to simply output a line to a command line in Java you're looking at
System.out.println("output");
whereas with c++ (for instance) you have
cout << "output" << endl;
As someone who's teaching this stuff, the second is easier to explain in detail and doesn't rely on saying "don't worry what System.out is".
The other prime example when teaching object orientation is garbage collecting. Students who learn in Java are significantly more difficult to teach about dynamic memory and the necessity of cleaning up after themselves than those who've learned in other languages that don't abstract this away. It's much easier to switch from C/C++ to Java than the other way around.
The standard way of teaching basic programming is procedural, then functional, then object orientated then onwards. Using Java to teach in that cycle is nuts. How useful that cycle IS is another question, of course :)
Rational thought is the only true freedom
"Right from the beginning, and all through the course, we stress that the programmer's task is not just to write down a program, but that his main task is to give a formal proof that the program he proposes meets the equally formal functional specification."
Where exactly do semi-formalized, poorly thought-out specifications handed to you half-written out on a napkin and constantly subject to change fit into the programmers task and Dijkstra's world?
i.e. CS programs producing students who know loads and loads of theory and can't write a damn line of actual code.
That's because CS programs are misnamed. Most coding should be done by engineers, not scientists. A Master in Physics doesn't necessarily qualify you to build bridges either.
Finally! A year of moderation! Ready for 2019?
I think they should teach low level first, teach students assembly first and work up from their. They don't need to create anything fancy in assembly just make sure that they understand how a computer works and does things rather then the abstracted model that higher level languages give you.
I may agree with what you say, but I will defend to the death your right to face the consequences of saying it.
The glaring hole in Dijkstra's argument is that most software is built to automate what used to be manual processes, and they therefor have to mimic a human-centric process... which is inherently illogical, inefficient and rife with nonsense.
In the world outside the ivory tower, programmers do not have the freedom to create completely logical, functionally complete programs that can be reduced to a mathematical proof.
Next time your boss comes to you with an project to write an application, show him this paper and explain that what he's asking for is "medieval thinking" and see if you can then explain to him why you should keep your job if you don't want to do it.
Insisting on "correct" English is like saying that there is only one, definitive recipe for chili.
Well, sure. Students should be able to write a bit of code, but why should software engineering be different from any other engineering?
When you get out of school with a freshly minted degree, you ought to have some knowledge of how bridges are built. Bridges are the civil engineers fetish objects, after all. But nobody trusts you to design one. About the only thing they'll trust you to do is to calculate how much paint will be needed to paint the lines on the roadway. If you don't screw that up, maybe they'll let you calculate how much paint goes on the bridge itself. Succeed there and they'll let you check somebody else's calculations.
This is not to say students shouldn't learn programming. They should, but we should be mindful of diminishing returns and the uniqueness of this opportunity in their careers. If you are programming for your career, you are constantly getting better at the craft, but when will you become better at the theory? You are bounded by the things you have done and thoughts you have had, and perhaps you can push those boundaries back, but not as much as the whole scope of human thought on the subject.
Post may contain irony: discontinue use if experiencing mood swings, nausea or elevated blood pressure.
based on Electrical Science, or Mechanical Science, are there?
So, why, then, are we forcing kids to take Computer Science, when what most of them really want is Software Engineering?
The only answer that I can come up with is that the people who come up with curricula are failed software engineers, and are trying to bring everyone else down with them. I interview kids with degrees that can't tell me what a heap is, or why I'd want to use a hashtable rather than a binary search tree, or vice-versa. Now, I know they had to learn that stuff, first year, but they haven't had to use any of it, since.
The ones who retained their first-year stuff often don't have the other engineering basics down, patterns like IOC, class factories, singletons, etc., are just vague ideas to them. Ask them to explain why you would use a class factory, instead of just calling new, sometime. That will bring an entertaining answer, 90% of the time.
Computer science doesn't concentrate on engineering skills, or it didn't when I was in school (UTexas in the 90's). I had to learn how to optimize various languages on my own. I had to learn various languages on my own. I have no need of calculus.
Now, I suppose there are jobs I could get, if I'd finished my degree, that require a lot of calculus. Physics engine designer, etc. There are plenty that don't, and don't require me to be able to design an operating system, either. Those things are niche specialties. What I know for sure is that 90% of the valuable information in my head was learned on my own time, or on the job, and that when I went to school, no classes covered much of this information.
Kids with degrees are notoriously goofy with multithreading (from our experience interviewing them), no longer a niche discipline, with multiple core machines commonplace today.
Ultimately, I find that a degree in CS is little to no positive indication of aptitude in Software Engineering. That's truly sad, and just plain dumb, besides. We're in trillions of dollars of debt. It's affecting our bottom line!
All I have to do is read one paper like this to be reminded why I stayed out of academia. Ah the smugness, the hypocrisy, the great irony. A "radical novelty" this essay is not.
There are plenty of truths out there yet to be discovered. Unfortunately most academics lack the self-confidence to go looking for them and instead find clever new ways to twist ideas around.
He's right, though. Writing the code is secondary. What matters is algorithms, data structures, proper analysis. Anyone with a computer and an internet connection can learn how to write a line of code. Heck, a modern integrated development environment almost writes the code for you. However, knowing what to write is a lot more important than knowing how to write it. One can write iterative code for traversing a linked list, or one could write recursive code. Knowing which is best can be what separates the hacker from the script kiddie.
When our name is on the back of your car, we're behind you all the way!
Dijkstra's comments were right on the mark, and fairly obvious to people outside of CS. They were only contentious within the field, for some odd reason.
The thing is, Computing Science should be approached in the same manner as most other science fields: A BSc in computing should be about theory, research, and pushing the state of the art. A modicum of programming is probably necessary to accomplish that, but programming should understood in the abstract--without the emphasis on 'this command, this language.' Learning to be a programmer (a) should be a division of computer engineering, or (b) probably not a degree at all. More like a one or two year college certificate.
Chemistry, Physics, Biology, Math, and so forth, are all degrees aimed at research and study, not commercial production. Why not computing?
"People who do stupid things with hazardous materials often die." -- Jim Davidson on alt.folklore.urban
The thing that confuses me the most about this paper is his hatred for using anthropomorphic metaphors to describe the functioning of a program. It confuses me partly because his examples of why it's bad don't seem to actually address his complaint, or anything like it. But also, because the more I think about it, they seem to fit very well.
Program components may not be living things, but they do run autonomously. They perform actions, frequently without any input from me. They seem to do things and interact with other components on their own - why not describe it as such? There's also the fact that he doesn't give any alternate way of describing what's going on inside a program.
There are some good quotes atributed to him, but one particular one that goes to show how very wrong even experts can be:
It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.
In my experience this is utter arrogant rubbish. Not being able to teach good programming to people who know Basic only stems from the inability of people like Dijkstra to teach. One of the reasons I usually stear clear of all to academic IT enviroments and programming languages. Like Ruby or Java.
We suffer more in our imagination than in reality. - Seneca
cat > hello.pl
printf("hello world\n");
^D
perl hello.pl
hello world
I don't think I really understand what Dijkstra is getting at here. Can someone explain it to me with a car analogy?
I've taken CS classes at a few different Universities and Tech Colleges.
At the Unis I learned theoretical stuff that as a business application developer I will never use. I will never bill my employer/consult to build a new compiler from scratch. Knowing the intricacies of how compilers work has never contributed significantly to my ability to debug a code problem. That said, they did a fair job of what they were trying to do: spit out scientists who could further the field of computer science.
At the Tech schools I saw a ton of technologies. SQL, SQLServer, C++, C#/VB.Net, Java, HTML, CSS, Javascript, Access, etc... tons of hands on lab time. And walking out of a tech school program I felt they did a great job doing exactly what they were trying to do: spit out working class programmers who could hit the ground running on day 1 in a wide variety of entry level contractor jobs.
Neither option is perfect. Going to a University you'll miss out on the actual practical coding, so while you might be able to pointer math in your head, you'll be way behind the curve in application development. Going to a tech college, you'll have a great framework to start from, but you'll have none of the in-depth or more advanced technical knowledge that someone with a university degree will have.
In both cases I found the knowledge transfer on application design to be completely lacking. Limited exposure to design patterns. No coverage of data abstraction or n-tier designs. Course work on customer interactions, requirements gathering, documentation, and project management were completely lacking (although the tech colleges did a fair bit of PM and Business focus in their Bachelor's program).
When I'm looking at college grad resumes, from a programmer's perspective I want to know that they can:
1) Code in 2 languages (preferably with different fundamentals)
2) Understand some amount of design theory
3) Manage their time
4) Interact well with users and coworkers
And for the love of all things binary, if they try to answer the "Swap the values of A and B" with out creating a 3rd variable on the screening test, they get round filed. I don't care if an instructor showed them a neat trick with pointers, answer the question the right way and save the flaunting for personal projects.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
you serious?
to me, system.out.println looks way more reasonable than this "cout << endl" thing.
factor 966971: 966971
I am very glad I never had him as a professor.
By the way, I am a physicist, and IMHO all of the best physicists develop a physical intuition about their physics, and that is certainly true with those who deal with quantum mechanics. Listen to the recorded lectures of Richard Feynman, for example.
However, I can't get behind the man's call to teach without compiling and running programs. Well, to be fair, I'd have no problems teaching a freshman college course that way, but I'm teaching teenagers. I want the students to be able to unleash what they have wrought (or at least see that they've created a program that works). That's the bait that hooks them deeper into the coolness that is computer science or software engineering or programming or pattern engineering or thinkyness or whatever you care to call it.
I strongly disagree. I see this attitude everywhere and while people who are already really motivated, you will kill off even the least interest in a student who could later find it all fascinating.
You have to engage students. They aren't automatons who will simply take in any information at the same rate. I understand that you're talking about undergraduate college, and that the system is probably different depending on which country you live in, but you have to start at a level where it is easily possible for a student to _do_ things, and that's how you pique someone's interest and sustain it.
I've been through two computer science courses (one introductory, one advanced) in college as part of my Math degree, and through a year in school of being taught C, and while to me it was interesting (I had a computer much earlier than any of my classmates - back when I was just out of primary - so I had an advantage), quite a few of my classmates were obviously struggling with the "This seems so useless, just learning a bunch of stuff for no reason." idea.
I know, they're in a Math course, and stuff like that, but there are a lot of people who will probably be capable of first-rate programming, but they will likely be scared away by having to write a 10 line cryptic bunch of codes just for Hello World.
Besides, Computer Science is about Computer Science anyway, not just the instruction set of one particular processor.
As I read through his writings it brought me back to my time at Moravian College circa 1979. I just started taking CS classes and in that same year Dr Brown, Head of the CS Department pulled out all the IBM mainframe systems and installed a PDP 11/45. Gone were the COBOL courses replaced by c, RATFOR, PASCAL, Fortran et al. I loved it and hated it at the same time.
Like the presentation, Dr Brown taught us programming before we really saw the computer. His focus was not on Language, but on concept. As he so well put to us, once done with our intro class we could work anywhere in any language. I believed it then and found it to be a true statement. At the end of that intro class he took the last three weeks and taught sort algorithms. The catch was each sort was analyzed in a different language. I chuckle when I read posts of youngsters that say "I learned Java, or C++ in college". I learned Programming in college then went on to figure out what language suited my economic and intellectual needs.
Cruelty in Computer Science? I am grateful for that kind of cruelty to this day. Since college I have had to adjust my knowledge as times and needs change. I have had the pleasure of working with RPG, COBOL, Java, FORTRAN, and even the bastard child Visual Basic. Unlike some, I do not look down at any language for each has its benefits for the task. What I do dislike is working on code written by persons who thought that "Learn to Code Java in three Weeks" made them a programmer; that language X is the best and only language out there.
Dr. Dijkstra says "Universities should not be afraid to teach radical novelties". What things could be discovered if that concept was embraced again.
Life is a great ride, the vehicle doesn't matter
That is spot on. It is the difference between an electrical engineer and an electrician. They don't do the same things and getting an EE to wire your house is as stupid as getting an electrician to design a CPU. Or you don't go to the engineer at GM who designed the engine of the car to change your oil (although given the state of Detroit that might change).
There is a difference between a CS degree and an IT or Software Engineering some other more hands-on degree. Yes, a CS or Comp Eng degree should have coding, that is a must because you need to implement a stack or queue or linked list to really understand it. Ditto for LISP or Prolog in AI or knowing a bit of C if you are into OS design (e.g. for Unix/Linux, so you can understand it). But the focus is on theory so that you can code efficiently (or tell the IT people, look, your coding is good, but the design is O(n^2) and you could code it so that it is O(n) or whatever). Or to tell them P NP or whatever.
I was just starting grad school at UCSD in CS when he wrote that paper and there are two separate fields here just like a builder vs an architect or plenty of other examples. One is not better than the other, just different with a different focus and just depends on what the person is interested in and wants to be skilled at. It is not widely understood though. When people find out I was a CS person, I get, "Oh, can you fix Windows for me?"
As Dijkstra put it, "...because persons exist and act in time..." And his claim was that using 'operational reasoning' was a 'waste of mental effort', and he used his domino problem to illustrate a problem where 'operational reasoning' is particularly ill-suited.
However, not all problems are like that, and humans have - in essence - hardware-accelerated modules for performing time-and-agent-based operational reasoning. Dijkstra was half-right: "refusal to exploit this power of down-to-earth mathematics amounts to intellectual and technological suicide", but also half-wrong - not all problems succumb so directly and easily to "down-to-earth mathematics", and not using the human talent for 'operational reasoning' is also "intellectual and technological suicide".
PHEM - party like it's 1997-2003!
Most people should be so lucky as to have your "problem". Programming is easy to learn. People who learn to program and learn no theory should not be computer scientists and should not get a degree in computer science. People who learn the theory should be able to easily pick up an arbitrary programming language and produce sound code in it.
The real problem with theory-free code monkeys is that they rarely actually understand what they're doing, and they rarely know a solid approach to a given problem. They can churn out lines of code that perform simple, straightforward tasks. Not very useful.
You are exactly wrong (IMO, of course).
In C++ (for example), the output just comes out on the screen. That's 'magic'. In Java, it is explicit that there is somewhere for the output to go that is not necessarily a terminal/command prompt/bash shell. The fact that learner Java programmers are told that it will be explained later is better than the average C++ class where it is not clear that there is something to explain at all.
Justin.
You're only jealous cos the little penguins are talking to me.
I think they should teach low level first, teach students assembly first and work up from their. They don't need to create anything fancy in assembly just make sure that they understand how a computer works and does things rather then the abstracted model that higher level languages give you.
Totally agree. I spent my childhood typing assembly games out of the back of Compute! and POKEing memory registers in my programs, and it really gives you a grasp of how what you're doing connects to the real world, even if you hardly ever use it professionally.
-1 Uncomfortable Truth
System.out.println("output");
System is a namespace
out is a print stream object
println is a function the outputs a line to the console
"output" is a parameter
done.
cout "output" endl;
cout is a predefined ostream that outputs to the console
if the write operator
"output" is a value
endl is a keyword the represents and end of line character
done.
Now, this is just personal tastes, but "out.PrintLn()" makes a whole lot more sense than "cout " which requires you to accept the 'magic' of the operator.
The memory side of things you have a point. But how many people are writing code that they have to manage their own memory? Almost everything at this point is either managed code with garbage collection built in, or there are toolsets you can use to manage memory for you. Are you ever going to send a consultant out and let them bill a customer for the time it takes to write memory management code when they could just use and off the shelf option? (**with very few exceptions)
If you are going to a university aiming for a computer Science degree, then yeah, starting off with lower level languages is a must. If you are going to a tech school for a Computer science degree, then starting off with lower level languages is a waste.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
And you give an example of how students should program, in C++? That's is the exact sort of language a student should not be learning first -- an overly-complicated, inconsistent hybrid language with a terrible object system. Say what you will about Java, but it's fairly consistent, portable, and closer to a pure OO language.
But personally, I'd rather see introductory programming courses taught in Python or Scheme. Those languages are small enough that students can focus on program design without being encumbered by syntax and semantics.
Systemd: the PulseAudio of init systems
Dijkstra mocks concerns about the lack of "programming tools". I think he is wrong on this one. Refactoring can be thought of as a programming tool, and it is a very useful one.
\u262D = \u5350
I think both approaches (top-down and bottom-up) make sense. You learn C very fast if you can think of it as a high-level assembler. And learning assembler teaches you a lot about what computers are all about and what they can and cannot do.
But learning algoriths on C or other low-level, manage-your-own-memory languages is unnecessarily painful and error-prone. The algorithm exists independently of a specific language incarnation. Learn the algorithms in a language that makes it easy to concentrate on the problem and not get lost in a thousand small implementation details.
You reach enlightenment when you can bridge the gap from very low level to the highest levels. But it is folly to try to do everything at once.
Can someone tell me on which page he stops the senseless rambling and gets to the point? I can't imagine having this guy as a professor. He loves to hear himself talk too much.
cout doesn't have any meaning if you don't scope-qualify it any more than 'out' does. So you have 14 vs 13 non-output characters. Not exactly game-changing.
Erm...
Where do I start?
First off, what is wrong with, "System is the system library, Out is a function in that library, and it prints to the console."??
Secondly, even in a garbage collected language, you can't just go around doing whatever you want, if you want to have an application that performs well. Algorithms are still quite important, and remain the primary form of optimization.
I know I will catch some flak for saying this, but non-garbage collected languages will soon be relegated to a COBOL-like existence. The fact is that languages like Java and the .Net languages are becoming "fast enough," now. Try out XNA sometime, if you don't believe me. So you're trying to convince me that I should like taking the garbage to the dump myself every day. What I want to do is work out a reasonable relationship with the garbage man.
"
As a result, it tends to get waved away as "magic" or "this will be explained later" but there's so much waved away that the students get disconnected. For instance, to simply output a line to a command line in Java you're looking at
System.out.println("output");
whereas with c++ (for instance) you have
cout "output" endl;
As someone who's teaching this stuff, the second is easier to explain in detail and doesn't rely on saying "don't worry what System.out is".
"
I think both have an equal amount of hand-waving.
System is a class that contains many useful run-time features your program can use. The out property is a way to write to the console. The println method of the System.out reference is a way to write text or other objects to the standard out, with an appended new line. If it gets passed an object, it calls the object's toString method first, giving each object control over how to display itself
The is an operator that is overloaded by many classes. The cout overloads the operator to print to standard out. The cout itself requires a bit of hand waving. Also, you need to return an int from the main (Why? Don't worry, just return 0), you need to import a namespace, and you need to explain that endl is a magic (but platform independent) line terminator.
Guess what? There is no good language to teach computer science in. They all require a lot of hand-waving for the intro programmer. The college I go to is shifting very heavily to not using any language in the first semester of the CS program. It's entirely flowcharting and basic UML- design first. 2nd semester is Java, 3rd semester is Data Structures (using JCF). 4th semester is C and Assembler. Junior and Senior years are electives, including Architecture, Distributed, Networking, Graphics, OSes, and Compilers. Also required is an internship.
A great programmer doesn't give a rats ass about what language they're programming in. A great programmer will program into the language, using the language to the best of its ability. A great programmer will, however, choose languages and environments that give them their greatest desire: the ability to be lazy. Good CS programs will teach people how to program, not what to program. Good professors must find a way to present all aspects of CS in an appropriate fashion, and that does mean design first.
It may surprise you to discover that the first actual computers were built by people who were trained in neither practical nor theoretical computer science. (They were, for the most part, physicists and electrical engineers.)
In fact, practical computer science ("programming") is almost useless if you want to build an actual computer. It's also useless if you want to deal with a theoretical computer.
So no, I'd say that if all we taught in CS was theory, we'd still have actual computers.
I had an instructor in college who was a brilliant algorithmist. Could come up with a working, efficient algorithm for anything, and he'd do it quickly. If we implemented the algorithm, the code would always work great.
His Win98 box on his desk was the most virus-infested machine I have ever seen.
I still consider him a great computer scientist... just not a great operator. But going for the requisite car analogy, I'll bet most race car drivers don't know all the physics and metallurgy needed to build a car, even if they might be able to put the parts of an engine in the right place. That doesn't mean that the engineer is a useless reference, it just means you shouldn't go to him for racing tips.
My blog. Good stuff (when I remember to update it). Read it.
I find it ironic that, to establish your argument that Java hides implementation details, you used a C++ example employing operator overloading such that the mere existence of functions is utterly concealed.
For instance, to simply output a line to a command line in Java you're looking at
System.out.println("output");
whereas with c++ (for instance) you have
cout << "output" << endl;
As someone who's teaching this stuff, the second is easier to explain in detail and doesn't rely on saying "don't worry what System.out is".
You're trading Java's (OO + packages) for C++'s (OO + operator overloading + namespaces). I don't see how that is any simpler.
I'm afraid I'll have to differ.
There is nothing more fascinating than learning how computers really work. And this background is essential when designing algorithms and memory structures that must be efficient. It is merely a question of teaching this in an interesting way, and of relating it to real-world problems, such as "why is this pretty reasonable-looking high level language code so fucking slow?"
So explaining operator overloading is much simpler than explaining the System class and its static members? Changing the meaning of the traditional bitshift operator to mean something completely different is a very bad and confusing idea IMO.
I'm trying to improve my English. Please correct me on any spelling/grammar errors in this post.
Not as sadistically cruel as my experience in college. Six, yes 6, semesters of COBOL/JCL/Mainframe... in a 9 semester Computer Information Systems Degree (which I dropped like a lead weight) I later found out from a friend that they tried to cram C programming in the last semester to cover some requirement.
I keep telling myself that I left because the English literature teacher treated us like kindergartners by turning off the lights when she walked into the room and waited for everyone to be quiet or the Japanese Management class that everyone failed (yet somehow nobody actually did after the grades where published)... but I think It was really the COBOL that made the nightmares worse every night.
Every time I start to have faith in humanity, I ruin it by driving to work between 7 and 8 am.
Fantastic article. I especially like this part:
(1) The business community, having been sold to the idea that computers would make their lives easier, is mentally unprepared to accept that they only solve the easier problems at the price of creating much harder ones.
So true. I deal with this every day. Despite the high tech wizardry around us, business still runs pretty much the same. Just, the management is all too happy to throw its problems at someone else. I can't remember how many times in the past that I've had a client, boss, or manager ask me something that is impossible and tell me "fix it" or "make it work".
University is supposed to make you a scientist. If the focus were on gaining practical, hand-on experience, your education would be outdated in just a few years, when the next best thing appeared. Not having the theoretical background, you would either become obsolete or forced to learn a new approach right from the start. After all, the best way to learn to code, is to code yourself. If you have the theoretical understanding, which progresses at a much slower pace than practice, it's much easier to adapt to a newer approach. That doesn't make it easy for the students, but, just as in mathematics, there is no royal path to knowledge.
In summary, it's better to "learn how to learn" than to focus on one thing and become useless when this thing is replaced
This "magic" is necessary no matter how you teach programming. Even if you teach assembly, there is still some amount of magic in how it is translated into machine language. If you teach machine language, then the way the computer interprets it will be magic. Hell, even if you build a computer out of relays (not recommended for "intro to programming" class), you still have to explain away the "magic" of magnetism.
So you can't do away with magic, so I recommend you choose a suitable level of abstraction and start there. Remember, most programmers will be working on large applications, not low-level systems stuff. So the level of abstraction presented by Java is a great starting point. The students who are talented will then be able to expand the scope of their knowledge in any direction, as necessary.
...have most schools corrected course and are now being necessarily cruel to their Computer Science students?
Buddy, we have 6 assignments, 2 quizes and an industry project presentation this due week.
You tell me!
Boy do you need to go back to school. Edsger wrote more and better stuff in his lifetime than anyone here on Slashdot. Did you ever get directions from Google Maps or Mapquest? Thank Edsger -- his shortest path algorithm is what they all use, and by the way, he wrote that before you were born, most of you. You know the semaphores used in the multi-cpu Linux kernels? Yep, you owe Edsger for them, too. And programming languages like C, Pascal, etc.? He helped write the first Alogol compiler, the great-grand-daddy of them all, once again before most of you were born.
Just because he eschewed the run-break-fix approach so beloved of the folks who are spewing billions of lines of error-laden code into the world today, doesn't mean he hadn't forgotten more about writing code than most folks here have ever learned. And yes, he advocated developing code formally, and he liked to do it with pen and paper.
So learn about who you're making snide comments about, and show some respect. When people are still using any algorithm you came up with 30 years from now, you will have the right to say something about Edsger Dijkstra.
- "History shows again and again how nature points out the folly of men" -- Blue Oyster Cult, 'Godzilla'
Meh. Write-only Perl line noise.
How can that be a real program without about 10 lines of module and class declarations around it?
thegodmovie.com - watch it
Babbage's Difference Engine was a calculator, not a computer. However, I do take slight issue. Anyone who has read about what Turing made the Manchester Mark 1 actually DO, apart from being suitably awed, would have to admit that while notionally it belonged to Manchester U, Turing definitely pwned it.
From scarped cliff or quarried stone she cries "A thousand types are gone, I care for nothing, no not one."
Now, this is just personal tastes, but "out.PrintLn()" makes a whole lot more sense than "cout " which requires you to accept the 'magic' of the operator.
What "magic" are you referring to? cout is a special instance of the ostream object type. And a "stream" is relatively easy to understand, as it's an object that can take input and produces output using stream operators. In this case, cout is a special object with its output side hooked to the console. If you want to explain the console itself, then yes, you have to go lower level into memory addresses and such, but it is understandable by going lower into the system.
The System.out.println is much more magical, as there is absolutely no explanation for how the println prints to the console. The "out" object is essentially undefined, and you have some magic happening in the java virtual machine that connects it to whatever the 'console' happens to be. But that "console" doesn't map to anything real. You can't go any lower level in the machine itself, because your code is not really running on that machine... Essentially, Java is far more magic than C++ because you have this black box called a "JVM" which is unexplained in its entirety.
Of course, this depends on what you consider to be "magic".
The memory side of things you have a point. But how many people are writing code that they have to manage their own memory? Almost everything at this point is either managed code with garbage collection built in, or there are toolsets you can use to manage memory for you.
This depends on your target audience. Are you teaching basic business level programmers who will write high level code and websites? Or engineers who will write embedded code for lower level devices?
Or, are you teaching "Computer Science", which is not fundamentally about programming at all, but is about ideas and concepts that back up computing? Because here is where you teach about how things like Memory Management and Garbage Collection actually work, and so yes, they do need to understand pointers, and how objects are created and destroyed and so forth.
If you are going to a tech school for a Computer science degree, then starting off with lower level languages is a waste.
What is a waste is calling anything taught at a tech school "Computer Science". Most of them call it something else, like "Programming" or "Computer Engineering" or even "Software Engineering". Not many call it CS any more.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
"I mean, if 10 years from now, when you are doing something quick and dirty, you suddenly visualize that I am looking over your shoulders and say to yourself 'Dijkstra would not have liked this', well, that would be enough immortality for me." - Edsger Wybe Dijkstra
A lot of software engineers like to work with new technologies, new paradigms, new code design patterns, new software development technologies and other forms of complexity. Quality Assurance rules by checklists and testing, only fixing symptoms. Every coder has it's own ideology what is correct code or the correct way to do it. Correctness proven by superficial subjective quality standards, beautiful crafted hacks included.
Edsger found ways to mathematically prove programs to be correct, requiring a very high level of math skills (the same level which is needed to prove the correctless a mathematical theory). This utopistic objective quality standard. Stuff for the real hard core developers who have plenty of time.
But most haven't the time. In the end time-to-market is key. Swift hackers remain the heroes of business who craft applications which get used in the real world.
However some pragmatical things I thank Edsger Wybe Dykstra for: invention of the stack, his low opinion about the GOTO statement; shortest path-algorithm, also known as Dijkstra's algorithm; Reverse Polish Notation and related Shunting yard algorithm; Banker's algorithm; the concept of operating system rings; and the semaphore construct for coordinating multiple processors and programs. His charismatic remarks about what we would typically consider software engineering are entertaining and humbling, examples:
And the above comment of "Line of code != Compilable program" stands.
perl is interpreted, not compiled.
Most of y'all are presenting a false dichotomy. It's not "Either learn abstract formalism OR learn practical languages." You can do both, you know.
I have met too many people who think that, because they can write some tangled, fucked-up C++, they are software engineers. Never mind the fact that they couldn't learn LISP, Objective-C, Java, or any number of other useful languages, as they don't know the first thing about actual computing.
Teaching Java or C++ doesn't matter. Sure, you need classes on practical application of your knowledge. But if you ignore what Dijkstra says here, you're going to end up with a bunch of code monkeys who have to test every element of the set, rather than test the rules of the set.
In my experience, those who started off learning theory, then learned how to apply that theory in practical situations, are far better programmers than those who are taught "practical" languages.
There's some very good advice in that paper. Calling him "out of touch" is a bit shortsighted.
Microsoft is to software what Budweiser is to beer.
echo "hello world"
- Michael T. Babcock (Yes, I blog)
If I had to hazard a guess, I would say that a computer science undergraduate degree attempts to prepare you for graduate study AND a career in industry immediately after graduation. An undergraduate degree in math or hard science typically prepares you for graduate-level study only. This distinction is a necessary result of the large demand for programmers in industry -- schools needed to adjust to the expectations of students and the industry. Some programs will separate out these pursuits into different majors (e.g. software engineering vs computer science), but that doesn't change the fact that companies expect a person with a bachelor's degree in computer science to be able to write quality software.
Weirdo.
Seriously though, the way my mind works is fairly analytical (so I hear). I more easily compartmentalize and break things down. So looking at the C version its a lot easier to see what each segment is doing after only a brief explanation, or even less. For example "cout" makes sense because the language is C and its the OUTput.
But to each their own.
Second semester freshman course is mostly about constructing machine-checkable proofs about programs. http://www.ccs.neu.edu/course/csu290/syllabus.html
My university actually teaches with a wide variety of programming languages. The beginning classes are in Java, but there are a required courses that use C, C++, Python, C#, Scheme, and a smattering of classes where they don't specify the language to use. And interestingly enough, for everything except Java, Scheme, and the memory management portion of C++, they expect the students to *gasp* learn most these languages almost completely on their own.
I don't mind removing pointers from the introductory classes--they are hard for a beginning programmer with little experience to grasp, I'd say--, but removing them from the curriculum altogether seems like a really bad idea to me.
FWIW, I'm an astronomer who spends most of his days writing code to analyze data taken by large complicated telescopes whose operation I understand but which I should never be asked to fix.
You are up for the Useless Use of Cat Award this week...
$ gcc -x c - <<EOF
> printf("hello world");
> EOF
<stdin>:1: error: expected declaration specifiers or '...' before string constant
<stdin>:1: warning: data definition has no type or storage class
<stdin>:1: warning: conflicting types for built-in function 'printf'
I'm curious where you are finding these students. In my experience, it is much more common to find people who think they know loads of theory, but can't write a line of code. In reality, these people usually can't write a line of proof either.
The best theoreticians aren't always the best coders, but they're usually able to code pretty well when they want to. I've much more frequently seen people who were great coders but couldn't handle more abstract algorithmic questions than vice versa. And I certainly think it's hard to say that great CS theorists who can't code is "the problem" in CS education right now...
I am the man with no sig!
Your whole comment is supported on the confusion of computer science and software engineering.
He's saying that computers represent combustion driven vehicles, as compared to sweat and bones driven vehicles, and that even though the wheels and the body may look similar, the purpose the same, we cannot faithfully still call a car a carriage.
This was a great way to start my day. So seldom do I thank you, slashdot...
That's because it's computer science and not engineering. The problem is that people conflate the two. If you want a coder, hire a coder not a scientist.
Give me Classic Slashdot or give me death!
You can't go any lower level in the machine itself, because your code is not really running on that machine... Essentially, Java is far more magic than C++ because you have this black box called a "JVM" which is unexplained in its entirety.
You have been blinded by marketing. The reason that it is called "Virtual Machine" is because that is exactly what it is. Java is an emulator. It's just that Sun thought "Virtual Machine" sounded more enterprisee. Saying that Java is magic because you can't go lower than the virtual machine is the same as saying that C++ is magic if you run it on VMWare.
edit hello.bat echo "Hello World" Alt+F X Y hello hello world
Mostly the shortest path is the best solution! ;)
I'm quite sure you meant: std::cout << "output" << endl;
You seriously think that's easier to explain than System.out.println("output"); ? The C++ version is concealing even more hairy details than the Java version, while using even more symbols that can't be fully explained until later!
If you think Java shouldn't be the intro language, that's fine (I think there's a case to be made for it, but I have mixed feelings). But C++ is definitely worse.
I am the man with no sig!
Ok, I get that Dijkstra was a profound mathematician type. But honestly, with regard to computer science, he just comes off as a fuddy-duddy luddite. I know a few scholars who refuse to use word processing applications to write their papers (one tenured researcher at my work, a phd mathematician well past his prime will only use his old IBM Selectric), regardless of how well they know their productivity could be increased. And I don't want to hear any aesthetic arguments. If I were an employer today I might find such behavior 'quaint', but of no use on my payroll. None. In my opinion he just comes off as an intelligent quack.
Python: 'And then suddenly you have a language which says "we're all stuck with whatever the whiniest coder wants".'
But personally, I'd rather see introductory programming courses taught in Python or Scheme. Those languages are small enough that students can focus on program design without being encumbered by syntax and semantics.
Isn't that like teaching kids to read for meaning in works like Catcher in the Rye, Moby Dick, ... before teaching them the simple grammer of first grade english class?
I must say that I agree very much with many of the points he's made in this paper. Anthropomorphizing concepts and excessive use of analogy is bad for teaching programming and it's bad for teaching many other concepts.
In terms of programming, one thing I absolutely hate are "real life analogies." Take the "Head First" series of books. On one hand they're very good at diving into subjects and explaining the concepts in several different ways. On the other hand, all of their examples are so far removed from reality that they're meaningless outside of the context of high level discussion. "Bill and Ted want to order a pizza, but Bill wants a Chicago style pizza and Ted wants a New York style pizza. What they need is a Pizza Factory!" Huh? I mean, I get it, but completely outrageous analogies don't really help when you get into the process of actually writing code. If outrageous analogies did work, then naming would be a breeze....writing comments would be fun!
Another example of poor example is the familiar "let me teach you about Object Oriented Programming by considering a circle, a rectangle, and a square." Of course these three things are all "shapes", and invariably they all "draw()" themselves. You can replace this example with the tried and untrue animal (or dinosaur) example in which an array of animals or dinosaurs are all related and differentiated and all, of course, "bite()" or "move()". These examples are horrible because they ask more questions than they answer. That is, the concepts behind OOP are not so complex that they require high level analogy to explain -- as if the people who will be writing OOP programs are non-programmers. And when the brain starts to consider how these analogies apply to real-life situations, it wonders things like, "wait a minute, why would a circle draw itself? What does that even mean? On my screen? In a window? On some paper in my printer? Or does it just return some data structure containing points? What is the value of that?" and "ok, my dinosaur just "bit()", but what did it bite on? How can my cheetah "move()" without knowing about its environment?"
In the end, the concept is understood but the actual implementation -- how these concepts can actually help us in the completely abstract unreality of a computer program -- is missing. What's most disturbing is when a text book will start with one of these corny high-level examples and then actually IMPLEMENT the example verbatim. That is, they'll have crazy polymorphic tyranosauruses and cheetahs and ducks all biting on shit in a completely meaningless exercise that wouldn't even apply to video game design.
In the non-computing world, poor use of analogy and anthropomorphizing concepts has an even greater impact on our reality. Consider the following statements: "buffalo travel in herds because there is safety in numbers." "Lions have eyes in the front of their heads to focus on their prey, and zebras have eyes on the sides of their heads so that they can watch out for lions."
Both of these statements would be considered basically true, however they are completely false. Buffalo travel in herds because that's what they do. Lions and zebras have eyes where they have eyes because that's where their eyes are. They had no choice in the matter. Their evolution was not one of decision making, but of beneficial mutations and lots and lots of death over thousands of generations. Explaining this as though some sort of strategy were involved only complicates matters and makes it more difficult to grasp the scope of time required or appreciate the concept of genetic mutation as something that has nothing to do with the Incredible Hulk.
I don't think I have to explain why injecting decision making into evolution is a dumb and dangerous thing to do, and does not help to further our knowledge of the subject but in fact just the opposite. Ok, I will explain it: intelligent design.
Actually, System.out.println() and cout are about equally cryptic, particularly because cout relies on templates and operator overloading just to work.
You want a simple way to output "Hello World"? Let's try an old teaching language, Pascal:
writeln('Hello, world!');
And now the newest teaching language, Python.
print "Hello, world!"
Much, much simpler.
I know I will catch some flak for saying this, but non-garbage collected languages will soon be relegated to a COBOL-like existence.
I pray you are right. The only thing keeping me from learning COBOL and getting a lucrative job working on the large codebase still out there is the hideousness of the environment. I could definitely stand a high paying niche job working on today's non-GC languages.
Towards the end of the essay, an introductory course is described where the student, as programmer, is required to build a formal mathematical definition of his program and prove that his program conforms to the definition.
At The Ohio State University, we teach precisely this in the form of the "Resolve" programming language. For every function and every block of code, one must provide both the procedural code and a set of logical constraints that describe the effects of the process. For instance, if a function's job is to reverse the order of items in a list, then the internals of the function are accompanied by a logical constraint that tracks the movement of items from one list to another and ensures that the operation is totally consistent at every step, in terms, for instance, that the two lists sum to a constant size that is the same size as the input, and that the concatenation of the lists in a particular way yields the original list. (I'm summarizing.)
An active area of research here is on automatic provers that take your code and your logical definitions and actually prove whether your code and defintions match or not.
I haven't read this essay before, and have only had time to skim part of it now, but Dijkstra's criticism of mathematicians has merit, IMHO. [I have an MS in Math, so I don't claim to be an expert.] It's been over 40 years since the introduction of nonstandard analysis (including hyperreals and later surreal numbers), but it's still not a mainstream topic. In fact, it boggles my mind why a professor or department would choose to teach their students "hard" analysis (Bartle or Royden) instead of "soft" analysis (Rudin) -- "soft" analysis uses topological results to arrive at key theorems faster, while "hard" uses Real Analysis as if it were the only option on the market. Not that there's anything wrong with using Rudin and Royden in tandem, but to ignore topological results altogether smacks of willful ignorance. To paraphrase Stephen King: do you expect brownie points for being ignorant of your own discipline?
The light on the horizon is the development of proof via programming, as covered by /. I'm sure there will be 50+ years of mathematicians screaming and kicking to avoid its introduction into the mainstream, but that will change the first time a computed proof that could not have been developed in one lifetime via the usual methods earns someone an Abel Prize. Until then, I suspect Dijkstra's point will still stand.
What "magic" are you referring to?
Sorry, slashdot ate my <<.
In this case, cout is a special object with its output side hooked to the console.
Magic. How is it attached? What type of model does it use to interact? And most importantly, who cares?
The System.out.println is much more magical, as there is absolutely no explanation for how the println prints to the console.
Again, magic. System.out is a stream object that by default prints to the console.
In either case the cout function and the System.out namespace are functionally identical for our intended use at this point.
And a "stream" is relatively easy to understand, as it's an object that can take input and produces output using stream operators.
Which requires the explaination of stream opperators, functions, and inputs. .Println requires the explaination of functions and inputs.
IMO it is much easier to explain how System.out.PrintLn works because there is less technicalities exposed. The user needs to understand that there is a stream called out in the System namespace, and that they can use the PrintLn function to output a parameter to that stream. And that by default that stream is directed to the console.
For cout the user needs to understand that there is a very special stream called cout, that they need to use stream operators (that have no english representation) to output to that stream and that they need to know reserved words that can be used to indicate a line end.
As far as ease of explaination goes, the higher level language wins out, pretty much every time. It's a high level language, that's what it is designed to do.
What is a waste is calling anything taught at a tech school "Computer Science". Most of them call it something else, like "Programming" or "Computer Engineering" or even "Software Engineering". Not many call it CS any more.
Ehh, CS might not be the best term for it, but that's what it was called at the Tech schools I checked out and attended. I've seen gems of students come from both Universities and Tech Schools, I'm not about to say either is better than the other. They develope different skill sets for different purposes. That doesn't make University students smarter or Tech students better coders, it just means they are different. And the best thing to do as an individual is to attempt to learn as much as you can from both institutions.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
I find it absolutely amazing how the field of software engineering is filled with countless "code monkeys," and yet, none of those people ever participate here on Slashdot.
:)
This was not meant as a shot at the above poster. Just an observation
Do you (or anyone else) have recommendations for schools that do a good job at teaching software engineering? I work with HS students from time-to-time and it would be nice to have some place to recommend.
I went to a science/engineering school and got a good Computer Science education there. I agree that it would have been nice to have a couple more classes on software architecture, testing and planning, and that some of the CS classes like Automata (which I enjoyed) aren't useful for 99% of the students.
However, the problem I've found is that all the good schools teach computer science and the ones that claim to teach software engineering are usually no better trade schools that crank out people who know a few technologies but none of the principles behind them. I wouldn't give up a rigorous hands-on treatment of Data Structures, Algorithms, and Systems Architecture for the world, so I still end up recommending a good CS program over software engineering, even if it means suffering through a few unnecessary classes.
He could of summed up his paper by yelling Troll, Groupthink, and then Personally I welcome our Automatic Computer overlords.
You can tell he never owned a computer by the way he doesn't think programs need maintenance. He is confusing cause and effect. The environment the program "lives" in changes and "wears" it out therefore it needs maintenance.
"The stupid neither forgive nor forget; the naive forgive and forget; the wise forgive but do not forget." -Thomas Szasz
I've written about this line in detail, but I suspect you are part of the problem in misunderstanding the comment. A good astronomer knows a huge amount about optics and has typically built at least one telescope by polishing and mounting mirrors themselves. I learned far more optics as an amateur astronomer than I did at school. In spite of this, astronomy is not about telescopes, it's about stars - telescopes are just tools.
A good computer scientist is the same. They understand every part of their computer, from transistors and gates, through low-level logic and up to operating systems and compiler. Given enough time, they could design their own computer and given enough resources they could build it. In spite of that, they understand that the subject is about algorithms.
I am TheRaven on Soylent News
It's not perl if its not nearly completely unreadble :D
It is really scary how few people really understood what Dijkstra was saying. My best guess is that because most people learn programming backwards, IMHO, by starting with the languages and then learning higher-level logical constructs, like state machines or even lists or maps, it has permanently skewed their perspective.
My experience, after over 10 years as a system test engineer on software systems, is that poor software really is from a lack of discipline in starting with mathematical constructs before writing the code. I generally worked with very experienced programmers who didn't make a lot of language errors, like improper use of pointers, but were still tripped up by things like when to free allocated memory. The kind of errors that wouldn't occur very often if the discipline of using a mathematical construct like a hierarchical state machine was enforced. For instance, instead of starting with a proven state machine library they would just set flags and create an adhoc state machine that was riddled with problems.
"Meaningless!, Meaningless!" says the Teacher. "Utterly meaningless!"
It is funny to me how many profs talk like this guy wrote.
Today we are going to...
Later we will go over...
It actually makes you think this will be some type of discussion and not a dictation. I would have loved to respond and say
We think you are an idiot.
As for his work? Who really knows. Maybe WE can figure it out someday.
The more I learn about science, the more my faith in God increases.
The fact is that the world needs a hell of a lot of running code in a hurry. Millions of lines of it. We don't have the luxury of treating a realtime airline-pricing-optimization manager as a lovely formal system that we can write out in pencil. We have to get it up and running, then fix bugs and add features as time permits, because of a phenomenon that Dijkstra doesn't take into account: IT'S NEEDED *NOW*.
I also think he's being unfair by suggesting that modern educational institutions are anything like as hidebound as medieval ones. First, medieval universities were not intended for inquiry in the first place; they were intended to prepare young men for the priesthood -- i.e. to teach them doctrine, which was not subject to inquiry. No institution except maybe a seminary is as restrictive as that these days. Second, it doesn't seem to have occurred to him that learning by analogy is how people learn *effectively.* He may decry teaching children about arithmetic by using apples because it's not a formal system, but a five-year-old doesn't have enough knowledge to know what a formal system IS. Starting a five-year-old with Principia Mathematica is just pointless. And your basic coding grunt who wants to build websites doesn't need to be taught JavaScript as a formal system either.
I piss off bigots.
Err, did you see the part where he talks about how bad it is that calculus is taught by giving example problems from people's chosen field so they see how it's relevant? And how this just conceals how drastically new a tool calculus is, and it should be studied by itself in isolation, not as it is applied? I'm pretty sure there are people outside of CS who might disagree with that. I'm a fan of Dijkstra's research, but not so much his teaching philosophy...
I am the man with no sig!
Wow. I'm going to go out on a limb and say you are a member of academia, not industry... While you are proving your code, your competitors will be releasing software and stealing marketshare from you.
A slashdotter who didn't build his own computer is like a Jedi who didn't build his own lightsaber.
Bad teachers gets you
#1. cargo cult programming
#2. people bound to a language instead of logic
#3. not knowing why using an unsigned int in a for loop is faster than a signed
#4. using linked lists when an array would do just fine(CPU prefetch unit can't prefetch well with linked lists)
#5a. Unable to make multithreaded programs that always work(omg! my program works on my single/hyper-threaded cpu..)
#5b. programmers that don't know why hyper-threaded cpus won't truely show all SMP bugs
#6. SQL queries that take 10 minutes instead of 10 miliseconds
It's not just about making something work, but knowing why it worked and what way works best
Dijkstra's Cruelty is the nickname UT cs students gave to the course his wife taught. It was a required course when I was there and it was 2 semesters long. I think it was called "Software Development" but should have been called "Fantasyland Development". Total waste of time and energy. I never saw him on campus, except maybe at graduation.
The best classes were given by people who either were working in the real world or had some experience in the real world and were trying to get their masters or doctorate. The 'professors' going for or having tenure were the worst.
The standard way of teaching basic programming is procedural, then functional, then object orientated then onwards.
Who teaches functional programming languages as a standard part of their curriculum, in particular as a "bridge" between procedural and object-oriented paradigms? I learned some Lisp in an AI class, but that wasn't part of the standard programming sequence which went Assembly-C-C++ (with the C and C++ parts now replaced with Java, sadly).
The enemies of Democracy are
For instance, to simply output a line to a command line in Java you're looking at System.out.println("output"); whereas with c++ (for instance) you have cout << "output" << endl; As someone who's teaching this stuff, the second is easier to explain in detail and doesn't rely on saying "don't worry what System.out is".
This is a troll, right? Calling a method is harder to explain than applying a string literal to an ostream reference and receiving another ostream reference to which a special-purpose construct is then applied merely for its side effect? What color is the sky on your planet?
Ah -- you mean, he was concealing details that will be explained later? Like he was criticizing the Java version for doing?
I wasn't being a smart-ass, I was pointing out a legitimate contradiction in his complaints. The C++ version concealed namespaces, functions, the whole mess of chaining applications via overloaded operators, and for God's sake, references (which are much worse in C++ than in Java). To me, that looks a lot worse than what he's objecting to...
I am the man with no sig!
The part about needing multiple personalities reminded me of doublethink from 1984.
oh, car analogy, maybe he is a genius, or maybe he just likes to blow his own horn.
I only look human.
My mother is a halfling and my dad is an ogre, so that makes me an Ogreling
It may look more reasonable to you (are you a java programmer, by chance?) but the GP's point is right. It is more human readable the same way applescript is more human readable. The 'cout' thing has more symbols, but each one of those symbols is easily explainable. The System.out thing has DOTS in it, which is clear to you, but to someone who doesn't even know how to print something onto the screen, dot notation is going to be a bit complicated (really: I tried teaching someone javascript as a first programming language, and he got the hang of the dots eventually, but it was hairy).
Inevitably ever teacher just teaches 'System.out.println' is what you type when you want to print something. We will explain it all later. Just as the GP said. People can handle weird symbols easily. It's the confusing concepts that really slow them up.
Qxe4
Last I checked, no one had quite figured out how to teach computer science -- your first course in college would serve mainly to flunk those who didn't know, or couldn't learn very quickly on their own, because the course itself certainly isn't going to teach you much.
However, the specific things Djikstra is talking about are not problems.
Consider his insistence that "bugs" should be instead called "errors", because this is less metaphorical and closer to the truth -- placing the blame where it belongs (the programmer), and allowing a lower tolerance -- a program cannot be "mostly correct"; it is either correct (with no errors) or it is incorrect (has errors).
This is to ignore one of the most important things to understand about modern computer science: Culture, or, more importantly, communication.
"Error", even in context in computer science, could mean several things. It could be programmer error, it could be an error in the rest of the software, it could be a hardware error, or an error status returned from any of these, even user error.
"Bug" has a very specfic meaning. When you say you've "squashed a bug", there is very little doubt as to what you mean.
Yes, it was initially attached to a metaphor. But as Djikstra so clearly points out, computer science is a radical novelty -- and such radical novelties tend to borrow words from older vocabulary, from other languages, from fiction, and invent some of their own. They do this not because of intellectual laziness, but because they need a vocabulary of their own -- yes, jargon serves a purpose.
And yet, it is not such a radical novelty that old ideas will have no effect. Certainly, some understanding of mathematics will be beneficial -- and although calculus may not be needed most of the time, the way in which it forces you to think will exercise the same parts of your brain that tough programming will.
I would argue, though, that computer science is not only informed by mathematics. It is also informed by softer sciences -- philosophy, creative writing, and languages.
Certainly, parts of it are very much a hard science -- the best sorting algorithm for a given situation, for instance -- but these are often confined to small, easily replaced cases. After all, it should not be difficult to swap sorting algorithms in most programs.
Other parts are very much a creative work -- an attempt to find the clearest possible way to express an idea, both to the computer, and to the next programmer. It is here that we most often talk about elegance.
Both are necessary -- without the creative structuring of a program, and proper communication of that structure to all involved, we would not be able to swap sorting algorithms at will. Without a clear understanding of how the performance of a program is impacted by various choices, that beautiful, creative code may never run.
And that is why it is so challenging to teach. A good programmer is going to be using both halves of his (or her) brain, if not at the same time, then certainly throughout developing a given program.
And that is also why it's not going to be easy to learn.
If Djikstra were alive, he could learn a thing or two from Why The Lucky Stiff.
Don't thank God, thank a doctor!
$ cat > hello.pl ./hello
printf("hello world\n");
$ perlcc hello.pl -o hello
$
hello world
From what you are writing, you are essentially arguing that the way we teach math in school is wrong.
1+1=2. But you can't really prove that yet. That's VERY difficult to prove
The square root of 4 is +/-2. Easy. But then we tell them that you cannot do the square root of a negative number.
Both of these things hide some of the realities of actual math, because it's easier to handle this way.
And so on and so forth.
Logarithm tells us that 2+2 != 4, but rather 3.99 [ad infinitum] - how's that for a bit of confusion.
You have to start somewhere. Sure, teaching the fundamentals is a good thing, but even in math some fundamentals aren't taught until you get waaaay beyond the intro to math. But just like in math, some times it's really nice to get to know the tools first and the precise knowledge of how it works later. If we had to know exactly how everything works before we started using it, physics would never be taught ...
I agree that teachers disconnected from reality are bad, but the alternative is even worse. Look at what too much bitching got us: they teach JAVA as the primary programming language in universities nowadays! How sadistically cruel is that?
Finally, I can put my university Java courses to good use!
:no they're not :(
output.stream.text.openRebuttalLibrary.strongRebuttals.javaIsABadFirstLanguage.showIcon.frownyFace.inputAudience.slashDot.inputArgument.cruel.ouputEmotion.snarky.noBorder.standardText.displaySettingsOptimal.blackFont.print();
I am the richest astronaut ever to win the superbowl.
You didn't provide proof to back up your examples, so you ask us to accept that explaining
cout << "output" << endl;
is incredibly easier to explain than
System.out.println("output");
In truth, the explanations for both are very similar, with the first you indicate that the << operator puts something into the left hand side which happens to be the output to the screen.
In the Java version you indicate that the System has an output device called out and you ask that out device to print on a line the string "output".
Why the Java version is superior is because in the C++ version you immediately run into a major issue: How does the string get a endl put into it? To explain that you then need to explain that << is an operator which is implemented on the cout device, which then returns another invisible reference to the cout device that will also accept the endl when the << operator is called on that.
Certainly neither is above the ability for an undergraduate to grasp, but saying that the Java version is harder to explain just shows a bias for all things familiar. I too miss the << syntax from C++ when programming in Java, but it's insane to say that the cleaner syntax results in more easily explainable programs.
As far as garbage collection, that's easier to explain in Java too. Since Java implements only one means of garbage collection, its explanation only takes a couple of hours. C++ has two means of objects consuming memory, one that is rigid enough to explain in an hour and another that is a "figure it out for yourself" solution. Best practices must then immediately be taught, which reduces the number of ways malloc / free can be used "safely".
I've see precious few programs which were competitive on the grounds of their improved garbage collection / freeing mechanism alone.
Perhaps you should read that Dykstra paper carefully, as you seem to have fallen into a trap or two he describes. That said, I wholeheartedly agree with you that the current educational process has a lot be desired for Computer Science, but sometimes I wonder at the utility of a College that does not offer some job training in this age.
Employers look to college graduates expecting them to be trained and have created a huge demand for graduates as a result. Due to the "everything for nothing" culture in the USA, those same employers make it clear that they want pre-trained employees. Colleges react in kind by expanding their enrolment and providing skills that make them competitive in the eyes of their prospective students for the purpose of obtaining a desirable job. Thus the system becomes more a job training centre each day, which is inconsistent with the loftier goals of a College.
Lofty goals are called lofty goals because they are hard to achieve. Colleges of lesser moral fibre will play lip service to such goals and mostly do what industry wants. Colleges of stronger moral fibre will uphold such goals and risk losing credibility with the future hiring base and likewise their future student body. Only a few truly exceptional Colleges will ever be able to disregard the collective employer pressure; like the Computer Science program Dykstra was enjoying. For the masses, environment shapes the subject to a greater degree than we might like.
But I think his arguments are centered around a misunderstanding of terms. It's simple academic dishonesty to which he objects:
The society for a thought-free internet welcomes you.
It's because the field is moving so fast.
In other engineering disciplines, there are new materials and other things to keep up with, but advances are measured in fractional increments (10% stronger, 5% lighter, 8% cheaper, etc.) and most things are made of steel, concrete, plastic and/or aluminum. In computing, over the last 20 years or so, the basic substrate has improved by a factor of 10,000 or more (especially if you look at it in terms of capability per dollar, which is a pretty sane thing to do).
Nerd rage is the funniest rage.
No, its not. Look at Structure and Interpretation of Computer Programs (SICP), which was taught decades ago (and now available on-line for free; google it).
It uses Scheme as its language but rather than present Scheme itself, the course starts with only a few primitives (numbers, symbols and closures/functions) and proceeds to build up to a relatively complete interpreter of the language itself, along the way covering imperative constructs, OOP, meta-languages (including a graphical one), streams (the original magical type; not the contemporary type) and much, much more.
So, to adopt your analogy, it starts students of at a very basic reading level and adds new words and grammar (defined from scratch using only previously covered constructs) along the way, pulling students along.
Note: of course, this is only one of the ways of doing gradually increasing complexity in courses, it's the lambda calculus way. The other way is the engineering way: start with hardware/assembler, work your way up to C and then to some OOP language. Problem with the latter method is that you'd have to find some awkward way of squeezing in functional, set/vector and other programming paradigms in there somehow if you want the course to be complete (and "science"), while the former can incorporate those readily.
An engineer still needs to take quite a bit of physics.
I don't want an engineer who doesn't know what "specific heat" means, and I don't want a programmer (whatever you call him) who doesn't understand computability and complexity.
When I was in university we had to learn how to make our computers first, before we could learn to program them! You whippersnappers don't know anything until you've blown the glass for a tube!
Actually, seriously, I think it's good to start off with some nice, readable mid to high level language. We did Pascal. Python is great. I've never thought Java was really appropriate because you get all the object orientation piled on right at the beginning. THEN, in the next course you get the keys to the kingdom - assembly. Our assembly course was more or less concurrent with a robotics course where we actually used the stuff for doing embedded programming. After that you move on to the stuff like objects and you appreciate them.
Don't you mean
std::cout << "output" << std::endl;
or do you say "don't worry what the line 'using namespace std;' at the beginning of this code does"?
Hmmm. I agree with your thesis, but disagree with your example. The C++ line isn't a whole lot better (if at all) than the Java one. What you need is a good function:
writeln("Hello World") (Pascal, the way I learned it)
printf("Hello World") (C, also reasonable)
print("Hello World") (Python, an excellent choice)
That doesn't take any handwaving about objects OR streams.
Qbasic or shenanigans.
It's better to vote for what you want and not get it than to vote for what you don't want and get it.
- E. Debs
Then again, maybe it's just because my team has alternating making me want to kill them and myself for the better part of the semester...
You're ready for a job in the software industry!
IMO there needs to be a starker contrast between computer science and computer engineering, just as there's a contrast between "real" engineering and, say, physics.
Those who just want to be able to program, who are focused purely on employability right out of college, can look for computer engineering courses teaching the popular programming languages. These people can be fine programmers, ready to start... so long as the language popularity hasn't changed by the time they graduate. It would be sort of advanced vocational program, just like any other engineering.
But the real scientists, those who want to experience and express code on deeper levels, should be looking for something very different, that which Dijkstra describes. Just as a scientist and an engineer can work on the same project contributing different skills, the computer scientist has his place even in the real world.
The two really are different mentalities, and it seems that the mixture of the two leads to situations that are non-ideal for either.
While I agree with your point in general, the particular example of
cout << "output" << endl;
is a poor one... it raises the obvious question of "what's <<?" which then requires either the "it's magic" answer or a lengthy discussion of operator overloading. Depending on compiler, you also might need to "using namespace std" (more magic) or write std::cout and std::endl (less magic but still requires an explanation). Also, what's "endl" and why can't I just write \n?
A better example from Hello World might be "public static void main(String[] args)" ... compared to "void main()" there is a LOT of initially-unexplained garbage in the Java function declaration. :)
Yeah, I know. What can I say? Sort of a force-of-habit as I'm a bit used to another (very lousy) forum (that I have no control over) which splices a supplied standard urls ("too long a word for input") into smaller chunks.
For those of you who are playing at home, the TinyUrl points to http://lucacardelli.name/Fonts.htm
C++ is hardly suitable as a beginner language, too - you'll have to "wave away" things like "#include iostream" and "using namespace std" just as well.
If you ask me, a good first language would be something from ML family (Caml Light is nice) used in an imperative manner (i.e. with loops etc). ADTs allow to explain things such as linked lists and trees without exposure to pointers (and NULL and SIGSEGV). All basic stuff - print, math functions, list operations etc - is in the implicitly imported standard module, so you can initially focus strictly on the algorithm itself, without being distracted by the scaffolding. Type inference also helps there - you can analyze something simple and working first, such as recursive quicksort, before even dealing with the concept of a "data type". This goes best if it's studied hand in hand with Math (as it really should be in school).
Also, OCaml & Caml Light in particular have a very nice simple graphics library done largely in the manner of the good old Borland's BGI (if you remember what InitGraph() did in your days of Turbo/Borland C++/Pascal, you know what I mean).
As for real world, well... myself, I learned on Turbo BASIC on my own, and later Turbo Pascal in school (it was, and, as far as I know, still is a very popular teaching language in schools all across the former USSR). It wasn't a bad choice either - its relatively strict syntax won't let you make a mistake easily, and is generally more readable than C; yet you can get to the more powerful stuff such as pointers if you want to. And, of course, easily accessible graphics.
Well, Algol-60 was Pascal on steroids (and a beautiful language on the whole), and I guess FORTRAN could sort of count as C.
I'd have to say in recruiting software engineers I have much more of a problem with theory-light code monkeys than I do with non-coders that are well-versed in CS theory.
A agree with the above 100% In fact our company tends to hire math, engineering and science majors with the idea that you can teach these people to write code in a few weeks but you can't teach a guy who only knows C++ Physics.
Actually we have a well rounded staff. You need the guys who know the CS theory and the math and physics people too and technical writers and graphic artists and managers. You really do need "code monkeys" but then you need the experienced older guys who can tell the monkeys what to code up.
But I do agree I see so horrible code written by "coders" who know only the details of some language but don't have a clue about (say) DBMS theory.
cat > hello.pl
printf("hello world");
^D
perl hello.pl
hello world
:-)
"If anything can go wrong, it will." - Murphy
While I agree that he talks about many issues that effected the computer industry as a whole, I believe that society has worked through many of these issues. As an example:
(4) The military, who are now totally absorbed in the business of using computers to mutate billion-dollar budgets into the illusion of automatic safey.
The military learned early on that computers are not the end-all-be-all to combat. It still take grunts on the ground to win the battle. Computers provide a means of sorting information. They are nothing more than a tool much like the riffle is to the infantry. (Sorry, I had to use one of those analogies that Dykstra is so fond of hating.)
Another thing Dykstra talks about, is that society changes at a slow pace. This too is a paradigm shift. While we were, at one time, accepting of change over generations. With the advent of the internet most of society now accepts change in the terms of just a few years. (ex: How long did it take Wikipedia to become accepted as a reference for college papers?) It is the ease of which we are able to pass on information that has allowed this to happen.
Some days I get the sinking feeling Orwell was an optimist.
"People who are not full of shit often stink less."
A decent solution to both A and B allows work on C. A crappy solution to A or B means more work on the crappy solution.
Nerd rage is the funniest rage.
>Logarithm tells us that 2+2 != 4, but rather 3.99 [ad infinitum] - how's that for a bit of confusion.
But,
3.999... = 3 + 0.999... = 3 + 0.333... + 0.333... + 0.333... = 3 + 1/3 + 1/3 + 1/3 = 3 + 3/3 = 3 + 1 = 4.
So logarithms are right. There are more than four ways to write two squared.
Check it out, the first page is numbered "0"
I'm a 2000 man.
We get Lenny. And you're nuts.
Everyone who is arguing against Dijkstra and saying that programing is about engineering, not writing formulas or proofs, remember your words when the software patent debate pops up again...
"Give me six lines of C++ code written by the most competent programmer, and I will find enough in there to hang him."
If teaching assembly doesn't interest and motivate the students then either the teacher is crap and needs to be fired, or the students should find something else to do beside programming. A good teacher can do a class based on assembly and hold the attention of the entire class quite easily, as most people who are learning programming (particularly in CS where theory is often more important than practice) should already be motivated to understand how the computer works. If you can't find the motivation to understand simple addressing and things like registers, you need to find a new major.
Curiosity was framed, Ignorance killed the cat.
You have been blinded by marketing. The reason that it is called "Virtual Machine" is because that is exactly what it is. Java is an emulator. It's just that Sun thought "Virtual Machine" sounded more enterprisee. Saying that Java is magic because you can't go lower than the virtual machine is the same as saying that C++ is magic if you run it on VMWare.
You have been blinded by not understand what I was talking about.
I do know very well what a JVM is, and you should read my comments in the context that I know WTF I'm talking about. Then, maybe, you'll get my point that the JVM is a magic black box because you have no vision inside its operation within the context of the Java language itself.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
Magic. How is it attached? What type of model does it use to interact? And most importantly, who cares?
How it is attached is explained by showing the code how it is attached, and the way memory works, and so forth. It's all easily understood, and something that CS students will, at some point, need to understand.
As for who cares, well, a CS student should care, and a CS teacher should care that his students know. It's a fundamental piece of computer science to understand how the fucking things work, don't you think?
Again, magic. System.out is a stream object that by default prints to the console. In either case the cout function and the System.out namespace are functionally identical for our intended use at this point.
False, because the "console" is not defined except in the context of a Virtual Machine that is outside the scope of the Java language itself.
In Java, you cannot explain the console without going outside the language and into the Virtual Machine itself, because that machine is all there is. The "System" namespace is defined by the particular JVM implementation, it doesn't exist outside of that particular JVM implementation.
In C++, you can delve deeper into C and memory and pointers and such, and explain how the console is hooked up, without referring to the specifics of the particular machine. Yes, you can then go even further and explain assembly and machine language and down to the wiring that hooks up the bloody screen if you want, but again, why?
Which requires the explaination of stream opperators, functions, and inputs. .Println requires the explaination of functions and inputs. IMO it is much easier to explain how System.out.PrintLn works because there is less technicalities exposed.
Those technicalities are what you're trying to teach. Or you should be, anyway.
The user needs to understand...
Your argument only makes any sense if you define "user". Because the "user" I'm thinking of is a Programmer. And IMO yes, a Programmer does need to know low-level details about the architecture he's working on. Because when it all goes wrong, then he'll have no fucking idea why unless he understands the details.
Your way does not produce programmers. It produces script-kiddies.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
There is nothing more fascinating than learning how computers really work.
Yes, there is: learn how reality works. I am a physicist and nothing beats the feeling when you get some insight on how the universe behave
-- dnl
Computer Science is larger than understanding how computers work. How about understanding how people work with computers?
Agreed.
Yes, Engineers understand math, at least to some extent. (I was surprised in grad school about how much more rigor was possible compared to doing the same material as an undergrad or high school student :-) And some kinds of engineers use appropriate math for what they're doing. Dijkstra's arguing here that software engineers generally don't. Sure, we'll occasionally apply order-of-magnitude math to our algorithms, deciding whether an N**2 or NlogN is a better choice for the size of data we're dealing with, but computer scientists have been bitching about the lack of use of program-correctness proofs for at least a decade before Dijkstra's talk, and even though our computers are 4 orders of magnitude faster and 6 orders more price-performing than when he wrote the talk, we still consider that stuff too inefficient for practical use and write lots of buggy code.
A simpler example than proof-of-correctness is input validation. A program is designed to take a given set of input and produce corresponding outputs, so one way to improve program correctness is to start by specifying the input set and validating whether the input the program receives is in that set and reject it if it's not. (Replaces "Garbage In Garbage Out" with "Garbage In Error Message Out".) My CS100 professor emphasized that ~30 years ago and made us run all of our homework programs on maliciously designed input, but how many of the security bugs you see today are still buffer overruns or stack smashing or other because people aren't bothering to define and enforce the valid input sets. It's improved a bit with object-oriented programming because objects are a bit more restrictive in what kinds of input they'll accept, and many of the popular objects validate their input and are almost as easy to use as similar objects that don't, as opposed to rolling your own lazily or using C's getwhatevers().
I partly blame Knuth for this :-) His books were the canonical algorithm books for a generation, and did the math really really well, but did programming examples in a baroquely ugly assembler language or spaghetti-pseudocode when better languages were available (e.g. Algol or cleaner assemblers), and that made it hard to learn how to apply his mathematical techniques to real programming.
Bill Stewart
New Fast-Compression-only CPR http://preview.tinyurl.com/dy575ks
They aren't actually right - they're just a very effective tool.
0.99... + 0.99... 2
0.33... + 0.33... + 0.33... 1.
There difference is pretty close to 1/infinite, but it's still less than 1. For all intents and purposes they are the same, but there's still a small difference
But (1/3) + (1/3) + (1/3) = 1 no matter how you slice it.
And that was my point. You shouldn't avoid using usefull tools, just because you haven't quite understood all of it. Imagine just how much you'd be freezing right now, if every seamstress had to understand every single bloody part of the physics and mechanics involved in sowing, carting, fabrication of synthetic fibers etc.
Edsger Dijkstra, the greatest computer scientist to never own a computer
Dijkstra did own a computer. He bought a Macintosh:
"Even after he succumbed to his UT colleagues' encouragement and acquired a Macintosh computer, he used it only for e-mail and for browsing the World Wide Web".
Source: U. Texas CS Department (In Memoriam): http://www.cs.utexas.edu/users/EWD/MemRes(USLtr).pdf
I'm not sure I fully agree with the article. Metaphors can help in better assimilating new knowledge by making it more natural to work with. Think about what object orientation has done for programming. If we had done as Dijsktra suggests and approached software engineering with an "open mind" maybe we would still be coding in assembler, as that is the "purest" way to interact and think the way computers do.
Actually, I think he would want you to do printf("\n");
In any case, I don't think one example of how Java code makes more sense really demonstrates its superiority. It wasn't hard to learn Java after learning C/C++. It doesn't seem to work as well the other way around.
Support a great indie game: http://www.abaddon360.com
So you're trying to convince me that I should like taking the garbage to the dump myself every day.
Well you might be surprised to know that my previous experiences with pointers, manual memory allocation and manual release of memory has been invaluable in my day job programming in for .Net.
Knowing what you shouldn't do to avoid creating excess objects is good for memory usage and performance, and would have been a lot harder to even realize can be an issue if all you've done are garbage collected lanuages
Secondly there are other scarce resources than memory, an relying on the garbage collector to release these (e.g. file locks) in a timely fashion will eventually bite you if the system is complex enough
What you need for GC languages is a decent understanding of how the GC works (in your language/runtime) so you know when you have to help it out. And to get that understanding you need to understand memory allocations first
- We are the slashdot. Resistance is futile. Prepare to be moderated -
You have the same vision that you do with C in VMWare. You either use pre-supplied code to do what you want or you dig into that code to see what it does. The JVM is totally irrelevent to the Java language verses the C language. The JVM is a computer. The X86 is a computer. There is no reason that the Java Language could not be compiled directly to X86, and there is no reason that C could not be compiled to run on the JVM.
Almost everything at this point is either managed code with garbage collection built in, or there are toolsets you can use to manage memory for you.
And this is the difference between a programmer, and a software engineer, who has the versatility to write everything from microcode for new hardware, J2EE applications, or administrative automation scripts. Incidentally - I don't think you get that breadth of skill right out of any 4-year program right now.
These are my friends, See how they glisten. See this one shine, how he smiles in the light.
But the C stands for console.
Not to mention it isn't C, it's C++.
True confidence comes not from realising you are as good as your peers, but that your peers are as bad as you are.
What does this word mean? I googled it, and all that was returned were copies of this article.
"That which does not kill us makes us stranger." -Trevor Goodchild
As an individual learning programming I'd like to strongly agree with this. I took several introductory programming courses, most of which were in Java. It was reasonably easy to make it through the examples in the class, the difficulty came when I tried to branch out on my own and begin learning data structures and patterns. I'm now going and learning assembler and C so that hopefully the principles that are abstracted in higher level languages like Java will have a basis in something more basic like a lower level language.
While this langauage has been implemented...MIT's Scheme is pretty close to a programming language that will never be used in the real world. I thought that it was an excellent way to learn programming outside of the other more practiced languages. There are two problems with his arguments. 1) It doesn't matter if schools press for their students to push their knowledge outside of their comfort zone. There are a wide range of educational offerings available from community colleges to private Unviersities. Students usually try to select their educational challenge based on a wide variety of factors. Prof. Dykstra discussed that the universities should push the students beyond their comfort zone into these radical novelties. Maybe he was teaching at the wrong school. Or maybe he was compelled by his department to dumb down his curicula, but I seriously doubt that every CS department tries to dumb down their education the way he described. The free market let's students decide the type of education they would like. If they want a CS challenge, there are plenty of offerings out there. 2) Not all people are as smart as Prof. Dykstra would like them to be. Even if you found a person with an 100 IQ that was interested in learning higher level abstract mathematics and their application to programming, that person would not be suitable for this education. Most people are very capable of self determining the maximum level of intellectual challenge they are up for. Even if they can't afford to go to some of the more expensive private universities, someone that is very intellictually capabale but financially challenged should have a very wide variety of resources available, including unviersity course access via the Internet.
What about a ^= b, b ^= a, a ^= b (for integers)?
Needed? So why didn't the world fall apart when the fandangled realtime airline-pricing-optimization system got delivered two years late, way over budget, and full of bugs?
Twenty years after Dijkstra wrote this, the situation has not improved; arguably it is worse. Programming has changed from a mere craft to sorcery. How do we solve a problem now? Consult the oracle of google, randomly select an entry, and cut and paste some magic code or call some totemic library. Still doesn't work? Chant some testing incantations. After a while the customer decides that they've run out of time, and decides that near enough to spec is good enough (after all, the spec is not very formal, and can be stretched to fit the program!).
Sure, I'm exaggerating. But when nine out of ten 'software engineers' don't even know what an invariant is, there is a failure of education. Especially now, when most programmers are not coming out of elite universities (which still teach computer science), but out of tech courses.
No, we don't use formal principles to design our complex software projects. But it isn't because time doesn't permit. It is because we don't know how to.
We call it software engineering, but traditional engineering does work from formal principles, and then refines the parts of the construction. We know that doesn't work for software, because of orders of magnitude more complexity, and interactions between parts of the system. Symbolic digital computation is a paradigm shift.
Why does it matter? Because we aren't just talking airline systems. Twenty years ago the big deal was the missile defence system 'star wars', which was to be a larger software project than anything in existence at the time. The potential harm from the failure (at runtime) of such a project is not worth contemplating. Maybe your airline system is not important (!), but some of us write code that has life threatening consequences if it fails. So we welcome any advancement in the theory of programming, and in the teaching of that theory.
Those technicalities are what you're trying to teach. Or you should be, anyway.
Ahh, but your initial assertion was that it is easier to EXPLAIN cout << "output" << endl;. Not that it was better teaching material.
I would concur with you on that side. If your goal is to teach computer science bridging from machine code to high level languages, then C is a better route. If your goal is to write code that can be quickly and easily explained and immediately obvious to later reviewers, the Java/C# (or even C++) option is a better route.
Your way does not produce programmers. It produces script-kiddies.
No need for a pissing match. Not everyone who uses managed code is a "script-kiddie". And not everyone who codes in C is a Computer Scientist.
You'll never bill time to a contract for developing your own compiler. (**except in a very limited number of situations). And only a handful of developers in the world will ever work on embedded software where memory management tools are not available.
Is it good to understand how garbage collection works? Sure. Is it great to have the knowledge of how compilers work? absolutely! Will either make you a better developer in the vast majority of software development positions in the world? nope.
But there are still great things that can be done with that knowledge, and there will always be a small demand for people who have studied hard on the subjects and are willing to push the envelop and work with the lower level technology. So I think it is excellent that it is taught in Universities.
But for the vast majority of computer programmers in the world, such lessons will have no significant impact on their professional careers. Which is why I think it is excellent that it is NOT taught in Tech Schools. (depends on the school actually, most programs that I've seen still cover a semester or two of C++ pointers, memory management, and compiler directives, but nothing compared to the in depth focus most University programs do)
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
That's all fine and dandy. But how to teach people about electrons?
Without analogies to properties of electrons which are wave-like or particle-like, how do you say anything useful about an electron to anyone who isn't already a particle physicist?
Ayn Rand said it well, if your base premises lead you to contradiction, you must examine your premises. Rather than be driven crazy about how an electron can be like two things which are as different as a particle and a wave, you should question your assumptions.
Are particles and waves so different from each other? And why should there be any dissonance in any one thing having properties of both? I have the accented english of Arnold Schwarzenegger and the physique of Danny Devito. Are you now driven crazy on how I could be like two such different people?
As someone who's teaching this stuff, the second is easier to explain in detail and doesn't rely on saying "don't worry what System.out is".
Hilarious. And what will you say if they encounter an error like the following? The error in this case is that bar is missing parenthesis, as it's a function and not data. I ran into this just yesterday:
15 more lines of the same follow. I'd give you the whole thing, but if I do Slashdot says: "Filter error: Please use fewer 'junk' characters."
Indeed.
Actually, I think you chose a really bad example for showing how Java is a bad first language.
For someone reading their first lines of code, I would argue that System.out is more readable than cout, and println("text") is more readable than
Don't get me wrong, I don't think Java is a good university language either. We use java for most compulsory courses at my uni, and I think it's a worse fit now (2nd year data structures) than in the introduction courses. I struggled with creating a hash function with no unsigned value, and a lack of pointers (specifically, you can't do "this = other_obj"). Maybe I'm just too used to C though.
echo "echo Hello World" > hello
. hello
Hello World
I'm a minority race. Save your vitriol for white people.
Amen
All the focus on this or that programming language, even in this topic, is totally misplaced. Any decent programmer will learn any decent language in a fair amount of time. I learned more different programming languages while working then during my education. I can list all of these on my resume, but thats not really important. Because you can produce crap in any language anyway and because I will just learn whatever new language you want me to use this time.
Stroustrup is wrong (or perhaps over-enthusiastic about teaching C++ to beginners). If it were any other language, sure, but using C++ for anything but trivial applications without a knowledge of C is an exercise in futility.
For example, you can't use "new" for anything (other than wasting memory) without using pointers in C++, so one better have some semblance of an idea about how pointers work before trying to write anything that doesn't look like a FORTRAN program.
The problem is that (for all its benefits - and there are many), the design of C++ is forever compromised by the requirement to be backwards compatible with C. String literals aren't strings, they are *pointers* to a series of signed eight bit integers. When new objects are allocated, by default they contain random garbage data. No array bounds checking anywhere. Does a language really need both references *and* pointers? Other than backward compatibility?
I wouldn't dream of teaching C++ to anyone who didn't have a working knowledge of C, because using C++ to do anything worth the extra complexity of the language requires it - and a lot more.
It's wrong to say that one has never owned a computer. Most humans do have computers, because our hands are computers. Our brains are also computers, as are our whole bodies. Computers are everywhere, even in non-living things, if you know how to recognise them. In fact we are living in a huge computer. So, the summary should say that he has never owner a digital electronic programmable personal computer.
At my university, the gateway CS course is taught in Python. I already have 3 years of Java under my belt, but they're going to assume I do not, which is good.
which is why it should be 'print "output"'. OH NO, that's BASIC. If you write one line it you'll become mentally retarded.
>Imagine that, a mathematician describing engineering as deriving a formula!
>No comfortable analogies here...
That's not an analogy. That's literally what computer science is. That you did not know that says a lot about why he wrote that article.
They didn't decide that merge sort was a correct sorting algorithm by coding it up and running it a million times. A mathematical proof was given. No actual running computer is necessary.
Furthermore, a computer program *is* a mathematical formula. It always has been. Dijkstra is pointing out that the curriculum has been so dumbed down that most programmers don't even know that.
In this article Dijkstra correctly criticizing the fact that most programmers don't know how to prove the correctness of algorithms. The same could be said about asymptotic complexity. Most programmers do not understand these concepts well enough to write programs that don't run forever on large input values. This is a real problem.
There are both analytical and empirical methods for dealing with computer programs. The analytical methods involves proofs of correctness and symbolic manipulation. The empirical methods involve software testing and debugging.
Dijkstra certainly goes overboard by suggesting that software testing is totally unnecessary because he's not interested in such intellectually uninteresting problems as reliably detecting typos in 10 million lines of source code for a problem. Dijkstra correctly points out that software testing suffers from the fallacy of induction, but ignores the fact that induction is an important tool even if it doesn't prove anything.
The truth is that most programmers are just code monkeys with no understanding of the *science* in computer science. That is what Dijkstra is railing against ultimately.
>Oh woe! Not having to worry about pointers and having built in string types.
>I love C. It's terse and really useful for optimising performance but it's really not a good teaching language.
C is an excellent teaching language. It has a relatively simple syntax, and doesn't hide anything under the covers. In a similar way assembly is also an excellent teaching language.
It teaches the user about memory addressing and memory management, which are important topics no matter what language you use. It also teaches the user how to do the elementary logic and understanding of flow control that constitute the early stages of learning how to program. It does all this without forcing the learner to memorize unnecessary syntax.
Conversely, while C is an excellent teaching language and a poor language for real world use, C++ is an excellent language for real world use, and a poor teaching language.
I expect there will be some inane comment about how C++ sucks from someone who tried it once and thought it was too hard to learn how to use. My response is simply, "don't be such a baby." Real programmers use C++.
For instance, to simply output a line to a command line in Java you're looking at System.out.println("output"); whereas with c++ (for instance) you have cout << "output" << endl; As someone who's teaching this stuff, the second is easier to explain in detail and doesn't rely on saying "don't worry what System.out is".
I'm no fan of Java either (and I think that none of C, C++, or Java make a good starting language), but that example is unfair. The C++ code would look either look like std::cout << "output" << std::endl; or feature a using directive, both of which require about as much hand-waving as "System.out".
Mr. Period: Nine is the one that's right by ten!
Nine: One day I will kill him. Then, I will be Ten.
How the college I attended did it....
1. Semester: VB 6.0 (it was in 2003) :( .NET .NET libraries.
- Doing more than the required work gave you negative points on your marks... People didnt bother learning much due to the teaching destroying interest
3. Semester: ASM and C for PIC-Microcontrollers
- Mostly useful, though somewhat messy since the teacher really didnt know ASM that well.
4. Semester: C++
- C++ without object oriented programming...
- We were not allowed to use string classes. All strings were to be char arrays and use the C-style string handling.
- We were not allowed to use Printf to format stuff, only cout.
- Only command line apps.
5.th Semester: C#
- Teacher didnt like us using "advanced" features of the
- Required us to turn in binaries in addition to source so "he wouldnt have to compile all the turn ins". (Yes, he ran unknown binaries...)
So I have a less than stellar view of the CS teaching that goes on... My degree was in automations engineering but still, computer science is a major part of it.
Frankly, I find printf("output\n"); to be more self-evident than either of the above.
But then, I learned C first.
myselfmusic
So, his Macintosh wasn't a computer?
It couldn't have been his, you know, personal computer ;)
Is it good to understand how garbage collection works? Sure. Is it great to have the knowledge of how compilers work? absolutely! Will either make you a better developer in the vast majority of software development positions in the world? nope.
Wow. Okay, we're just going to have to agree to disagree on this one, because that is by far one of the stupidest things I've ever read.
If you don't know how garbage collection and compilers work, then IMO, you are not a Programmer. You're only a code-monkey at best, somebody who can bang rocks together and can make things happen, but is incapable of anything higher-level than that. One of those useless management types, at best.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
Nonsense. There is no technical reason that a subset of the English language cannot be compiled directly to the X86 either, but that doesn't mean that knowing English makes you a programmer or makes you understand how the things work.
C is closer to the metal than Java is, for anything that currently runs Java. When you understand C, you have a better understanding of the underlying architecture. When you understand Java, you don't.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
I would venture a guess that many of the people who have contributed code to the /. code base do not know how garbage collection works.
I would venture a guess that the majority of people who actively develop small business (and even large business) software solutions using managed code libraries don't know the intricacies of how garbage collection works.
So long as they understand scope, and that the GC will clear memory when it decides it needs to, they are perfectly capable of writing great applications. Understanding they underlying windows pump messages and assembly level memory interactions is a waste of time.
Is it good to know? Sure. But it will not make them a better application developer. And anyone who is cowboy enough to try to rewrite a memory management system while on contract has no business being on contract in the first place. The tools already exist, use them. If you want to design new tools, and you want to get into the intricacies of the GC, get a job with Microsoft, Sun, IBM or even the smaller 3rd party tool designer companies where you will be working on creating the next generation of tools. There are significantly more jobs for people who use the tools than those who design them.
You want to talk about stupid reads, see how your CIO would feel about reading your time sheets with 200 hours dedicated to creating a new memory management system for an ERP application.
If you don't know how garbage collection and compilers work, then IMO, you are not a Programmer. You're only a code-monkey at best, somebody who can bang rocks together and can make things happen, but is incapable of anything higher-level than that. One of those useless management types, at best.
Going with your definitions, I've seen a "Programmer" cost a company half a million dollars in a single day. And I've seen "Code monkeys" develop top notch applications that saved companies millions of dollars every year.
Personally, the debate doesn't matter to me. You may take offense that a "code monkey" who doesn't deal with assemblers or GC gets paid more than you, and the code monkeys may be offended by your pretentiousness, but in the end, it still takes both types of mind sets to push the future of software development.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
What about Konrad Zuse? You are clearly forgetting Zaphod Beeblebrox!
Guns don't kill people; Physics kills people! - John Lithgow as Dick Solomon on Third Rock From The Sun
I would venture a guess that many of the people who have contributed code to the /. code base do not know how garbage collection works.
Hell, I have no doubt of THAT. Have you ever looked at the monstrosity that is the Slash code?
Is it good to know? Sure. But it will not make them a better application developer. ...The tools already exist, use them.
Without knowing how it works, you have no way to gauge whether it is the correct tool to use or not.
Knowing the right way to do things makes you better at anything, programming included. It's not about creating the tools from scratch or even needing to do so, it's about knowing how things work in order to choose wisely.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
Without knowing how it works, you have no way to gauge whether it is the correct tool to use or not.
You seem like an intelligent fellow. I would venture a guess that you comprehend the basics of an internal combustion engine. You understand that an air fuel mixture is compressed and ignighted and the resulting expantion is used to force a piston down, turning a crank shaft and producing torque.
Now, if we assume that you know that, and follow your logic, you should not be able decide if a car is an appropriate means of transportations.
Why? Because I doubt that you are intimately familiar with the underlying technology of your car. The electronic control systems, the fuel delivery system, the air delivery system, the exhaust, etc...
Do you honestly know the composition of all of the catalitic converters on your car and the temperatures they require to opperate correctly and the exact chemical reactions they produce to reduce your car's emissions? Do you know the composition of your engine block, it's rate of expansion, it's ability to transfer heat? Do you know the displacement of your heads, the valve presure, the oil gally routes? etc...
And to my point, does knowing any of that make you a better driver?
As for the GC issue. So long as a developer understands scope, and the basics of how memory works (this is the heap, this is the stack) then they are perfectly capable of making such a decision. Just as knowing the simple basics of how a car works allows a person to make decisions about their means of transportation, even if they can't tell a wankle from a otto.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
If you weren't anon and this a couple days old, I'd say mod parent funny!
What's wrong with the world can largely be attributed to the usual things: Chinese, Russian, and American policy on a wide variety of subjects, plus petty-minded xenophobia that keeps the Hutus and Tutsis, or Palestinians and Israelis, at each others' throats. Nothing to do with how we teach computer science, I assure you.
I piss off bigots.
Are you cracked out? cout is an object, so you still need to explain OOP, and you have to explain that you're calling a member method <<, which also requires explaining operator overloading, etc etc etc.
In my opinion the C++ version requires more because you really do need to explain operator overloading, whereas the Java version is bog-standard dot-notation method invocation. Obviously we don't agree on that point, but everyone should be able to agree that they both require quite a bit of 'splaining if the person has never seen a programming language of any kind.
Why? Because I doubt that you are intimately familiar with the underlying technology of your car. The electronic control systems, the fuel delivery system, the air delivery system, the exhaust, etc...
Do you honestly know the composition of all of the catalitic converters on your car and the temperatures they require to opperate correctly and the exact chemical reactions they produce to reduce your car's emissions? Do you know the composition of your engine block, it's rate of expansion, it's ability to transfer heat? Do you know the displacement of your heads, the valve presure, the oil gally routes? etc...
I am a poor example, as I have done much work for many automotive manufacturers, so yes, I have done much work on automobiles and know them quite well. ;)
As for the rest of your diatribe there, involving the heat transfer and composition and all that, knowing specific facts is not particularly useful, however knowing that these things occur is quite handy. Knowing that heat makes metal expand, for example, is a useful fact in and of itself, even if you don't know exactly how much a specific piece of metal expands.
And to my point, does knowing any of that make you a better driver?
Yes, it absolutely does.
More to the point, it makes you a more knowledgeable human being, and makes you a better person overall, in everything you do. You never know how the facts will come together, and so a general knowledge of everything is very handy to have.
As for the GC issue. So long as a developer understands scope, and the basics of how memory works (this is the heap, this is the stack) then they are perfectly capable of making such a decision.
But will that decision be a good one or a bad one? Anybody can be lucky. A wider and deeper knowledge of the subject matter could lead one to a better decision.
Just as knowing the simple basics of how a car works allows a person to make decisions about their means of transportation, even if they can't tell a wankle from a otto.
Some decisions, yes. Others, no.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
After BASIC, I was glad to encounter programming languages that could be used to solve complex problems, and made it possible to understand complex programs.
So the dead Dijkstra was wrong, and the living Dijkstra is right.
I think you're missing the point. Yes, the program is fairly easy to write. The issue is that it will take a very long time to run on problems of non-trivial size.
"The use-mention distinction" is not "enforced here."