Are We Teaching the Best Things?
I'm in Denver right now, mostly to see family. Being the geek that I am though, you know I snuck a little time for the local Rubyists. One of those Rubyists that I was lucky enough chat with is Katrina Owen.
I always love getting a chance to talk with Katrina. She's so thoughtful that she raises the level of discourse and makes me feel smarter. Plus, it turns out that Katrina and I have been thinking about similar things lately.
For my part, I've been thinking about the various students that I've taught to program over the years. I have taught many and because they all learned from me, they learned roughly the same way. What's interesting to me is how different the results have been from that technique. In some cases my students were all set after our lessons and they just began coding up a storm. Other students didn't seem to feel they were ready yet though. They had more of a "Now what do I do?" attitude at this stage.
Katrina raised a similar point from her time teaching in a developer school. When they would get to teaching language basics, they would show several constructs and how they are used. This is similar to how I teach. Just as I have observed, this works for some students. They can just take what they know and run from here. But they also found other students felt a little lost at this point.
The best news is that this isn't the end of the story. Katrina's team does not just give up on these not-quite-there-yet students. Instead, they switch tactics.
This is the key insight, that I feel both Katrina and I have separately arrived at: these students can still be taught program. There's nothing wrong with them. It seems much more likely that our instruction is somehow failing them. Katrina observes that using different teaching methods (which they have incorporated into the initial lessons, of course), they can reach a significantly higher number of students.
What's the huge secret to reaching these other students? I'm not going to promise that I have this 100% figured out, but I feel I've reached a point where I can make educated guesses based on what we are seeing.
I have written in the past about how I feel the Ruby language is a combination several useful programming paradigms. Well, I think a good programming education also needs to pull from multiple areas.
When I have taught programming in the past, I've focused heavily on the language and how it works. Looking back, this seems silly to me. Programming languages are, generally speaking, pretty simple things. Ruby has around 60-some keywords, if I recall correctly. The operators you use at early stages are generally pretty common sense, like simple math operations, or easy to understand needs for what what you are trying to accomplish, "How do I jam these two strings together?" Sure, it'll take some time to learn all of the functions/methods in the core of a language, but you can make decent progress with a small subset and you probably don't need a teacher's help to pick up most of the rest when you're ready. I do realize that languages have plenty of rabbit holes you can get lost in, but I think most of those can, and should be as much as possible, avoided at the earlier levels. In summary, these language concerns obviously play a role, but this may not be the most significant piece of the learning to program puzzle.
I would say there are two more significant challenges to picking up our particular craft. First, you have to spend quite an effort to learn how think like a computer. Let's face it, computers are really dumb. When I was in school we had to do the exercise of writing down a set of instructions for making a peanut butter and jelly sandwich, which our teacher would then execute as literally as possibly. If you wrote, "spread jelly on bread," the teacher might grab the still-closed jar of jelly and roll it back and forth over a bread slice. Experienced programmers know that teaching machines is exactly like that. They don't make any intuitive leaps and they always do precisely what we told them to. Learning to program is, in part, a process of learning how to specify all steps algorithmically at a ridiculous level of detail. This is the only thing machines understand. I suspect this is the major reason long-time programmers can pick up new languages so quickly. Once you've dumbed yourself down to the level of the computers, putting a communication layer on top of that process is fairly easy.
There's another element that I suspect contributes heavily to the differences we see in students. It's common to hear claims that programming involves a lot of math. This use to bother me because I felt it gave the impression that you would need to be pretty sharp with trigonometry or calculus to build a Web application. This is just not the case. However, there is a very important concept that math and programming do share: how to solve problems. This is a big deal. Knowing how to break down a challenge into manageable chunks, knowing how to select a good starting point for your efforts, knowing how to work your way from where things currently are to where you need then to be, and knowing how to validate results are key to what we do. This is the beating heart of programming and I rarely see it taught with our languages. Some students come to us already familiar with how to do this stuff from other training so it doesn't hurt them as much when we gloss over it, but it's still a shame because we probably miss good opportunities to put programming specific twists on this process.
There are almost surely other key skills tied to programming that I haven't listed above. These are just some I feel pretty confident that we need and that may not be receiving enough instructional focus. I believe one thing is pretty certain at this point: programming isn't just about learning a language. I highly doubt that's even the most interesting part of learning to program. Our lesson plans should reflect this.