As many of you probably know by now, my day job is programming computers. A year or so back, a non-technical friend, having got that question out of the way, followed up with "so what does that mean, then? What do programmers actually do all day?" This occurred at about 1am, and I wasn't exactly sober, so I did what any other programmer would. I babbled incoherently.
The question remained with me, though, and it's become clear that the answer is far from obvious to many people. So here's a slightly more detailed answer for interested non-techies.
What is Programming?
At the most fundamental level, computers are only really capable of performing simple processing of numeric information (arithmatic, comparing numbers, shuffling numbers from one place to another). Doesn't sound very useful, does it? However, computers can do this processing very fast indeed.
The individual operations may be trivial, but a few thousand of them can add up to something useful. The main processor of a modern desktop computer can do billions of simple things per second. That desktop computer also has several specialist sub-processors to handle specific tasks like manipulating the images you see on screen, reading information from disk, or generating sounds.
Every "thing" that a computer manipulates has to be described as numbers. As you read this on screen, somewhere deep in the guts of your computer is a group of numbers representing each and every letter. There are numbers representing the buttons on your web browser window, the state of each key on the keyboard, the time of day, and everything else the computer is keeping track of.
As well as all these numerical models, a computer has a set of instructions telling it what to do in certain circumstances. When you click a button on your mouse, or press a key on your keyboard, a number changes somewhere in the computer. The computer has (hopefully) been instructed to watch that number, and do stuff when it changes. Of course, that's where programmers come in. We decide what numbers mean what. We write the instructions.
Easy, right?
How To Make A Cup Of Coffee:
- Put coffee in cup
- Put water in Kettle
- Boil Ketlle
- Put hot water in cup and stir
There's a problem here, that most programmers learn pretty quickly: when you get right down to it, computers are DUMB. Really, spectacularly, mind-meltingly dumb. They can't think, they can't guess, and they don't actually know anything. They don't know what a cup is. They don't know what a kettle is. They don't know how to fill or boil the kettle. They don't know what water is.
The core of a programmer's job is to design the numerical models that the computer manipulates, and write instructions telling the computer what to do with them.
So you tell the computer what all these things are, give it the instructions, and set things in motion. This is where all the fun starts. You've probably encountered stories where a foolish mortal makes requests of a genie/demon/two-year-old child or similarly malevolent being, which then gleefully mis-interprets the instructions in an amusing and/or morally educational manner. Well, that's what computers are like.
Computers, while dumb, are very good at following instructions literally. They rarely make "mistakes"; in fact they reliably do exactly what they've been told to do, and remain completely oblivious to the fact that it's all going Horribly Wrong™.
How To Make A Cup Of Coffee:
- Put coffee in cup
- Put water in Kettle
- [...]
(Having the rammed the coffee jar into the cup, breaking the cup in the process, the computer is now pouring more water into an already-full kettle, soaking the kitchen.)
The instructions given to a computer must be absolutely precise, with no ambiguity (oh, you meant the stuff in the jar). The instructions must recognise and cater for unexpected circumstances (the kettle is already full) - if they don't, then the computer will try to do what it's been told to anyway. This might cause an obvious problem immediately, or it might cause more subtle difficulties later on.
One of the greatest challenges of programming is working out, in microscopic levels of detail, exactly what it is that you are trying to get the computer to do. If you forget anything - some tiny wrinkle of ambiguity, or a rare situation which needs to be handled differently - then your instructions will be flawed, creating a bug in the program. Indeed, this is how almost all bugs occur - a failure of imagination on behalf of the person writing the set of instructions.
Once you've worked out what you're doing, you write the instructions, in a form that the computer can understand. Actually, nowadays, it's far more common to write the instructions in a form that can be read by a computer program (known as a compiler or interpreter) which then translates the human-readable instructions into machine language, so that us humans don't have to curdle our brains trying to think purely in numbers (been there, done that, not fun).
At this point, the spectre of the over-literal computer returns to haunt us.
How To Make A Cup Of Coffee:
- Put coffee in cup
- Put water in Kettle
- Boil Ketlle
- [...]
What's a "Ketlle"? Oh, you meant the Kettle! Well, why didn't you say so then?
The old tales about missing minus signs causing moon rockets to go astray are dead on. In computer programs, typographical errors are downright dangerous. Which is a bit of a problem, really, given the fallibility of programmers. Fortunately, the translation programs we use can spot most typos fairly quickly, long before they get installed in real moon rockets (or, in my case, web servers) but the odd one still escapes into the world to wreak havoc.
Even with all these wrinkles, it still sounds fairly straightforward, and in some ways it is. A program is a "structure" of information, a set of instructions. In many ways, writing a program is similar to designing a physical machine. When the computer loads the program ("design"), it will construct the "machine", start it up, and feed it "raw materials" (all those numbers describing something useful). If all goes well, something useful comes out the end. If not, we get 47 zillion three-fingered left-handed gloves. Or something.
So, what do I do all day?
I design, construct, test and repair information structures, which exist purely to control and direct very-fast-but-very-stupid numeric calculation engines. In practice, large chunks of my time are spent discussing the fine details of what the customer actually wants the program to do, working out what the blasted thing is actually doing, and figuring out how to make them line up. We do other things, too, mostly centred on keeping track of what everyone on the team is doing and preventing any mistakes from affecting our users.
Overall, it's a job that needs a logical mind, attention to detail, and an ability to keep track of lots of things at once. Experience counts for a lot, particularly in terms of learning what can go wrong, what the resulting symptoms look like, and how to prevent such problems in the first place.