A pupil writes a program that runs. The output looks right. The teacher moves on.
Later, the same pupil cannot adapt the solution when the problem changes slightly, cannot explain why the loop terminates, and cannot find a bug when the program fails on an edge case.
The code was syntactically fine. The thinking was thin.
Computing education has to hold both truths at once: pupils need working programs, and working programs are not sufficient evidence of understanding. The subject is not only a language. It is a way of structuring problems, expressing procedures, and checking whether an idea survives contact with reality.
The gap
In classrooms, the gap often appears between tasks that reward completion and tasks that reward reasoning:
| What we can observe easily | What we actually want |
|---|---|
| Correct output | Correct reasoning under variation |
| Finished exercises | Transfer to a nearby problem |
| Copied patterns | Ability to construct a new pattern |
| Quiet compliance | Willingness to test, challenge, and repair ideas |
The gap is not laziness. It is often a rational response to assessment: if only the artefact is marked, pupils optimise for the artefact.
Good computing teaching therefore designs for visible thinking — predictions, tests, explanations, comparisons between approaches — not only final programs.
Syntax and structure
Syntax matters. Pupils cannot express ideas they cannot write. But syntax is the entry point, not the destination.
Useful progression:
- Read code and predict behaviour before execution.
- Trace execution with small examples — what changes, line by line?
- Modify an existing program to meet a new requirement.
- Compose a solution from smaller procedures with clear responsibilities.
- Justify design choices: why this data structure, loop, or decomposition?
A common mistake is to treat step five as optional once step one succeeds. That is how pupils learn templates without learning programming.
Structure — decomposition, naming, invariants, clear interfaces between parts — is what makes programs maintainable in the pupil's mind, not only on screen.
Explanation as evidence
If a pupil can run code but cannot explain it, treat explanation as unfinished learning.
Useful prompts:
- What is the smallest input that would break this?
- Which line would you change first if the requirement changed?
- What does this variable mean at the start and end of the loop?
- How would you check your answer without running the full program?
These questions are low-tech and powerful. They also resist shortcuts that produce correct-looking output without comprehension.
Explanation does not need ornate prose. A clear trace, a labelled diagram, or a short spoken walkthrough can be enough. The standard is whether another person could follow the reasoning.
Debugging as thinking
Debugging is not a remedial skill for weak pupils. It is central to the subject.
A useful classroom norm: errors are information, not embarrassment. A failing test is often more instructive than immediate success because it locates a misconception.
Teach debugging as a sequence:
- Reproduce the failure reliably.
- Narrow the location — which input size, which branch, which line?
- Form a hypothesis about the cause.
- Change one thing and observe the effect.
- Keep a short note of what was tried.
This is scientific thinking in miniature. It also builds independence: pupils who can debug are less likely to treat programs as magic spells that sometimes work.
A classroom example
Consider a simple brief: write a function that returns how many values in a list are greater than a given threshold.
A pupil submits:
def count_above(values, threshold):
total = 0
for value in values:
if value > threshold:
total = total + 1
return total
The program works on the teacher's examples. The lesson could end there. A stronger lesson does not.
Ask:
- What should
count_above([], 5)return? Why? - What happens if
thresholdis negative? - Rewrite the loop using a different approach. Is one version clearer?
Then change the requirement: count values greater than or equal to the threshold. Pupils who understand the comparison operator adapt quickly. Pupils who memorised a template may change the wrong line or duplicate code blindly.
The pedagogical goal is not the function. It is the portable idea: iterate, compare, accumulate, test boundaries.
Practical habits
For teachers and tutors, habits that keep computing education substantive:
- Predict before execute. Make prediction a routine step, even for short programs.
- Require tests. Even informal ones: three inputs chosen by the pupil, one chosen by the teacher.
- Compare solutions. Two correct programs can teach more than one when pupils explain trade-offs.
- Mark process. Credit clear reasoning, test cases, and revision — not only final output.
- Use realistic contexts sparingly and precisely. Context should illuminate the structure, not distract from it.
- Connect to prior mathematics and logic. Computing is not separate from clear conditional reasoning and attention to definitions.
These habits align with broader principles in good teaching: start from the learning objective, make evidence visible, and treat struggle as data when it is productive rather than pointless.
What to try next
Computing education succeeds when pupils leave with more than a folder of completed tasks. They should recognise problems they can model, tools they can use to express solutions, and habits they can apply when those solutions fail.
If you teach the subject, ask:
- Where do my tasks reward syntax without structure?
- What would pupils still need to do if working code were already given?
- Which explanations would convince me that they understand, not only that they finished?
The aim is not harder marking. It is clearer design: tasks that treat computing as reasoning made executable — not typing made to look like thought.