Working code is not the same as understood code.
You understand it when you can run it in your head.
The familiar wall
One way AI supports me is by improving my learning curve. It helps me notice earlier where my understanding breaks down. And ofcourse, assist by advicing me how to patch up the holes in my knowlegde.
I remember when I started learning programming, that simply learning constructs and definitions, following tutorials isn’t enough. I kept hitting a wall.
I could read the code, but I could not reliably predict what the next line would do. When two variables referred to one object, or when a method changed state that another method later observed, the program became mist. That familiar wall has a name.
The learner is missing, or has built an incomplete, notional machine.
A notional machine is the simplified computer you run in your head when reasoning about code. It tells you what exists, what changes and what a statement causes to happen.
Three publications worth knowing
The idea appeared explicitly in Benedict du Boulay, Tim O’Shea and John Monk’s 1981 paper The Black Box Inside the Glass Box. They described the notional machine as the idealised model of the computer implied by a programming language. They also argued that learners need ways to see this otherwise hidden machine in action.
In 1986, du Boulay’s Some Difficulties of Learning to Program placed the notional machine among five overlapping areas learners must master.
Knowing syntax is only one area. You must also understand the machine that executes it, recognise standard structures and learn the practical craft of creating and testing programs.
Juha Sorva’s 2013 review Notional Machines and Introductory Programming Education connected decades of research on mental models, misconceptions and introductory programming.
Its practical lesson is simple. There is no single perfect diagram for every language and learner. A useful notional machine is limited, consistent and accurate enough to predict the behaviour currently being studied.
Build one while coding
Do not try to visualise all of C#. Choose one behaviour you cannot yet predict.
Suppose you are unsure what happens here.
var first = new TaskItem("Write draft");
var selected = first;selected.Complete();Before running it, draw only what must exist.
first --------\
>----> ( TaskItem object )
selected -----/StateNew ---- Complete() ----> Completed
Now make a prediction.
Both variables refer to the same object. Completing it through selected means that first also observes the Completed state.
Run the code or inspect it in the debugger. If reality contradicts your drawing, revise the drawing. Do not merely memorise the result.
Four questions that expose the machine
1. What exists?
List the concrete actors at this moment.
Get coding | seaphylla | omnivorous’s stories in your inbox
Join Medium for free to get updates from this writer.
These might be variables, values, objects, collections, callers or external stores. Do not begin with vague words such as data or system.
2. What points to what?
Distinguish a copied value from a shared object.
Use separate boxes for copied values and arrows for references. This catches many misunderstandings about assignments, parameters and object changes.
3. What may change next?
Write down the allowed states and transitions.
A task might move from New to In progress and then to Completed. Ask what prevents an illegal jump and where that rule belongs.
4. Where does one input travel?
Trace one real input through the program.
“Write draft” is better than inputData. Mark every check, transformation, method call and side effect.
[ "Write draft" ]
|
v
[ Validate ] -- invalid --> [ Error ]
|
valid
|
v
[ Create object ]
|
v
[ Save ]
|
v
[ Display ]Use this five-minute coding routine
Freeze
Select the smallest moment you cannot predict.
Draw
Use boxes for things, arrows for references or movement, and named states for change.
Predict
Write down the expected value, state and side effect before execution.
Attack
Try null, duplicate, empty, repeated and out-of-order input.
Verify
Use a test, debugger or tiny console experiment.
Revise
Change the model when the evidence disagrees.
(you can find my free Notational Machine Cheat Sheet on Gumroad)
Where AI helps
AI is particularly useful for generating contrasts and challenging a model.
You can ask
Show one assignment that copies a value and one that copies a reference.
After each line, list every variable, object and current state.
Find an input for which my diagram predicts the wrong result.
Give me two minimal examples that differ in exactly one respect.
Then verify the answer yourself.
Avoid asking only for an explanation of finished code. Fluent explanations can conceal wrong assumptions. Prediction followed by verification provides stronger evidence.
The essential act remains yours. You decide whether the model is clear enough to think with, where it oversimplifies and whether it predicts the program correctly.
AI accelerates the feedback loop. It does not inherit the responsibility for understanding.
Know when to replace the model
A notional machine is a deliberate simplification, not a miniature description of every runtime detail.
“Objects are on the heap and values are on the stack” may help initially, but it becomes unreliable around boxing, captured variables, spans and asynchronous state machines.
Mark what your current model explains and where it stops working.
The goal is not to draw forever. It is to internalise a model precise enough to anticipate behaviour, recognise a broken boundary and question generated code.
The compiler tells you whether code is legal. Your notional machine helps you understand what the code means.
You can find my free notational machine cheat sheet on gumroad
Like this article? For more deep dives into creative obsessions, literary inspirations, game development stories, philosophical rabbit holes, and other hyperfixations turned into writing, visit www.onlyfangirling.com.








