Teach Concepts Not Just Code
Written by Mike James   
Thursday, 31 August 2017
Article Index
Teach Concepts Not Just Code
Math, Not Arithmetic

What tends to get overlooked when discussing STEM skills is that we need to teach algorithmic thought in the same way as needing to teach math, not just arithmetic. What you don't know the difference between math and arithmetic? You're not alone and even many programmers don't know the difference between code and algorithmic thought.

Computer education seems to have been in the headlines for the last few years, for one reason or another. In most cases what can you say except "good", and perhaps "about time". Or perhaps you think, like many that coding is a menial low level skill that shouldn't be taught to children of any age unless they are going to be cubical drones the information ages equivalent of the manual worker. 

The idea, and one I subscribe to, is that we should all learn to program and this would make the world a better place.

I'm not saying this just because I program. A widespread ability to apply algorithmic thought processes to any problem not just when working on a program is a good thing. Instead of just having a vague idea of how to approach a problem or project, the algorithmic mind puts together a fairly exact plan and also knows where the difficult bits are. Programming isn't the only skill that teaches algorithmic thought, math does for example, but it is more direct than most.

I have written before (What makes a programmer) about the simple fact that programmers often don't realize what their skill actually is. It is too easy to confuse what we do with the details of code, languages and data to be what programming is all about.

It is about code, but it is just the surface representation of what is going on deep inside. These inner workings are usually not discussed because they are not really of practical concern. Yet they are vitally important if we are to teach non-programmers how to program. (James, 1979).

One of the big problems we have with the programming education revival that is going on is that quite a few proclaimed experts on teaching programming are actually just expert programmers - and the two things are very different.

Doers aren't necessarily good teachers - in fact there is a fairly strong negative correlation between the two, even if it is only in popular opinion.A good "doer" will often approach teaching as a "just do what I do" task. As most people who are good at something how they do it and there will often be a long silence. This doesn't mean that there isn't more to it than just mastering some skill by repetition and practice.

If you have just learned your first language - Java or JavaScript say - then you immediately conclude that you have made it. You are now a programmer. This is, indeed the case, but being able to program isn't the same as knowing how you do it.

Imagine that you have spent a few months learning to juggle. You can do it, but you might not know how you do it. In this case, when it comes to teaching someone else to juggle, knowing how you do it isn't much help. But when it comes to programming it is vital.

When you learn to program something magical happens inside your head.

You get a model of algorithmic processing, and this model has a life separate from the syntax, and even the exact semantics, of the language you just learned.

This is easy to prove because if you go on to learn a second and a third programming language you will learn them faster and you will identify commonalities that are surface expressions of the model inside your head. You have a way of thinking about problems that enables you to express solutions or even attempts at solutions in code.

As soon as a problem is presented your brain starts to put together algorithmic fragments as if you were clipping bits of model railway track together to get from the problem to the solution.

This is also the reason why it is just fine to use graphical programming languages like Scratch to teach programming. You can absorb the skill of planning and building an algorithm using clip-together blocks just as easily as writing code.

However, there is one important skill that isn't readily acquired using graphical programming languages and this is the ability to  transform the flow of control from how it might be in you head into a textual left-to-right top-to-bottom flow.

For example, you can show a beginner a diagram for a conditional that has two alternative branches of instructions running parallel:




Then you can show them the classic if..then..else construct where, of course, the two alternatives are not set out on the page next to each other. The then comes first and  below it the else follows. A very common error for a beginner, is to mistakenly think that the else part is executed following the then because this is the usual flow of control.




It takes time to learn to build an algorithm in your head, and it takes even more time to learn to express that algorithm as a textual coding. These are two separate skills.

Programming is about converting dynamic processes into static text.

This skill is relatively independent of the language used for the text. We generally don't teach this skill directly but use a language as a way of showing how it is done. This is reasonable but what is not reasonable is to ignore what is being learned and not point out the this is more than just the language being learned. You may be learning the JavaScript for loop but all but the strangest languages have some sort of enumeration loop.

Building blocks as algorithms

As you continue to program you also start to see small chunks of algorithms that are fundamental in the sense that before you understood them there were things you couldn't do but after it's all so easy.

I can give you an example but if you already program you almost certainly have encountered these ideas before and won't be very impressed. What you have to keep in mind is that for a complete beginner this is all non-obvious. And if you don't believe me try teaching a complete beginner and take note of what they have difficulty understanding.

For example, after you have learned about loops as a way of repeating code, it is generally only a short time before you add to your pack of tools - the "sum loop".

Do some condition
End Do

Beginners may well have encountered the idea of a loop that repeats instructions and they may have mastered the idea of a variable and how it stores a value. But when you put the two ideas together in this particular way, what you get is something special - its almost emergent behaviour.

This is a loop that counts how many times it repeats. Don't belittle it - this is a real breakthrough in thinking about algorithms.

In fact even the increment by one instruction is a breakthrough. If you don't believe me watch any complete beginner struggle with it at first and then ignore it as if it was obvious common knowledge a few hours later.

The sum loop can be elaborated to:

Do some condition
End Do

which is an accumulating sum or a reduction process.

Again, don't think that this is trivial; it is a loop that keeps a running sum and you only really understand the term "running sum" because you can program.

If you want to just put yourself in a slightly alien place, consider the product equivalents of both loops. Here you find something a little more unusual that might just manage to remind you how clever you were to have absorbed these ideas.

If you are still not impressed at how clever you and all programmers are consider the simple fact that the sum loop is equivalent to the mathematicians Sigma notation:


and the product is the equivalent of the Pi notation:


It is worth pointing out that even though there are similarities, math is not programming and vice versa. Programming has an element of process and time that most math does its best to ignore. Math consists of static truths and in programming nothing is static.

So how do you use all this to teach programming?

Last Updated ( Thursday, 31 August 2017 )