There’s an appreciable risk that this post may be considered sacrilegious within the programming world. If there’s one thing, even just one tiny, single thing, that every programmer knows about teaching programming, it’s that the first lesson should be how to output the string, “Hello world!” (There’s some dispute as to whether the ‘w’ should be capitalised but the ‘!’ is entirely necessary.) How heretical would it be to suggest that, not only is this probably not the best place to start, but that a better alternative can be found by turning around a bottle of shampoo?
In truth, of course, “Hello world!” does have a lot going for it if the intention is to learn a new programming language. It does what it says on the tin and everyone knows what whatever’s in the tin is supposed to do in the first place. It’s a reliable introduction to Input/Output (I/O) in a new syntax (Java, Scratch, C#, Assembler, etc.) or a particular environment (Console or Windows Form mode, for example). It’s also a first exercise in how to enter and compile (say) code and how to switch between development, debugging and output modes. On the other hand, it really isn’t the place to start for a complete beginner, who’s probably not going to make any of these distinctions.
Our ‘very-first-ever programming session’ needs different guidelines. Firstly, the challenge in getting programming across to a new audience is a conceptual one, not technical. Secondly (and we’re much better at saying this than actually doing it), this ‘computational thinking’ thing we’re so keen on should be more about algorithms than syntax. There’s no absolute definition of this (although a fair amount of confusion between exam boards) but the kinds of ideas we’re looking to instill in novice programmers would be something like the following:
- Computers (although ‘Robots’ is more fun) follow simple steps to get things done
- A combination of steps (including maybe some choice or repetition) makes an ‘algorithm’
- Generally, we have to provide these steps – the algorithm – to the computer/robot
- The computer/robot will do exactly what we tell it to; there’s no scope for relying on its ‘intuition’
All this leads very nicely to the back of a bottle of shampoo. Of course, this will vary from product to product but the following, fairly typical, version is a wonderful introduction to the notion of an algorithm, first and foremost because it’s such a terrible one.
(It’s best not to number the steps at this point – that may or may not happen later.) Give this to a group of would-be programmers and get them to work it through. (Explain individual steps, such as ‘Lather’ if necessary.) Depending on the delivery format, they could work individually or in pairs or groups. Depending on ages, they could read it to each other; one could be ‘the program’, another ‘the robot’. They could draw cartoon story-boards or physically act out the steps, etc. However you introduce it, make sure they follow the steps exactly. You or another group member may have to act as ‘the enforcer’ to make sure they don’t apply any intuition.
It doesn’t take long to realise that the algorithm, if they try to follow it precisely, leaves a lot to be desired. The first four instructions are fairly harmless but the fifth presents problems to a literal mind.
- Repeat what?
- Repeat how many times? (Whatever we decide to repeat, we’ll come back to the ‘Repeat’ step again … and again)
Let them discuss the different scenarios, working them through as appropriate. Let them see that they might be wasting time or never stopping. Once, it’s accepted that this isn’t a great algorithm, discuss what it’s probably meant to mean and whether we might realistically expect a computer to understand it that way. Consider the different ways there could be of interpreting it. These are suggestions only:
- In an abstract sense, if the computer has to make a logical interpretation of what to repeat, common sense would suggest either ‘everything’ or ‘just the last thing’. In other words, either go all the way back and wet hair that’s already wet or simply rinse hair that’s already rinsed. There’s absolutely nothing at all logically obvious about returning to the second step; that only makes sense to us because we intuitively know what the program’s meant to do.
- There might be some common sense in ‘repeat once again’ to wash our hair twice but, taken with the first point and remembering that we then hit the ‘Repeat’ again, it’s not obvious that it has to be like this. (Remember to consider it from the computer’s point of view. ) Anyway, suppose we wanted to wash our hair three times. Why does ‘Repeat’ have to mean ‘once’ or ‘twice’ or ‘for ever’. It could reasonably mean any, all, or none of these things.
If there’s general agreement on the algorithm’s flaws, the next step is to consider what’s to be done about it. (This might be for the next lesson if sessions are short.) How can the algorithm be improved to get rid of the uncertainty? Again, depending on the format being used, get them to re-work, re-enact, but ultimately re-write the algorithm to be more precise. Tell them they can do it any way they like. Observe closely to see what solutions develop and talk through where it helps.
There are an astonishing number of solutions that arise, although two or three tend to dominate. Some groups will naturally extend the solution beyond the fixed two washes (and will often allow just one). This notion that solving a general problem can be easier and more useful than solving a specific one is actually a fairly advanced concept but there’s no harm in throwing it in informally here. What’s particularly interesting (although obvious in a sense) is that each (broadly ‘correct’) suggestion will align to one or another programming model or paradigm, even a specific language in some cases. It may or may not be a good idea to drop these observations in at this stage and could depend on the actual language you’re on the verge of introducing. (“Hey, that’s cool. That’s how you’d do it in Pascal”, will be of little more than passing interest if you’re just about to start a Python course, for example.) What’s important is to consider what’ll work and what won’t. There’s no particular need to discriminate on the basis of efficiency or elegance at this point.
(Note that the actions can be simulated in simple output in various ways such as the Scratch example below.) There has to be repetition and selection in any solution that will actually work (although the selection may be implicit in the loop) so, along with the basic sequence in the steps, you have the three essential algorithmic components, right there in a few lines. It could be argued that sequence/selection/repetition is too much for an introductory lesson but that’s not the point. The finer detail of conditional statements and loops can wait until later; this is simply an introductory case study in turning a problem into a solution. Actually putting right a poor solution along the way just gives it that little bit more relevance into the bargain.
You could stop at this point with a job well done. A final step however, assuming you’re working towards a particular language, would be to highlight a solution that’s reasonably close to the structure (possibly syntax too, although this is less important) of the target language and focus on this. Perhaps refine the solution a little to be even more recognisable in terms of the language itself? Then open up the development package you’re going to use and show them it working ‘for real’. A real first program – one that actually solves a real problem, or at least gets a real job done.
With a bit of luck, the would-be programmers will now have a bit more awareness of what’s needed in terms of algorithmic rigour. They’ll be thinking computationally about problems and solutions and they’ll have seen a working program that they can see the point of. Hopefully, they’ll be a little more tolerant of the dry syntax that’s on its way, difficult to entirely avoid, because they’ll appreciate the need for it and what goes wrong if it’s not there. Now, it might be appropriate to take a deep breath and restart with something simpler …