Back in the day -- before I started on what would become Blackbird Code -- I was teaching my kids to code, using various online education systems, and I got frustrated. Long story short.
One thing that jumped out at me was the lesson presentation systems. Every system for teaching coding has got to have a way of checking that the student is entering in correct code, but that’s not trivial. It’s not like there’s a single way of solving any given problem, so if you give your student a task -- say, “Ask the user for a sentence, then print out the words in reverse order” -- there’s no simple way to tell if they’ve solved it correctly.
All the systems I looked at handle this the same way: They run the user’s code, give it sample data, and check if the output is correct. This works fine if the code is correct. If it’s not, though, you have a problem, or rather, the student does. They’ll need to fix the code, but they’re a beginner, and fixing bugs (code errors) is not something beginners can generally do on their own. (Which is why I got frustrated: my kids basically needed me there helping at all times, and often it seemed like it would be easier for me to teach them myself than use an online system that had so little to give.)
This got me thinking about how you would make a system for teaching programming. When the user is coding, and makes a mistake -- which is unavoidable, ongoing, and completely normal -- it’s almost impossible for an automated system to help, except by undoing everything the user had written and replacing it with the correct code. Which hardly counts as helping.
I began the process of designing a new approach to this problem. I decided that, instead of checking that the user’s code does what it’s supposed to, I would make sure the user wrote each specific line of code as I planned it. I would prevent the student from making any serious mistakes by not allowing them to enter any lines of code they weren’t supposed to. There would be room to experiment and make mistakes, but only within a limiting framework. This would prevent too much confusion, and make it possible for the student to focus on practicing something in a comfortable way until they understood it -- rather than beating their head against it until the problem finally gave way, which is what generally happens, a painful process that takes way too long, and all too often leaves behind a traumatized student who still doesn’t have a correct understanding of the material.
There were a number of issues with my approach. Firstly, philosophically, most developers believe that the only way to learn this stuff is the hard way; I had a number of conversations with people who told me I was going about it ALL WRONG: I would spoil the students. But I decided to persevere. Next, there are a lot of technical issues -- like the fact that we need to allow for multiple (sometimes hundreds) of versions of a line of code. It took me about a year to write the first version.
But having this setup allows us to have a Show Me button that shows the correct version of any given line of code, so a student can get help when they need it.
It’s true that most lessons can be completed just by repeatedly pressing Show Me and typing in the code it recommends. Two things about this. First, you don’t get a star for completing the lesson if you use Show Me -- it’s amazing how much people care about those stars -- and second, every stage has a challenge lesson where the Show Me is turned off, so you can’t progress to the next stage until you’ve mastered the material at a basic level.
So, with Blackbird Code, students can learn quite difficult concepts that can really only be internalized through practice, and they can do it without the kind of extreme, traumatizing experience that so often characterizes the process.
Once they’ve practiced them a number of times in the lessons, they are encouraged to work on them in the less structured environment of the Guided Projects. And at any time, they’re free to try them out on their own in the Workshop.
In the beginning, I felt like this was simply the best available way to approach the problem -- the least worst option. Over time, I’ve come to understand that, from an educational point of view, it’s actually the correct approach: Students start by repeating back what they’re told...then, with repetition, it gradually starts to make sense. With continued practice, it becomes part of their vocabulary.