Hacker News new | past | comments | ask | show | jobs | submit login
CS Education: The Deep End of the Pool (atomicobject.com)
80 points by gvb on May 21, 2011 | hide | past | web | favorite | 63 comments

Today's CompSci programs consist of an unholy melange of Software Engineering and theory. Both aspects are rather messed up.

The Software Engineering part is done badly because the slope is too abrupt and ends too quickly. The Java-based curriculum invariably ends up teaching OOP concepts within weeks (if not to start with) to someone with no concept of program flow, variables and functions. From my experience as a TA, I'd say 90% of students who haven't programmed before end up utterly confused about the order of execution of the various bits of code in a simple Java program with 3-4 classes.

The few people who survive this abrupt slope with an intact desire to learn more CompSci find that the slope ends too quickly. There is no further discussion of issues that are crucial for industrial Software Engineering: debugging techniques, version control, code repositories. Instead, the sophomore abruptly has to choose between a rock and a hard place: either a course in C, leading to an honours thesis in Systems; or some math-y courses leading to Theory.

The C course is a frustrating experience, requiring the student to un-learn a lot of the concepts learned in the Java intro courses and to learn instead to tread carefully on a landscape suddenly filled with inexplicable bugs. But this is actually the more accessible course, as the theory courses require a mathematical ability that the majority of potential CS majors simply don't have (or even had any inkling that it was required).

I think any intro course should begin with an explanation of very simple architecture concepts (program counter, memory, hard disk) and spend a good amount of time drilling the basic concepts (variables, loops, function parameters, function return values) and basic debugging techniques. In the second half of the semester, while the students work on a large project to practice these skills, spend the lectures to give them a broad survey of the major: architecture, algorithms, programming languages, OS, theory of computation.

> The Software Engineering part is done badly because the slope is too abrupt and ends too quickly. The Java-based curriculum invariably ends up teaching OOP concepts within weeks (if not to start with) to someone with no concept of program flow, variables and functions. From my experience as a TA, I'd say 90% of students who haven't programmed before end up utterly confused about the order of execution of the various bits of code in a simple Java program with 3-4 classes.

This perfectly mirrors my experience.

If a kid gets a 5 in AP comp-sci, the college will still make him take the intro base CS courses.

College is also set up for majors to be chosen without any understanding of those particular areas of study in high-school.

So, yes, your intro class should be for kids with no former compsci exposure, just like every other major your college offers. You then allow AP compsci students to waive some of the intro classes.

Of course, the real question is why should the kid pay money to hear this guy when, if the kid already has an interest and some knowledge of CS, learn with MIT open courseware and iTunes University?

Do you think CS professors are the best at presenting/explaining the material? I believe it depends on the professor.

Music is much more difficult than compsci. In addition to the mental, you have to hear/listen, and possess excellent muscle coordination.

So, yes, your intro class should be for kids with no former compsci exposure, just like every other major your college offers.

I think his point is that no other major starts from scratch. The standard first-year math course is calculus, which builds on algebra, geometry, and trigonometry. First-year English and history classes are very much like high school English and history classes. First year classes in most subjects actually provide a misleading degree of continuity, with second or third year classes suddenly taking a college-level turn: proving theorems, writing seminar papers, etc.

To make an analogy with math, imagine if a student's prior exposure to math was just basic arithmetic to calculate change, scale recipes, and figure out how many weeks until their birthday. Then they go to college and take an "intro" course that covers all of high school algebra, geometry, and trigonometry. They're floundering because of the pace of the class, and they look around and see that about 20% of the kids are utterly bored and itching to get to trigonometry, because they already learned algebra and geometry in their spare time in high school.

That's the situation college CS programs find themselves in. How in the world do you take someone with no prior exposure to one of the fundamental skills of the field and, in four years, turn them into someone to whom it would be appropriate to give a college degree in computer science? Programmer isn't just a neat and useful skill. It's the skill by which computer science is traditionally explored and learned -- we don't know any other way except mathematical theory -- and it's the skill to which computer science knowledge must be wedded for a computer science graduate to make themselves useful. (Not every computer science graduate needs to be a programmer, but they all need to program, unless they also have a degree in another field or plan on going to graduate school.)

>> How in the world do you take someone with no prior exposure to one of the fundamental skills of the field and, in four years, turn them into someone to whom it would be appropriate to give a college degree in computer science?

You don't, unless they have the passion, drive and natural aptitude. The author makes very apt comparison to music and expresses that there's really no way out of the conundrum in that field, but wants to find one for CS. Just like music, if you want a university-level program where anyone can come in and succeed in a limited amount of time, you have to rely on high school curriculum to provide the foundations.

The problem is perception. Given a standard high-school curriculum, it's obvious that a student won't succeed in a university-level music program without becoming specialized in high school, but it seems like students should have the foundational knowledge to succeed in a university-level computer science program. Unfortunately, it's just simply not true.

The author says this in the comments:

I don’t want to effectively require students to choose early in high school whether or not they want to study Computer Science in college. While computing skills are clearly beneficial for everybody, I hesitate to make the claim that computing courses are more worthy of limited curriculum time than other disciplines such as foreign language.

Unlike the author, I don't hesitate to make that claim at all. People often lament that students graduate high school knowing basic history, algebra, physics, biology and the like, but don't understand how a credit card works, what happens when they push the gas pedal in their car, or most importantly, simply how to think logically and critically. Shifting part of the mathematics curriculum to focus on logical thinking, regardless of whether it's presented using programming or not, would go a long way towards enabling success in fields like computer science, and would make graduating high school students more well-rounded to boot.

I like the analogy to music, but honestly, I think programming itself, divorced from knowledge of operating systems, theoretical computer science, mathematics, web design, or other complementary skills, is not on the same level of technical difficulty as music. You don't need to start as a child to become sufficiently competent to become a computing professional. You do need practice, though, and that is what is sorely lacking in the curriculum. His concern about the lack of sufficiently engaging practice problems is spot on. When all the programming assignments are about CS topics, they're trying to teach CS and get programming as a freebie, instead of teaching programming as a skill in itself.

I agree with you about teaching programming in high school and lower grades. Programming would be much more beneficial for most kids than advanced algebra, trigonometry, and calculus. Average people today need to understand their computers, their taxes, their employers' benefits policies, and other logical and algorithmic systems much more than they need to understand radio waves, flow rates in pipes, or falling objects. The standard curriculum should include some programming at the expense of sequences and series, trigonometric identities, possibly any math beyond geometry, basic algebra, and using a calculator's sine and cosine functions to compute the sides of a triangle.

(Actually, I would be hesitant to suggest such a thing because many college-bound kids need as much math as is currently offered and more. If a kid is going to take freshman calculus in college anyway, you might as well teach him some programming in high school instead of pushing all the way through a math class he's going to retake in college. On the other hand, every high school needs to offer a complete calculus course for kids who will be able to ace the Advanced Placement test and skip calculus in college. There are so many ways for educational reform to go wrong, and I have so little faith in the people who would carry it out, that sometimes I'm glad the system is unlikely to change significantly any time soon.)

College level music studies are more difficult primarily because they have to be. As the program gets easier, enrollment can tend to go up because the pool of people who both want it and can do it becomes larger. College music programs have to cut their pool size down by raising the bar or they'd be flooded. In terms of intrinsic difficulty, well, in a way they aren't that different; anybody can pick up an instrument and with effort attain basic fluency, anybody can pick up a programming language and attain a basic level of fluency.

I disagree. I have personally known physically disabled individuals who are excellent programmers yet are physically incapable of playing musical instruments.

> If a kid gets a 5 in AP comp-sci, the college will still make him take the intro base CS courses.

That's not true (at my university, anyway). You can skip the first two semesters of the CS curriculum with a 5 on the AP CS AB exam.

I personally chose not to use most of my AP credit to give myself a relatively easy first year during which I instead developed lifestyle/social skills. One of the best decisions I ever made.

I believe the AP Computer Science AB exam was discontinued after 2009.

Ok, so lots of things to tackle here:

1. The commenters seem to imply that java is probably not the most appropriate language for cs1, where syntax considerations often overpower practical concerns.

2. Bright students that 'get it' are not the baseline, they're the exception. It's the other, intro level students that the class/recitation/curriculum should be catered towards.

3. Many (if not all) fields of study 'get hard' in college (i.e. physics, pure math, etc). The problem in this case is one of students being improperly tracked (i.e. curriculum failure).

4. Intro CS courses vary wildly in expectations and ideology. This set of courses seems to focus on 'practical' considerations that are probably better suited to a separate 'software design' course. It's possible that this 'survey' is actually too broad and not focused enough.

5. The music analogy is cute, but fails to consider that intro cs courses typically only succeed (and attempt) in getting students expressive (i.e. jibbering toddler) rather than elegantly fluent. This is why many post-cs1 students generally can solve problems using their new toolkit, but often solve them naively (it's like a toddler that says the wackiest things)

6. Confusing "programming ability" with "computer science" is problematic overall, i don't know that anyone would want to spend four semesters "programming" but i've know a bunch of people that enjoy the theory=>pracitce :: state machines => regular expression 1-2 punch. You can do quite a bit of fascinating cs in a logic/philosophy class as well as in a complexity theory class without ever touching a computer. I know, heresy, but it's true.

I think finally, the issue here is confusing "computer science" with "software engineering." I think java's a great language for software engineering, it's got all the stuff builtin to teach those concepts, but as a language for sketching, i'd probably use python.

People often make this mistake in teaching javascript because built in is the ability to manipulate the dom which, while eminently useful, is also basically a whole separate language/paradigm mess than 'javascript neat.'

And this is a hard question to be confronted with in any case: what are you teaching and why are you teaching it? Neither of those seem to be fully addressed in the author's description of cs1/2.

In regards to #5, I think a more apt comparison would be teaching music theory students some basic piano so that they can mash a few keys and experiment with the ideas presented in class. And the choice of piano as the learning instrument isn't arbitrary: it's trivial to make sensible noises just by pressing a button, whereas something like violin requires a decent amount of technique just to play a single note. Plus the layout of the keys is very intuitive, a student can play their first scale on day one, which is certainly not the case with violin.

If you follow the analogy, the best programming languages for CS101 will first, minimize the amount of technique required to accomplish simple tasks. Java is out, "hello world" already introduces the concept of classes, static methods and access specifiers. Ruby, python, and plenty of other dynamic languages look a lot better, "hello world" is a single statement/expression. Second, the layout of the keys should be intuitive, consistency and simplicity in syntax/semantics is often cited as one of lisp's strong points with regard to it's suitability as a teaching language. If you want to play a scale, you just need to hit the keys in order.

this reminds me, although tangentially, that i saw a chapter of a book once that was basically dedicated to dissecting all the boilerplate in a standard C "hello world" program. It would go over details about argv and so forth and then introduce wrinkles into the program and see if you caught what they were.

It's my opinion that CS first-year courses are a wreck. The system is broken.

To get competent in programming seems to take about two years. To teach computer science/software engineering concepts in any form of depth (besides a simple, 'yo, here's X, here are 5 datapoints about X for the test', requires knowing something about programming. That means that to seriously teach data structures, algorithms, software engineering, computer organization/architecture, programming languages, all carries with it the pre-req of years of work. So students have massive issues!

I believe that it is indubitable that the best way forward is to have an optional programming track added to high school education. But we've all heard the high school programing-teacher horror stories. Add to that the idiocies perpetrated in the name of 'students must know computers' (Oh, look, Little Bobby Can Use Word). So that's probably not realistic.

What might be realistic is sketching out a college curriculum that uses a step function in terms of winnowing out students. E.g., the spring courses are hard, the fall courses are easy. That would help move things along better. Yet, the fundamental issue is that a 4-year college degree seems to be insufficient to prepare students from knowing zilch to being hireable, without some pretty heavy investment on the student's part.

Outside of software and music, I have never heard of this scenario for any college degree. I hope that I am wrong, that these two majors are not unusual.

I prefer to have spring courses hard, fall courses harder. I also think the first year of CS should be read straight out of Knuth's The art of computer programming.

It's something I've always thought, but I was not able to put it in words as well as the article do. The comparison with music is highly accurate, and very simple. I like it.

I agree, and I really like it because it works on a lot of levels. Like music, a "computer science" curriculum covers a huge range of things on the "practical everyday usage" <--> "theory" scale, and in order to be valuable you have to have knowledge all along that spectrum.

The 15 week expectation is aggressive, perhaps too aggressive, but not entirely absurd. The problem is the follow-up to the introduction, not the introduction itself.

CS 2 should not be dealing with inheritance, polymorphism, or object-oriented design. These subjects are advanced not because they are difficult, but because they are useful abstractions that help solve large-scale organizational problems that students have never faced. They are important aspects of programming discipline but are useless if you don't understand the underlying tools to begin with.

Instead of trying to teach design and high-level abstractions in CS 2, the focus should be on how systems actually work. You should be removing layers of abstraction rather than adding them. Programmers make computers work using compilers(and interpreters), operating systems, and networks. So begin teaching students the fundamental knowledge needed to use those tools effectively.

Students need to understand syntax. Teach regular expressions and context-free grammars. There is no need to go as deep as theory of computation or languages or compiler design, but students should be able to recognize how a language's specification matches their own code, so they can correct errors from principle rather than by trial-and-error.)

Students need to understand how to use libraries. They should understand how they can obtain and use new ones in their own code.

Students need to understand how to use the interpreters and compilers that translate their programs into machine code. They should know how to build and configure several different development environments given a standard windows, linux, or mac box.

Students should know the basics of memory and IO. There doesn't need to be a dogmatic focus on optimizing for performance (there will be plenty of that later I am sure), but the constraints need to be as clear as possible.

Consider teaching OSI layers or the HTTP protocol rather than inheritance.

Data structures and basic functional abstractions are important fundamentals, too. If they aren't covered in CS 1, it makes sense to prioritize them in CS 2.

A programmer who doesn't know object-oriented design and polymorphism might write ugly code. A programmer who doesn't understand his target environment is going to write broken code. A programmer who doesn't know how to use his compiler isn't going to write any code. If the goal is preparing a student to be an effective computer scientist, the first step is imparting fundamental tools of the trade.

I agree with your point that making inheritance, polymorphism and OO design the focus of the second course is not a good idea. But I think you're still trying to put too many disparate concepts into it.

My first programming course took us from assignment 0 where we copy-and-pasted code to make sure we could use the compiler to a 450 line program that required us to answer queries on a simple data-set that was a directory of people. My second course was focused around an extension of the previous semester's project. The data-set became more complicated, we added a GUI, and we had to be able to write intermediate results out to a file, and read them back in. We were introduced to pointers and dynamic memory, and we got our first taste of data structures by implementing a linked list and having to sort it. The final program was 4,000 lines. Near the end, we were introduced to the basics of OO design - no inheritance or polymorphism, but we were supposed to take our data structures and associated functions and organize them into classes. In that way, we were able to see that some OO programming was just a more organized way of doing what we were already doing.

The emphasis of the second course was introducing us to data structures, basic algorithmic analysis, and making us program a lot. Not just in time, but also having a large program. Full OO came in the third course.

I agree with your point that making inheritance, polymorphism and OO design the focus of the second course is not a good idea. But I think you're still trying to put too many disparate concepts into it.

That's very probable. I'm in the middle of organizing my thoughts on this, based on my memories of introductory CS 14 years ago and what I've learned since then.

By far the biggest difficulty I had with my CS program was that they left it up to me to learn any "real" language on my own. The only language covered during the first two semesters was Pascal. C was never covered, except as an optional one credit class (which was combined with Unix and shell scripting). Assembly was covered, and if you took theory of languages you learned lisp. That was it.

All the painful idiosyncrasies of C and Java, rather than bogging me down in my first year, bogged me down when I was supposed to be writing operating systems and learning algorithms. Despite having a solid understanding of all the concepts: loops, recursion, lists, queues, functions, etc, having been using them since high school, I had a ton of trouble just getting them to work in C or Java (This was Java as it was in 1999 or so).

I remember submitting assignments in Java that used one single gigantic method in a single class because I got sick of spending time trying to figure out why the abstractions I was trying to create weren't working like I expected. I knew the object oriented concepts and aced all the tests, but had trouble when it came to actually writing code in anything but Pascal or BASIC. (or Matlab, actually, but that wasn't part of CSci)

In particular, I believe that expecting a student to learn to program well enough to study Computer Science in a single 15-week course is almost as absurd as expecting a student with no instrumental musical experience to be ready to join the university orchestra after 15 weeks.

I was a TA for CS 101 and 102 for a couple of years. I think I taught almost no one to program. The result (in terms of actual programming) would've been the same, had I just given everyone software and books and said, "have at it!"

As it was, I was just putting people through the motions of being in a college course.

The writer of this blog post and some of the comments here seem to be conflating two terms: "Computer Science" and "Programming".

I'd like to suggest that maybe we should consider two completely different things. Just as there is a huge different between someone who can play a musical instrument, and someone who is well versed in musical theory, there is also a huge difference between a _programmer_ and a _computer_ _scientist_.

You can learn how paging in a virtual memory system works, and how a garbage collector works, without necessarily being able to code up a program that plays "twenty questions". And similarly, someone be able to code up all sorts of interesting programs, without necessarily understanding "big O" notation. Their programs might not be the most efficient in the world, but it's certainly possible to do all sort of programming without being exposed to the formalism that comes from taking CS classes --- that's what most high school students who taught themselves how to write Basic, or Pascal or C programs generally have done.

If you decouple the two, then you could imagine having a series of classes which are "programming labs", for which you could test out of the first 1 or 2, and which would be mostly about the skill of programming, and different series of classes that are about _computer_ _science_, and which don't necessarily require that much programming expertise.

Programming is a fundamental tool of computer science.

Sure, you can learn how paging in a virtual memory system works by reading wikipedia, but a computer scientist should really be able to write one of their own if they had to.

Why? Would you consider Knuth less of a computer scientist if he were unable to implement some modern operating system component?

Knuth was the author of TeX and Metafont, and I'd be hesitant to suppose him to be unable to implement anything.

Not just being snarky here. I think even theorists have an implementor somewhere underneath.

Knuth, the guy who wrote The Art of Computer Programming?

I'm not sure I can make sense of that question.

No one can know everything, but if your specialty is, for example, virtual memory paging algorithms you should be able to write programs that implement and comprehend those algorithms, even if it's not production-quality code. If you are on the more practical side you should be able to read and hack on the existing code, even if it's not the central focus of your job.

I'm sure it's possible to find people who can be considered computer scientists but don't code very well or at all. But those people are rare exceptions, and aren't evidence that programming isn't an important tool in computer science.

You mean Knuth, the guy whose algorithms ignore the effects of caches?


There is a place for academia and mathematic approaches, and there is a place for real world experience and technical abilities. Ultimately someone who is good at being programmer does need a leavening of academic background, and someone who is a successful academic needs to know something about real computers instead of the academic over-simplified illusory world that contain friction-less pulleys and massless ropes.

The binary heap is not Knuth's algorithm. He just analyzed it in great detail at a time where caches weren't as important as they are now. If Knuth were starting out today, I'm sure he would be interested in cache-aware algorithm analysis.

I really don't think Knuth of all people can be held up as an impractical egghead. Compared to many other academics, he has always maintained a view towards real computers.

From what I've heard, other engineering disciplines (civil, industrial, etc) curriculum is based on actual real world work experience and jobs. They prepare you to work as an engineer. CS, on the other hand, tends to prepare you very poorly to work as a programmer. Being a programmer is about 25% CS fundamentals and 75% other stuff - understanding requirements, writing maintainable and easy to understand code, being productive, testing, bug fixing, estimation, refactoring, reading documentation, pair programming, prioritization of work, managing your task list, handling failure, working with 3rd party vendors, etc. All that stuff is not taught and should be.

A good video sort of on this subject that I recommend is this one:


That is because computer science is not engineering just as biology is not practicing medicine.

I tend to agree with the article. I am a senior, studying computer science and also a tutor at the engineering building on campus. The large majority of students that come in and need help are from the CS1 and CS2 classes. It's really frustrating for me sometimes because these students typically know very little about how at program and they are asked to make decently large/complex programs. As a result they all think programming is this insanely hard field that only geniuses can understand. I tell them that learning programming is like learning a language, to someone that doesn't understand it or is learning it it looks like gibberish. However once you get it, it's just like reading. Unfortunately, most of the students don't believe me and end up not continuing CS.

In addition, at my university I feel like the majority of students who are in the upper level classes with me (CS majors past their second year) got credit for the intro courses in high school. The way I interpret this is, it is a lot more likely for students to continue study CS past the first year if they take high school CS, which is a longer slower moving intro CS course.

I think the intro courses need to be much easier. They are discouraging too many smart students!

First, my school started us with a course in theory (sets, counting, probability, recurrences). Only second semester did we start programming (and continue with theory: regular, context-free languages, turing machines). This is the track offered to "honors cs" students which, officially, display "significant interest in CS" but may easily have no programming experience. I don't know if this is a better model, but it certainly worked much better for those of us that would eventually have gotten it anyway.

Now we get to the part where I sound like an asshole:

I'm not convinced that there is a good argument for teaching the "normal" students. In math, we don't go out of our way to attract people that don't like or aren't good at math. In fact, they usually come to us and say "I'm terrible at math" or "I hate math" and we politely help them with the calculus they need to pass to graduate and send them on their way. Math seems to have accepted its position as a "higher discipline" and while there are those that lament its inaccessibility to the layman, they don't lament that there are so few laymen in class---they just want to be able to show pretty girls at the bar pictures of the beautiful structures they play with all day.

So why can't CS just accept that some people just "don't get" the discipline? It is really hard, you have have a really amazingly large amount of domain knowledge, going all the way up from the metal to the OS and libraries, plus you have to know all this discrete math, understand algorithms of many flavors from many sub-disciplines, and recall it all at once so you can make tradeoffs. A good deal of the theory comes damn close to the math people are so open about being terrible at.

The way computer science works, you get students that love the math and can handle the programming, that stick with it long enough to excel with the programming too, and do great. Then, you get students that love the programming and can handle the math, same thing happens. But right now, you also get the students that hate the math and admit it, and hate the programming but don't feel like they can admit it, so they stick with it until they either drop to Information Science or something, or they graduate and become another one of those programmers that recruiters are always implicitly complaining about when they say "it's so hard to find good programmers".

In math, students who aren't excellent and passionate generally don't even try, or don't continue. That's because all they can do with a bachelor's in math is go to grad school, where they have to be good. In CS, it seems like we think we can send off crappy graduates and, well, if they can't go to grad school, at least they can get jobs programming. Well, wake up. Industry doesn't want them either. Better to help these kids realize they don't like the field and find something they do like, than let them continue busting their asses believing they'll get their dream job just for graduating.

This doesn't mean we should turn people away after the first semester. I like this model: let the kids that are really good skip the intro class(es), and make the intro classes intro classes. This means taking care to think about just how little background you can assume (in particular, assume no math skills, because otherwise they'd probably be math majors). Let this sequence take a year or so if necessary. Redesign the upper-division curriculum to both leave time for this extra intro stuff, and to take advantage of it: don't waste space with "upper-division" classes that are really just there for the crappy students to take so they can have something to do, because you won't have those students anymore. That way, you still be able to serve the average students, but they'll be nurtured at the right pace, making up for the lack of education in high school, until they're ready (or realize it's not for them), which seems to me like a much better model than "sink-or-swim CS 1".

I think perhaps you could consider schools like MIT closest to the idea you're advocating (makes complete sense to me also, BTW). Smaller schools that can't take the cream of the crop by necessity have to teach around the median student or they'd have most of the class flunking or not learning anything.

Unclear. MIT's introductory CS course used to be taught in Scheme, which in many ways was a grand leveler because people who knew how to program imperative languages had to un-learn many things first. It was still considered quite a hard class.

In the new world order, we have 6.00, which is a "learn how to program" class which is not required for computer science majors (and which many non-6 majors take), and 6.01/6.02, which is the introductory sequence that everyone is required to take. The programming segments of these classes are still relatively trivial for someone with a reasonable amount of programming experience. (But I’ll also note the cover a very broad range of topics, and you’re bound to not know some of the other topics, e.g. EE)

The University of Minnesota's introductory computer science course for majors is still a Scheme course based on the SICP book.


Yeah the MIT approach seems oriented towards fundamentals that will be useful in both EE and Computer Science.

To me, the beginning of 6.01 looks like a thorough review of most of the standard programming concepts using Python. I get the sense of "hey here's this tool, we're going to learn to use it. Try and keep up." Once Python and programming are covered, a whole bunch of programming-related engineering concepts are introduced. 6.02 looks to be primarily about networks and signaling and programming seems to be secondary.

That's what I'm saying they shouldn't do: if your intro class flunks a bunch of students, you need another intro class before your intro class. If students aren't learning anything in a class, let them skip it or test out of it. Maybe this is too expensive, I don't know, I'm dealing with ideals right now.

There is a huge gap between high school and college curriculum for many subjects. There is a huge gap between colleges and their curriculum, too.

There are no standards in education with regard to curriculum.

I don't know if they are still doing it, but 12 years ago the University of Maryland had something like this. They had CMSC106 Introduction to C and CMSC107 Introduction to Unix classes that had no credit towards the major, but allowed those interested a gentler introduction to computer science.

What for?

There is no shortage of cs students, and you need to filter them at some point anyway - might as well be with the intro to cs course.

Er, my understanding is that MIT takes the approach that most people should learn to do programming, at least at a fairly basic level.

Maybe, but not via requirements. If you don't take a course that teaches you to code, you're expected to pick it up on your own when you need it (most non-EECS engineering majors end up with lots of Matlab coding experience, for example, but there's no class on using Matlab as such).

When I was there, 1.00 was the "learn how to write programs" class, and it's a Civil Engineering class, not CS. 6.001 has been phased out in favor of 6.01 (unfortunately), and I'm sure as a result there's more "learn how to write programs" since they're using Python rather than Scheme.

There are other classes like 22.00 (also offered under many other numbers), "Introduction to Modeling and Simulation," but again they don't expect to be teaching you concepts like loops and conditionals.

On balance, I'd say most people come out of MIT knowing something about programming (even if it's just Matlab rather than a more general-purpose tool), and a decent portion of those learned it on their own.

How is that unusual? All the hard science, math, and engineering majors had taken at least one class on programming. And it's not like the majority of MIT students end up not majoring in some kind of engineering or science major.

CS majors are going to be bookkeepers, not mathematicians.

I'm pretty sure anyone with a BS in math can get a decent programming and/or finance job.

I've seen absolutely disastrous code from people with advanced math degrees. There were major maintenance problems. (A huge OO subsystem, with no instance methods at all!)

Also a tendency to use single letter variable names exclusively.

Come to think of it -- yes! There would be these wild loops where 4 or 5 variables would be incremented simultaneously by deeply nested code, which would sometimes recursively call slightly modified cut & paste versions of themselves. It was a nightmare!

He was still hired, though.

She. Big company BS. She was foisted on the group.

One thing to consider when drawing comparisons between music performance (not theory) and programming is the market for fresh graduates.

Julliard can afford to be as competitive as it is because the input-output function is a strong bottleneck: You don't need many graduates (for every open violin position in European orchestras, there are roughly 800 graduates), there are plenty of kids who've been playing since the age of 6, so entry is competitive and standards are very high.

Programming? Very different situation. The market demands large numbers of CS grads, and (what the author so condescendingly calls) "natural programmers" are fairly rare. So standards suffer.

I've often wondered how someone would go about becoming a crackerjack enterprise programmer who could A) create a scalable and robust architecture B) design a system that does what it's supposed to do C) design a system that can be extended in the future D) apply the advanced mathematical principles that are at the heart of the most exciting innovations now and D) write it. That is just SO much to learn, I really don't know of any way to accumulate that knowledge without years in the field.

The right question is, what's the proper place to start?

I recommend starting with the math. You won't even know you could think in certain ways until you've been introduced to the mathematical concepts.

On a similar note: The linked post is on how many new students don't understand the fundamentals in only one semester of programming. A counteranecdote is how many hard-science majors pick up programming far more easily than beginning CS students. I suppose the thought patterns for the one help in understanding the other.

I've long thought that there are too few hackers and too many CS students. Nobody can merely just educate people to turn them into hacker programmers but you can give some support in that regard.

First, set the bar high enough in universities/colleges that only people who have that magical natural programmer aptitude and lots of spare time programming experience can make it. Limit investing the precious university resources to that level and above only. This prevents academic CS education from being dragged down and dumbed down because they have to shovel nearly anyone who got accepted through the system.

Then, supplement those who wish to become the CS students but who lack the necessary mind and experience with training courses that begin from zero. These can be private courses or public education available in some other, non-academic institution. If it turns out that, given some experience, some of the trainees actually have the right aptitude then they can collect more experience and eventually apply to the university/college like the rest of the hackers.

Joining this discussion late, but Software Carpentry looks like the solution to alot of these problems.


If their pitch is to be believed, passing this course should provide enough programming competence to begin a CS curriculum.

> Mark Guzdial and Barb Erickson have shown that introducing students to programming by teaching them Python and writing programs that manipulate images and sound

This worked wonders for me, Python, I mean. I was one of those students who had no programming language knowledge prior to my CS1 class, which was based on the C programming language. I was not that bad at things like maths or physics, but I couldn't for the life of me understand how could one write "i++;" or "for(i=0;i < n; i++)", they didn't make any sense to me. I barely, barely passed CS1, but CS2 I failed like a pro. I didn't even try to pass it for a couple of semesters, until I learned Python (by myself) and then everything was smooth and easy. The professor actually congratulated me for my A grade.

I absolutely agree with the idea of improving students' interest and motivation by having them work with multimedia (and I would recommend also, games). The part of my CS classes that I found most tedious was the interminable drudgery of textual input and output.

(Also posted on the original thread:)

I think some of the comments about simpler syntax (moving from Java to Python, for example) are in the right direction, but not far enough down the path. I think the fundamental problem is that of generalization. Someone may intuitively understand how to do a specific task themselves, but how do you take that idea and make it generic enough to be useful?

Programming is communication about how to solve a problem. So let’s skip the whole computer language implementation detail. Don’t start with computers. Start with problem solving. Make the implementation language a list of steps to be performed. Split off people into pairs – have them write down descriptions of how to solve some problem, and then have their partner act it out. You get to talk through parse/compiler errors instead of having to translate something that only really makes sense when you’ve seen it a couple hundred times.

Once people are comfortable with taking a problem and producing steps to solve it, picking up a syntax to say the things they’re already comfortable talking about seems like a much smaller step.

Long term, we’ve got to start doing this earlier. Grade school. Hell, preschool. Why should analytic problem solving be something you’ve got to wait to learn?


Other thoughts while I'm here:

We need to get over the math obsession. Yes, it's important. Yes, deep computer science has lots of math. But you don't teach someone to love music by first trying to get them to understand music theory. Let's cut out the parts that aren't essential. Let's take a lesson from unit testing culture - start with the smallest thing that will work. Big O isn't one of those things. Once people can come up with simple algorithms on their own (remember how great those first little wins felt?), it's a great opportunity to lead into complexity theory. But if you do it too early you'll just scare them off.

Maybe I'm in the minority, but I think everyone has the ability to learn basic programming and the analytic skills that go with it. It doesn't have to be hard. But we've got to start with baby steps.

I'd have been thrilled in college to even have 15 weeks for a CS course. My school had quarters instead of semesters, and I found the density really off-putting (for example, going through all of SICP in 8 weeks).

By the end of your freshman year, you had taken:

CS1005 (which was basically learning C)

CS2005 (Object-oriented programming)

CS2135 (Scheme)

CS2137 (Prolog)

More importantly, when you were taking 2137, you had pretty much forgotten everything you learned in 2135 (as you're basically just perpetually cramming).

If it takes four years to teach a basically proficient student to program at the BA level (which we've seen it does), why would anyone expect to be able to teach a true beginner to the same level in the same time?

Perhaps there could be a special program in which a student spent 1 year intensively studying programming between high school and college. That might be able to bring motivated students into readiness.

Go further-- interested students start music not in high school but in elementary school. By the time they get to college, they've been doing it for more than half their lives, with plenty of time to focus on the fun parts rather than rigor.

I don't think there's any reason you can't teach an interested third grader to program.

He's right, both about the problems and about the lack of alternatives. There are two particularly large practical hurdles to fixing the problem, and I don't know how to solve either one.

The first is the "number of requirements" problem. At most colleges, there is some limit as to how many courses can be required for the major—a practical limit if not an explicit formally-imposed one. A lot has been forced downward into the standard two-course intro sequence,[0] and this has "worked" because some of the students are either brilliant or have had good preparation in high school, where that "two-semester sequence" can be spread out over multiple years, and in many cases is preceded by one or more years of "pre-AP" computer science courses. But the downward migration of material has meant that what we now consider to be a standard computer science degree includes a lot of material, and if we add some sort of college equivalent to the pre-AP courses, we can either add them as explicit major requirements (that some students can place out of), which means removing material from the other end of the major, or leave them as bypassable prerequisites, implicit requirements that mostly serve to discourage students without a high school CS background from taking CS.

The second big problem is the staffing issue. As a practical matter, every course that might get added at the pre-CS1 level will be viewed as an "extra" that has to be staffed, and either takes away from staffing that could be provided to upper-level courses—earning the ire of at least some in the department—or else requires additional hires and thus administration approval. If it is played as "we need this as an additional prerequisite to CS1", it will find an administrative reaction of, "how did you get by for the last few decades, then?" If it is played as "we need this to get some students up to speed before taking CS1", it will find an administrative reaction of, "why are you proposing to teach remedial courses at the college level?" There is also likely to be an uphill battle to even fill the course, especially if you can't get the college to let it fulfill some general education requirement, and then you have the added problem of trying to justify offering a course that is chronically underenrolled.

Adding to the campus-politics tangle of the whole thing, CS is often viewed as too mathy and/or vocational training and therefore viewed with distrust by members of some other departments, making it even more difficult (in some cases) to argue for needed changes.

So, it's a hard problem. Good analysis, though.

[0] Which isn't actually anything like standard, actually, but we still talk about it as if it is. It's at least the case that formerly-advanced topics are now widely present in the first few courses.

My university has unintentionally addressed this problem in a (cough) interesting way. The CS classes are increasingly difficult programming practice for three years, and in senior year we finally get one and a half courses of what I would call "computer science" with an introduction to state machines and algorithms. The people who don't know what they're doing or who don't like to program will change majors within the first two years, and the survivors have become comfortable with programming before they are introduced to the high-level concepts. The obvious downside is that there is little time left in the degree track to teach the high-level concepts, but fortunately MIT's OpenCourseware is there for students who want to continue learning.

Both my local university and junior college use C++ as the introductory language, which I believe makes the high learning curve even worse. (I cheated my way through the introductory course by teaching myself C and arguing that the programs compiled and ran in a C++ compiler, and taught myself C++ later when I was better grounded in the fundamentals.) If it were up to me, the introductory class would be half in Python to teach the fundamental concepts of 'if' and 'while', and half in straight C to teach the low-level concepts of compilation, data structures, and memory management, and the fact that you can implement the same algorithm in different languages. I would wait until a second course to introduce C++ and its inheritance, templates, and operator overloading.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact