Learning Programming

I’m interested in how people learn to program. Over the past few years, friends or relatives have asked me about resources for learning to program for themselves or for people they know. I’ve collected and refined that advice here. It’s hard to know what approach will work for someone to learn to program. It’s hard work so it’s important that each step be interesting and rewarding enough to keep going particularly when there’s no external force such as formal courses.

The best approach I’ve found once the very basics of programming are understood is to have a problem to solve. The best kind of problem is the kind where progress can be shown after each session.

It helps immensely to have one or more people available (locally or online) to act as mentors. It’s also important to have an audience which may or may not be the same as the mentors.

Learning to program is learning several things:

  • Thinking logically and procedurally — computers do exactly what they are told do. Decompose the desired “experience” down into smaller, programmable chunks that can be captured as code. Tools make a difference here by deciding how high level the “commands” are and thus how much of what the machine is doing is hidden by an abstraction. Starting with high level abstractions is helpful because modern environments are ludicrously complicated and getting from anything resembling the “bare metal” to “something that does anything interesting” is a very big leap all at once.
  • Demystifying the computer. The “ah-ha” moment when it becomes clear that all the things a computer does are programs that someone decomposed into smaller sets of steps and implemented.
  • Distinguishing between “how to program” and “how to program in this environment”. The syntax, tools, and library for the environment de jour are important but understanding that programming environments come and go and different environments may be suited to solve different problems is important. A student learning his first language is learning programming at the same time so it’s not yet clear that “the environment” and “the skill of programming” are different. Picking this fact up early in the journey to becoming a programmer will help immensely.

The first approach to learning to program is to set out to learn to program as a goal in itself (or a step along the way to a goal e.g. first-year computer science students). The environment used for this approach isn’t too important as long as it’s relatively easy to get started.

There’s usually some steps or exercises to follow that each introduce some concept and then some projects to tie the concepts together. Usually (but now always) this approach solidifies the separation of the programming skill from the language and environment because many “learn to program” since frequently the next problem the student wants to solve is going to use a different environment — either because the next course uses a different language or because after learning to program the student gets excited about a problem that requires a different toolset than the teaching environment.

The second approach is to have a project in mind to solve and to try to learn how to make it happen. This can be combined with the first approach — using the first approach to understand the basics and then moving on to the second approach to get to the “next level” of making something interesting and rewarding. It can also be combined with the first approach by first attacking the problem at hand and hacking something out (e.g. modifying an existing mod to do something slightly new) and then after that victory stepping back to learn to program with some more rigor.

The problem domain will help guide the choices of language and environment. Some examples:

  • A modification to an existing game (many games have programming environments built in and some come with dev tools). For example, writing a World of Warcraft Add-on, or making a map for a first person shooter and then adding new behavior. Many PC games are modable.
  • Making a robot or other embedded system to do something cool
  • a web site to track or mash-up resources or something
  • A Firefox extension or Greasemonkey script
  • …and so forth.

Fortunately there will usually be some resources available aimed at not-yet-programmers that want to get started with some kind of project because a lot of people get started with projects in mind.

Some resources:

Update: I’ve added links contributed by commenters to some Ruby resources. Thank you!

Learning to program:

Environments intended to make creating things that do something interesting and are programs in a guided or easy way, some of which may be applicable to the first “project in mind” approach for learning to program:

The last obvious environment to learn is HTML and JavaScript — lots of interesting interactive things can be done entirely locally in a browser. It’s probably too complicated a canvas to start with without a specific project or series of exercises in mind, though.

Having an audience is amazingly helpful. I remember when I was learning to program that inflicting my (in hindsight) pretty lame programs on nearby people and having them react appropriately was important in terms of positive reinforcement. Programmers are frequently motivated by both the “ah ha” moment of making the computer do their bidding and by the reaction of an audience like any inventor/creator. Solving problems people care about (including “I have some time to kill, what would be fun to do with it”) is the obvious next level after showing off some sort of toy demo.

It’s important to find a path where the student can see something “go” in relatively small, quick steps. That “WOO!” when the thing works is what keeps programmers slogging through all the hard bits, so it’s pretty key to pick early projects where that can happen before burnout/frustration occurs. There’s a lifetime to master programming but only so many opportunities to get excited about it before one writes it off as “too hard” or “boring”.