Guideline 9: Programming for the many, not the few

Decorative image showing "Guideline No 9"

Over the last week or so, I published here eight guidelines for teaching programming. This last one is not so much a guideline, as a guiding thought. The first eight were reasonably concrete tips about how to (or not to) approach the teaching of programming to novices. This one just illuminates one aspect of our teaching that may be helpful to hold in the back of your mind to guide your general approach to the content you decide to teach. It has to do with how initial programming teaching has changed over the last 20 years.

When I started working in teaching programming to beginners, the target audience we had in mind were first year university students. This is where programming learning really happened.

It is not now.

Today, almost every learner encounters some form of programming long before university, at some time during their school age. The migration of initial programming teaching from universities to schools creates a big shift. The difference is not primarily that learners are younger, but that they have different goals.

When we started to move computer science teaching into schools – initially into the last few years of a curriculum – the content was almost universally derived from introductory university courses. Mostly, teaching at school was a direct copy of teaching at university.

Now that teaching of computing has migrated down the years, is taking place sometimes in primary school, and in earnest in early secondary school, this makes no sense anymore.

The goal of the teaching of programming in a university computer science degree is to educate potential future software engineers. The learners had chosen a career in computing, and professional software skills are an essential part of that education.

In early secondary school, we teach programming to all pupils. Not just the ones who go on to work in a software profession, but all of them.

We should be very aware that the goal is not to train software engineers. Most of your class will never work as a professional software developer.

When we shift from training computing professionals to educating the entire population, we need to adjust our objectives. Learning professional software engineering practices is no longer the main goal. Gaining a deep understanding of the power and limitations of computing systems in general is. Grasping how computing impacts our life, the possibilities and dangers of modern computing systems, the potential for creativity, for science, for social change.

Understanding how the world can be modelled digitally, the transformative power that results from this, the limitations and dangers, the joy, the potential – that is the goal.

At secondary school, we are trying to create educated citizens in a digital world, not software engineering professionals.

Keeping this thought in mind when planning your teaching helps to provide guidance in judging the importance and value of different elements of content in the curriculum. It can help you decide what to emphasise, and what to leave as challenges for the keen few.

That said, programming is still best door to enter the magical world of computer science. It gives us concrete and immediate experiences of the power and joy that can be had by creating something out of nothing. It is wonder-ful in very sense of the word, and lays the foundation for all else that comes afterwards.

Guideline 8: Use A Spiral Approach

A decorative image showing the test "Guidelines for Teaching Programming" and the number 8.

One common mistake (and yes, I think it’s a mistake!) that I often see in teaching (and especially in textbooks) is to try to be exhaustive too early. When it is time to mention, for example, data types, you have to say all there is to say about data types. Or if it is a textbook: since this is the chapter with data types, it has to have a table of all the types and all their operations.

Since types are needed early, this lesson/chapter comes early. Perhaps a pupil only needs to use a number and a string, but suddenly they hear everything about floats, booleans, chars, type conversions, widening casts, and whatever else there is to say about the intricacies of type systems.

The problem is that learners do not know which bits of the information is relevant right now, and which isn’t. It’s just stuff.

The result: The relevant information is lost, the budding programmer is overwhelmed, learning is rote (and therefore boring), and no one but the author is happy.

The thing to do instead: Use a spiral approach. When encountering any concept for the first time, say only as much as is needed to get the task done. Get learners to get a result on screen without overloading them with detail. Then return to the topic again (and again) over the next weeks, each time deepening the discussion and understanding.

There are several benefits to it: First, you avoid adding cognitive load for no (immediate) gain. Let pupils concentrate on what is needed. Second, you get to the fun parts more easily and quickly. And thirdly, linear instruction doesn’t work in programming anyway. Constructs in any modern language have circular dependencies, and you cannot fully explain everything in a single sequence.

By revisiting concepts multiple times, you can get to interesting results quickly, deepen understanding as learners develop, and discuss influences of specific language constructs on others, pointing out the (circular) dependencies of one language design element on the others.

Guideline 7: Creativity (or: Open & Closed)

Decorative image showing the text "Guidelines for Teaching Programming" and the number 7

Many teachers think that the main goal of programming instruction in early secondary school teaching is to make pupils understand computational thinking, algorithms and the writing of programs.

I think this is wrong.

The main goal, at this level, is to get students interested.

What I most want from early programming instruction is to get pupils excited, having experienced the creative potential and expressive power of computing, and wanting to know more.

The best way to achieve this is to support creativity in the learning of programming. Supporting creativity means finding ways to let pupils take control, to let them add their own ideas and extensions, to allow creative experimentation and expression.

Allowing creativity is not always easy: You should use creative examples, such as stories, games, art, animations or simulations. These are areas of expression that allow pupils to shape the content. You need a programming environment that supports this (more on this later).

But also: you need to structure your projects to make this possible. The way to do this is to use what I call the Open/Closed principle: The assignment you give your students should be simultaneously open and closed.

What I mean by this is this: The task should include a core component with the expected minimum achievement that is well specified and carefully scaffolded. This is the Closed part: it allows the less secure and less adventurous students to concentrate on the core material in a guided environment, and supports them to succeed.

But the task should also include an Open part: a challenge to extend the project in various directions of interest to the learner, to invent, to experiment, to stretch. This allows the keen learners to take control, to make the project truly theirs, to excel and to show what they can do.

An example might be a game where you specify core functionality that everyone is expected to implement, but challenge students to add their own extensions and personalisations.

I will come back to how exactly to do this later. But for now, the takeaway is: The most important goal is to let pupils become creative, so that they experience the power and joy that writing programs can bring, the joy that we have all experienced, but that is so impossible to express in words.

Guideline 6: Illustrate the process

Decorative image showing the text "Guidelines for Teaching Programming" and the number 6

One common pattern of programming teaching – especially in books and other written material, but also in in-person teaching – is the focus on the product, rather than the process.

The usual structure is: (1) Here is a problem. (2) Here is a program (involving some new construct) to solve the problem. (3) Here is a discussion/explanation of the solution and the new construct.

The problem with this is that the solution appears – apparently in one step out of the ether – in its entirety.

In novice learners, this creates the impression that this is how experts work: If you know how to program, you will be able to think for a moment, and then just write down the solution.

They struggle with coming up with a working program, and even if they have an idea, they make mistakes, run into compiler errors, have bugs in their code, and think “I am just not a good programmer”.

The fact that we all work like this – write some code, discover mistakes, correct, change our minds, slowly build – must be one of the best kept secrets in programming.

For you as a teacher this means: Don’t just teach your pupils what the correct program looks like, teach them how to get there.

Guideline 5: Show program structure

Decorative image showing the text "Guidelines for Teaching Programming" and the number 5

In much of programming teaching at school level, the discussion revolves around syntax and statements. I realise that – with young learners – mastering a loop is initially a challenge. But the statement level (and especially syntax) is neither the difficult, nor interesting, nor important part of programming.

Every pupil will learn to write an assignment and an if statement. This is not where the difficulty lies, nor where the important concepts, which we want our students to understand, are illustrated.

The most important part of learning to program is abstraction, and its incarnations in structuring a problem, conquering complexity and guiding our thinking.

In object-oriented languages, this is embodied by classes, objects and methods. In procedural approaches, it manifests in procedures and functions, scope of data and separation of concerns.

It is important to visualise this structure early and often. In the best case, use a programming environment that provides the structure visualisation. Use an environment that de-emphasises syntax, ideally removing the need to memorise where it can.

If you don’t have an environment like this, do it yourself: draw diagrams on the whiteboard. Do what works, but TALK ABOUT STRUCTURE.

The challenge of learning about statements will become meaningless. The challenge of designing program structures will remain – it is an intrinsic part of being a programmer and computer scientist. Make this the centre of teaching your students good programming practice.

Guideline 4: Don’t use “Hello World”

Decorative image showing the text "Guidelines for Teaching Programming" and the number 4

I am now skipping two of the guidelines from the paper, because they are specific to object orientation, and I would like to first concentrate on the general advice. (I might come back to the OO advice later.) Therefore, our Guideline 4 here is actually number 6 in the paper. It tells us not to start with “Hello World” as a first example.

The main problem with “Hello World” (or the only marginally more interesting “Hello <NAME>”) is that it is just so boring!

If you want to show a 15-year old why they should be interested in programming as a discipline, why on earth would you do THIS? Felienne Hermans, in a recent article, described her experience in teaching beginners where a pupil commented “If I want Hello world on the screen, I can type that in Word.” (1) And that student is quite right!

The problem is not restricted to Hello World. When I was a student, we were told to write a program that prints out all the prime numbers from 1 to 100. This is a boring example. There is so much wrong with it.

Firstly, it’s Maths. Maths immediately puts off 80% of your class.

Secondly, if you really wanted to know the prime numbers up to 100, what would you do? No, you would not write a program for it. You would google it. It would take you about three seconds and bang! – there they are. Using a computer to solve this problem is entirely artificial. It makes nobody understand why you would want to learn to program.

Thirdly, the program is finished when it prints exactly what I knew it would print all along! To test my program, I would work out the complete answer myself, and then confirm that the program does it. You learn absolutely nothing from running the program. You might learn the program statements, but not why you would want to write them. It excites no one.

And fourthly, imagine a pupil is really quick, finishes the exercise after five minutes, while everyone else is just getting started. What do they do then? How can they stretch, extend, be creative? Add their own ideas, and grow? Print out the primes to 200?

The problems is that, once the program has run, there is absolutely no reason to ever run it again. A program that you do not want to run twice is not an interesting program.

So my advice is: use examples of programs where you actually need a computer to do the task! Games and simulations are such examples. Visualisation of data, or graphical animations. Use examples that give learners immediate ideas what they want to add!

Of course, you need an environment that supports this, and makes it easy enough to do this from your first hour of teaching. But these exist. Use them!

Every time I see another “What is your name? Hello Michael” program, I could tear my hair out in frustration at how far we have not come.


(1) Felienne Hermans: The Story of Building Hedy: A Programming Language with Cognitive Science in Mind, Informatics in Education, Volume 23, Issue 4 (2024), pp. 791–822

Guideline 3: Read Code

Decorative image showing the text "Guidelines for Teaching Programming" and the number 3

The third guideline of teaching programming is to read code, lots of it, and early.

I have already talked about this in Guideline 2, which was about not starting with a blank screen. While Guideline 2 was aimed primarily at avoiding the empty-screen paralysis (and discussed code reading as a side issue), this one is explicitly about the importance of code reading as a skill, and not limited to the first example.

Many programming courses concentrate solely on code writing, and assume that – somehow – code reading will follow. Either it is assumed that this is an easy skill that exists automatically, or that it is acquired by osmosis somehow. More often teachers do not think about this much at all.

Code reading is, in fact, a valuable and separate skill that should be practiced. And it should be practiced early, since it is of great value to learning to write code.

For the first few projects (spanning weeks, if not months), start each project by handing out to students a partial, half written application, and make the goal to fix/complete/extend. In this way, the first task required is to read and understand the existing code, before working out what to extend and write. Discuss and require code reading explicitly.

A large amount of peripheral learning happens when reading well written code. We get benefits from an apprenticeship approach, where learners can copy the master’s practices at many levels, and learn by example.

This approach is also much more realistic as preparation for actual work: No new programmer joining a software company will, as their first task, be asked to write a new system from scratch. It is always the reading and extending of existing software.

Of course, this requires teachers to show students code that is worth reading, that embodies good practice, from which also techniques can be gleaned that are not the current focus of discussion. It requires teachers to use a significant number of well-written examples that exemplify good practice. Not all teachers will always be able to write such examples, but resources can be shared. Look for resources that support this approach.

Guideline 2: Don’t start with a blank screen

Decorative image showing the text "Guidelines for Teaching Programming" and the number 2

The second guideline from my 23-year-old paper told teachers not to make students start with a blank screen.

Putting learners in front of an empty screen and saying “Today we are going to write a program” always seemed very strange to me. I think programming may be the only discipline that that would ever approach learning this way. It is the equivalent of teaching English Literature, and making students write a story before they have ever read a story. (Or, indeed, heard a story, or know what a story is.)

Imagine French learners writing French before reading it. Or children learning to play the violin being taught to play without ever having heard music before.

Code reading is a skill that is (at least) as important as code writing.

So: Start by giving your students a small program that does something (hopefully interesting! – more on that later), and get them to execute and experiment. Then get them to make small modifications. Let them experiment.

And free yourself from that idea that you have to completely explain everything they see on screen before they are allowed to look at it! Young learners are resilient – they can cope with a bit of intrigue and mystery.

Sitting in front of an empty screen as a beginner can have a paralysing effect. Being able to experiment and play is an easier, less intimidating approach. Bonus: The quick learners can make guesses and experiment.

Starting with a blank screen requires knowledge, planning and design. Tinkering is easier and gets you further quicker. And it makes it easier to show interesting examples early. (More on interesting examples later.)

In your first class, creating curiosity and engagement is more important than teaching the first bit of syntax. At the end of the class, you want them wanting to come back wanting to know more, not running away from a dispiriting experience.

Guideline 1: Objects First

Decorative image showing the text "Guidelines for Teaching Programming" and the number 1

The first of the guidelines for programming teaching from 2001 stated that you should start teaching objects from the start.

This, perhaps, is the least convincing of the guidelines today. In 2001, when I was thinking about teaching beginners, I was thinking about teaching first-year university students. Thus, it was a selective audience who had chosen to become software professionals.

Today, novice programming teaching is mainly an affair happening at school age. And we have to be aware of the difference it creates: most of the pupils do not want to become software professionals, and they do not all have to learn about best practice in software engineering.

Thus, it is a perfectly fine path today to teach an introduction to programming without objects. (More on this in a later post.)

But I would maintain: IF you want to end up with object-orientation, then you should START with objects. Object-based programming is not a language construct that can be added on to procedural programming later. It requires a different structure of the program, a different way of thinking, a different approach to algorithmic problem solving. If it is not done from the start, it would require unlearning habits later, and start again in a new way. This rarely works well.

So, I would maintain my advice from 23 years ago: If you want to teach object-orientation, start with objects on day 1!

Guidelines for Teaching Programming

Decorative image showing the text "Guidelines for Teaching Programming" as the heading of an academic paper

How to teach programming is a hot topic again. 23 years ago (!) I wrote a paper titled “Guidelines for Teaching Object Orientation with Java” that provided some guidelines (eight, to be exact).

And although, as the title suggests, this was specific to OO and Java, I was wondering how many of these would stand up today. I was surprised to see that almost all of it – I think – is still relevant, and almost all of it we still cannot take for granted.

So I will, over the next few days, revisit the guidelines here, one at a time, and add my comments outlining how much of each I think still applies in “modern times”.

Watch this space over the next week or two for the discussion.