How We Teach Introductory Computer Science Is Wrong
cacm.acm.org
cacm.acm.org
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.
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?
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 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.
Of course, these are just my opinions as a relative n00b. :)
* 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.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.
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.
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).
I completely disagree. At least at Northwestern, the systems people know their stuff. You may be right about the theory people, though.
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.
Maybe this should start becoming a requirement of the instructor?
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.
[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.
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.
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.
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 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.
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.
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.
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.
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...
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.