Hacker News new | past | comments | ask | show | jobs | submit login
How We Teach Introductory Computer Science Is Wrong (acm.org)
78 points by nreece on March 23, 2010 | hide | past | favorite | 35 comments



I learned to program by reading code others had written. This was way before college. By the time I got to college, I had years of experience reading Perl scripts and very complex C networking programs.

If there's one thing I would fix in CS curricula, it would be to make students read more code. When I was at Apple, I wrote a lot of software to make it easier for Apple employees to read code that other people in the company had written. That software has since been called "the most important thing to happen to software engineering at Apple, ever" by someone who is very high up in the org. chart.

I have written a lot of code, and that has made me a good programmer. Reading a lot of code, however, has been even more important.


When I was at Apple, I wrote a lot of software to make it easier for Apple employees to read code that other people in the company had written.

This idea of improving the reading/understanding experience with software is something I've tinkered with, without much success, so your story intrigues me. If you can say & don't mind, what sort of approach does/did that software take?


It makes sense. Writing prose works the same way. Learning to write is all about reading.

One thing I've noticed is that I like to reread. I get through a lot fewer classic books than many of my obsessive-reader friends because I take time to revisit books over and over. And it occurs to me that this, too, is a key activity in writing: One must read sentences and paragraphs again and again to refine them.


I think pair programming with the beginner at the keyboard is the best thing I've worked with. As part of the student ACM chapter I've organized a lot of tutoring for non-programmers. Walking through my own thought process with the beginner in how to solve a problem seems to help a lot. For example, one thing I had to explain to a student was that figuring out how your program will work is often identical to figuring out how you yourself would do the problem (assuming you can solve the problem). One specific problem we were working involved essentially an itoa function. By using the Socratic method I managed to get the student to explain at the most basic level how they did operations on numbers. Once they got to the digit level, I handed them the well-known division + modular division algorithm for processing the digits of a number and they were able to build the solution from there.

I also think that one of the most important concepts is really poorly taught in computer science. A lot of what we view as "good code" is really just a series of idioms and conventions that we have all agreed upon. As the IOCC shows, there are really no rules forcing anyone to follow these conventions. With somebody looking over their shoulder and saying, you know, we usually express this pattern as this, it basically teaches them what they would have otherwise had to spend hours reading code learning.

That said, I'm not really sure what the best way to teach programming is. The most important thing one programmer can teach another is how to learn on their own, but I really have no idea how to teach that.


My biggest complaint about programming education and text-books is the handling of the 'object-oriented' issue. They throw it at you, at the very start, with zero context. I asked my lecturer what 'non-object-oriented' programming would be, and he couldn't give me a straight answer. A fellow student turned and said 'it's like when you don't have buttons, just prompts' (with an implied 'd'uh!'). It seemed he was confusing the OO paradigm with the 'visual' programming/design paradigm. Another problem is when they teach about encapsulation, they put far too much emphasis on defensive programming and make it sound like there's hackers out to meddle with your classes or grossly negligent colleagues who MUST NEVER see your code; whereas it seems to me the main benefit is 'information hiding' for the purpose of focusing control/interfacing into single points thereby making changes easier (eg. you could have any number of possible mechanisms behind a clock-face but the face remains always familiar to the outside world).

Of course, these are just my opinions as a relative n00b. :)


Object-orientation has got to be the most confused and abused concept in all of technology. Even the experts can't agree on exactly what it means, but that doesn't stop every other dingbat from telling you.


This reminds me of some teacher training I received a few years ago. The teacher was showing us a technique for teaching a new skill to people:

  * First I do it.  (Step one is blah, then we do foo, etc.)
  * Then you help me do it.  (So what's the first step? and then what do I do? etc.)
  * Then I help you do it.
  * Then you do it.
The first part is important: new learners simply watching an experienced teacher applying the skill.


My best CS professors would write code on-screen during lectures (usually in a REPL, or sometimes an IDE).

The great thing about watching them coding "live" is that you can see into their thought processes: which mistakes they make, how they figure out the mistakes and recover from them, exploratory code they write and throw away, the order they do things, how they evolve simple examples into complex programs. You don't get any of that from just seeing the finished product.

It's also great for picking up mundane practical tips, like tab completion, GNU screen, shell history, and how to quickly look up documentation.


Out of my four years of college maybe one professor coded on-screen in front of us, and it was during one of the earlier classes. It's not that I don't appreciate or respect the traditional CS study, but as a programmer, how else are you really going to learn, than to watch a master at his craft?

As I sit here in my last semester implementing a few chosen functions of a small but complete RDBMS for my databases class (i.e. most of the code was written, we just had to fill in stuff relating to a certain topic (buffer management, heap files, etc.)), it makes me wish that I would have seen how the whole system was developed from the first thought processes to the final debugging. That would have been a much better learning experience.


Well I think the issue might stem from the fact that professors in university might not be masters of the craft of coding. I am sure they lost a lot of that mastery while researching their theoretical distertations and what not.

Many who show a mastery in coding are working on the next-big-thing and not furthering their theoretical knowledge.

This is just my thoughts, however. I really have no experience in learning to code in university (2 semesters of intro ECE).


Well I think the issue might stem from the fact that professors in university might not be masters of the craft of coding. I am sure they lost a lot of that mastery while researching their theoretical distertations and what not.

I completely disagree. At least at Northwestern, the systems people know their stuff. You may be right about the theory people, though.


I would say that some of my professors are quite talented programmers. That or the software they use in class has been extensively worked on by many people (including grad students) for years and they have put little into it. Who knows :)


Yes, yes, yes. My favorite programming instructor would often code in front of the class on a projector. Like you I learned a bunch of little tricks, and it also built confidence. If he can write an AVL tree in front of my eyes in an hour then man, it can't be that hard.


I tried this when I taught a programming languages course a couple years ago. I thought it went well enough, but to prevent wasting too much time in class, you should rehearse.

During office hours and personal consultation I would also do live coding with students, but that wasn't rehearsed. In some cases it went really well, in others, it didn't (usually because something would just take too long -- or maybe because it was Scheme). Still, I enjoyed it and I know at least some of the students did.


Consider yourself lucky, I graduated last December and never had the fortune to see any of my professors code on-screen during lectures. It would have been nice for a professor to code on-screen to see their thought processes, given that I started college with little programming experience. Even if I had programming experience coming in, it would have been nice to see somebody else's perspective.

Maybe this should start becoming a requirement of the instructor?


This is related to the effective way to teach kids anything. "C makes a c- sound, like in cat. CAT. Say it with me, CAT. CAT. Billy, what sound does C make? That's right, C like in CAT. CAT. Good job. CAT is spelled C A T. C A T. Say it with me, C A T. Jennifer, how do you spell CAT? That's right, C A T. Good job. Another word with a c- sound that is made by C is CAKE. Say it with me, CAKE. CAKE. Fernando, what sound does a C make? That's right, c- like in CAKE. Good job. Here's another word: CAR. CAR. Linda, what sound does CAR start with? That's right, CAR starts with c- like CAT and CAKE. Jimmy, what letter does CAR start with? That's right, CAR also starts with C. Good job Jimmy."


My Mum is a primary school teacher here in the UK; it's incredibly depressing because, as you say, this is the best way to teach kids... and here in the UK they have basically dropped the learn-see-do and reinforcement techniques. Everything is "approved" worksheets.....


Good technique indeed... I think different people prefer different ways of learning. As of myself, I learn way faster when I see someone doing whatever I want to learn right in front of me.

I do a lot of book-learning to, but I rarely find the SICP-kind of book that clicks on me. So book learning is more informative than practical... So the way I read many books (not the SICP kind, of course), is I quickly devour then and keep most of the stuff in the back of my head, so that when I'm doing the real thing I know what I don't know. After reading in a fast-pace, I try to do whatever I'm reading about and use books as references.


Are you sure you got the order right. The standard pyramide rather goes like: explain people how to do it, help them doing it, let them do it, let them explain to/tutor other peoples how to do it.


Re: examples vs problem-solving: I found that attempting a problem that was beyond me would prime my mind, so that when I read the solution, my mind would grab it. Like an enzyme. Apart from focusing on the relevant aspect of the material, it also provides motivation, and then satisfaction though tension and release. Something of a drama/sales technique.

[EDIT it also combats that feeling of not having learnt anything in 3 years, by giving contrasting experiences of not-knowing and knowing. All humans are intelligent; I believe learning is just a matter of paying attention, which requires motivation and confidence. A sense of progress helps both.]

I tried this on a class when I was tutoring at uni, and it seemed to work well. Students were surprisingly interested in the answers to puzzles I put on the board at the start of each tute, even though I didn't refer to them, and several did extremely well in the subject. Unfortunately, I have no comparative data with other tutes, due to "privacy issues", which averages would have overcome. So much for my dept's interest in teaching quality.


While I agree that this method might help in Algebra/intro to CS, I'm not sure it's beneficial in the long run. The net result is the following set of expectations: you teach them how to apply an algorithm, then they repeat what you told them on the test. This is nothing more than "teaching to the test".

This is, for the most part, how students are taught in high school.

The problem is the following: real life and (if you are doing your job right) more advanced classes don't fit this model. A simple linear algebra example (from my midterm two weeks ago) illustrates what happens when students are taught this way.

Problem: a 4k x 4k matrix M consists of 4x4 blocks along the diagonal, 4x4 blocks on the bottom row, and zeros elsewhere. Find an efficient algorithm for computing M v (v a vector).

    [ M1 0  0 ... 0 ]
    [ 0  M2 0 ... 0 ]
    [ ...           ]
    [ B1 B2 ...   Bk]
The right answer consists of multiplying only the non-zero blocks and has complexity O(k). I gave partial credit for any answer that computed M v. The most common answer I got was "compute the LU factorization." Some went so far as to explain how to use the LU factorization to solve Mx = v. Apparently, I used the word "efficient" when explaining the purpose of the LU factorization, and I used the word "efficient" in this problem.

My students were trained for 12 years to repeat the teachers password. This training failed them the moment they needed to think. It may improve performance in the short term, and it's an easy way to teach. But the long term results are extremely harmful.


Extreme programming could be a better alternative. Have the experienced person solve the problem while the novice types out the solution. It's better than simply reading the solution, because you're hearing the rationale for the lines as they are being written. Writing them burns them into your brain.

Perhaps we can group sophomores with freshmen. The sophomores are tasked with solving the problems and the freshmen are tasked with typing out the code. It also primes the seemingly naturally introverted programmers for group based activity that will benefit them in the long run.


Perhaps we can group sophomores with freshmen. The sophomores are tasked with solving the problems and the freshmen are tasked with typing out the code. It also primes the seemingly naturally introverted programmers for group based activity that will benefit them in the long run.

I think this is an awful idea because the average freshman will learn from the output of the average sophomore, which is not good at all.


This is a technique that teachers use and it can be effective if done right. Of course you have to make sure the "sophomores" know what they are doing. It works for a variety of reasons, including more one-on-one time and the fact that you learn best what you teach (yes, the sophomores will be learning, too).


This idea is called cognitive apprenticeship. A freind of mine will be getting her Ph.D. soon, based on research into this in the realm of physics education. Apparently over there it works very well. One of the big problems with teaching/learning in general is that "experts" (defined as those who know the subject matter well) don't know how to think like n00bs. Seriously -- once you know something fairly well it becomes "simple" because you've gone ahead and rewired your brain. It actually becomes difficult to understand why the n00b just doesn't get it.

Cognitive apprenticeship solves this much like you are describing. The basic idea is that the sophmores will be able to better help the freshmen than the teacher will, because the sophmores are better able to remember their own struggles than the teacher is. Basically, the sophmores are in a state where they understand it the "good way" and also still understand the "wrong way". This puts them in a pretty good position to help.


I think there needs to be a much larger than one year gap between learning programming and teaching programming. It's just too easy to write bad code and not know it, or to think you understand something when you don't (see above OOP anecdote). All those bad habits and misconceptions will continue to rot as they are handed down from one freshman class to the next.

After you've spent years learning, practicing, and mastering a topic and you've tried and failed to find anything more to learn about it, then teach it to others.


At least in my case, this wouldn't have worked at all. Most of the stuff I wrote as a sophomore was orders of magnitude more complicated than what I was doing as a freshman. I wouldn't have understood what was happening at all.


That's okay. It'll be that way forever. I look at code I wrote 6 mos ago and gasp at the inefficiencies. If the freshman finds a better way, all the better -- the sophomore learns more too!


That's not ok at all. You can't toss someone who doesn't understand what a function is into large-scale application development (which is what I was doing first semester sophomore year) and expect them to get anything out of it.

There's merit (a lot of merit) to the idea of pair programming as a way to learn programming. I just don't think the logistics of freshman/sophomores working together are realistic.


I'd argue that you should do just that. Throw them right into the middle of it. Dive right in! I think they'll get a lot out of it. As an intern after my freshman year, I had no idea what a database was, but I was thrown right into it and got a ton out of it.

I have been observing how people learn and how things can be taught effectively. I noticed that the best teachers of a concept are those who have learned the concept most recently. If you've been programming for 20 years, it's hard to empathize with someone who has never coded before. But if you only started coding last year, it's easier to convey the thought processes required to learn the new information -- whatever field of knowledge it is in.

A sophomore can explain the concept of the function to the freshman and in the process learn it better him or herself. It's a win-win.


Course you can!

That's pretty much what we do with new starts where I work. Give them a mentor, get them stuck in, they pick up the basics very quickly and the complex stuff during the few months after that.


A human teacher isn't always available to demonstrate things. How can we duplicate the experience of teaching for people with nothing but a browser and desire?


Aren't there some good books that show an overview of what programming is all about? For example, those at

http://olympiads.win.tue.nl/ioi/study/books.html

include a few quite accessible books (and several more that are very hard).

How about guidance into C via The Art and Science of C: A Library Based Introduction to Computer Science by Eric S. Roberts

http://www.amazon.com/Art-Science-Library-Introduction-Compu...

or guidance into LISP with the famous Structure and Interpretation of Computer Programs (SICP) textbook?

http://www.amazon.com/Structure-Interpretation-Computer-Prog...


The best way for me to study for test was to read through a lot of worked out problems. This works great for the short term, but not for the long term. Retention from reading is a lot less than from doing.

Sure, you may learn programming faster by reading lots of examples and books ... but it will discourage experimentation. You'll only learn what you read, and you will likely not understand it as in-depth.

I learned programming without guidance, on my own. Having to figure everything out with only one or two books and no Internet is an invaluable experience. I really feel that going through that was my competitive advantage.


Law schools should take note, too -- generations of 1Ls have cynically remarked that the main benefit of "Socratic method" teaching is that it allows law schools to maintain a 100:1 student:teacher ratio.




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

Search: