You watched the video.
You typed the commands.
Your output matched the instructor’s output.
Everything worked.
Then the next day you opened an empty editor, tried to do the same thing without the tutorial, and suddenly had no idea where to start.
If you’ve learned programming, data engineering, cloud infrastructure, machine learning, or almost any other technical skill this way, you’ve probably experienced this.
It is tempting to conclude:
I guess I didn’t understand it.
But something more interesting is happening.
The problem may be the way we commonly mistake successful performance during instruction for learning.
And cognitive science has been warning us about this for decades.
Imagine I give you this SQL:
SELECT
customer_id,
SUM(order_total) AS lifetime_value
FROM orders
GROUP BY customer_id;I explain each line
You understand what SUM does.
You understand the GROUP BY.
You type it into your editor.
It runs.
At that moment, you may genuinely understand everything you’re looking at.
Now close the tutorial.
Delete the query.
I give you this requirement:
Find the total amount spent by each customer.
What happens next?
That is a different cognitive task.
In the first case, you were primarily recognizing and interpreting a solution.
In the second, you have to generate one.
That distinction matters.
In a classic 1978 series of experiments, Norman Slamecka and Peter Graf compared information people generated themselves with information they simply read. Across their experiments, generated information was remembered better. The finding became known as the generation effect.
The exact experiments weren’t about SQL or Python, of course.
But the underlying distinction should look very familiar to anyone who has learned technical skills:
Seeing the answer and producing the answer are not equivalent activities.
There is another problem.
When instruction is going smoothly, it feels like you’re learning.
The instructor asks a question.
You know the answer.
The next step seems obvious.
The code makes sense.
Everything is familiar.
That feeling is useful, but it isn’t a reliable measurement of what you’ll be able to retrieve later.
Research on what psychologist Robert Bjork termed desirable difficulties examines a strange feature of learning: some conditions that make practice slower and more difficult can improve long-term retention and transfer. Conversely, conditions that make performance easier during practice can sometimes produce worse long-term learning.
That’s deeply counterintuitive.
We naturally judge our learning by how we’re performing right now.
Smooth feels good.
Difficulty feels bad.
Getting stuck feels like failure.
But the purpose of training isn’t to maximize performance while the instructor is standing beside you.
It’s to change what you can do when the instructor is gone.
Roediger and Karpicke ran an experiment where students either repeatedly studied material or practiced retrieving it.
Five minutes later, additional studying looked good.
But when the students were tested after two days or a week, retrieval practice produced substantially better retention.
There was another interesting result: repeated studying increased students’ confidence that they would remember the material.
Think about that combination.
More studying can produce:
better immediate performance + greater confidence
while retrieval can produce:
more difficulty now + better performance later.
That gap is enormously important when designing technical education.
A walkthrough is optimized to keep you moving.
Learning sometimes requires stopping you.
Manu Kapur’s work on productive failure explored an even more interesting possibility.
What happens if students encounter a difficult problem before receiving direct instruction?
In his 2008 work, students attempted complex, ill-structured problems without the support structures normally supplied during instruction. Their initial attempts often failed.
But that failure could become productive when it was followed by instruction and consolidation. A 2021 meta-analysis by Tanmay Sinha and Manu Kapur examined 53 studies comparing problem-solving-before-instruction with instruction-before-problem-solving. Overall, the problem-solving-first approach produced better learning outcomes, with stronger effects when the instruction closely followed productive-failure principles.
The goal isn’t failure for its own sake.
And it certainly isn’t:
“Here’s something you have no hope of solving. Good luck.”
The important part is what the struggle forces the learner to do.
They have to ask:
What do I know?
What am I missing?
Why didn’t this work?
What assumptions am I making?
What information matters?
What alternatives are possible?
Then, when the formal explanation arrives, it has somewhere to attach.
The learner isn’t merely receiving an answer.
They’re comparing the answer against models they already attempted to construct.
Programming-specific research is beginning to point in the same direction. In a 2025 study of novice Python learners, students taught using productive failure performed similarly to students receiving direct instruction initially, but showed better retention and performance on delayed tasks.
Consider two ways of teaching an API.
Create this file.
Copy this function.
Add this dependency.
Put the API key here.
Run this command.
You should see this JSON.
Congratulations.
Here is the API documentation.
Your goal is:
Retrieve these records and store these four fields.
Try it.
Maybe you send the wrong authentication header.
Maybe you misunderstand pagination.
Maybe you receive a 429.
Maybe your first data model is wrong.
Maybe everything appears to work, but you only receive 100 records.
Then we investigate.
Now the documentation means something.
Now rate limiting means something.
Now pagination isn’t a vocabulary word from a slide.
It’s the reason you only received 100 of the 14,000 records you expected.
That moment of:
“Wait. Where did the rest of my data go?”
can be educationally valuable.
The learner encounters the need for the concept before being handed the solution.
There is an important warning here.
Difficulty by itself is not learning.
Making instructions confusing isn’t productive struggle.
Hiding information isn’t productive struggle.
Giving someone a problem hopelessly beyond their current knowledge isn’t productive struggle.
Research on desirable difficulties specifically concerns difficulties that ultimately improve retention or transfer—not arbitrary friction.
Good technical training therefore needs to control the amount of support.
It should change when that support appears.
Instead of:
Explanation → copy the solution → repeat a similar exercise
consider:
Problem → attempt → feedback → instruction when needed → retry → changed problem
That difference matters.
In the first sequence, the learner sees the path before they have to decide what path to take.
In the second, they encounter a problem first.
They have to retrieve what they know.
They have to decide what matters.
They have to form a hypothesis.
They may fail.
Then the instruction arrives in response to a problem they already understand.
Instead of teaching pagination and then manufacturing an exercise to practice it, give the learner a task where pagination becomes necessary.
Instead of teaching retries and then asking them to copy retry logic, let the API fail.
Instead of explaining schema drift and then showing an example, change the schema.
The problem creates a reason to learn the solution.
That last transition is especially important.
Because that’s where tutorials usually stop and engineering actually begins.
I think one of the biggest mistakes we make in technical education is measuring whether learners can successfully complete the learning material.
That’s useful.
But I care much more about what happens afterward.
Close the browser.
Remove the instructor.
Take away the exact sequence of steps.
Change the dataset.
Rename the columns.
Make the API fail.
Ask for the same concept in a slightly different context.
Now what can you do?
That’s the capability we’re actually trying to build.
A good tutorial should eventually make itself unnecessary.
And if you’ve completed hundreds of hours of tutorials but still freeze when you’re staring at an empty editor, that doesn’t necessarily mean you’re bad at programming.
It might mean you’ve spent hundreds of hours practicing something subtly different:
following someone who already knows where they’re going.
Learning requires eventually navigating without them.
Slamecka, N. J., & Graf, P. (1978). The generation effect: Delineation of a phenomenon. Journal of Experimental Psychology: Human Learning and Memory.
Roediger, H. L., & Karpicke, J. D. (2006). Test-enhanced learning: Taking memory tests improves long-term retention. Psychological Science.
Kapur, M. (2008). Productive failure. Cognition and Instruction.
Sinha, T., & Kapur, M. (2021). When problem solving followed by instruction works: Evidence for productive failure. Review of Educational Research.
Suriyaarachchi, H., Denny, P., & Nanayakkara, S. (2025). Investigating the use of productive failure as a design paradigm for learning introductory Python programming. Proceedings of the ACM Technical Symposium on Computer Science Education.
No posts

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.