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.
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."
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).
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 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.
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?
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.
[+] [-] wooster|16 years ago|reply
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.
[+] [-] pmjordan|16 years ago|reply
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?
[+] [-] mechanical_fish|16 years ago|reply
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.
[+] [-] Locke1689|16 years ago|reply
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.
[+] [-] Tycho|16 years ago|reply
Of course, these are just my opinions as a relative n00b. :)
[+] [-] extension|16 years ago|reply
[+] [-] techiferous|16 years ago|reply
[+] [-] mbrubeck|16 years ago|reply
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.
[+] [-] patio11|16 years ago|reply
[+] [-] reginaldo|16 years ago|reply
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.
[+] [-] xtho|16 years ago|reply
[+] [-] 10ren|16 years ago|reply
[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.
[+] [-] yummyfajitas|16 years ago|reply
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).
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.
[+] [-] fnid2|16 years ago|reply
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.
[+] [-] swolchok|16 years ago|reply
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.
[+] [-] sophacles|16 years ago|reply
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.
[+] [-] extension|16 years ago|reply
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.
[+] [-] samdk|16 years ago|reply
[+] [-] jacoblyles|16 years ago|reply
[+] [-] tokenadult|16 years ago|reply
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...
[+] [-] psyklic|16 years ago|reply
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.
[+] [-] dctoedt|16 years ago|reply