Essentially, relying only on correct, worked examples runs the risk of missing opportunities to identify the limits of your knowledge or the limits of the examples themselves. Correct examples of code promote “I agree because you’ve told me it’s correct and I am learning from you” rather than, “Here’s an area where I don’t understand why this is wrong”, for example.
Enter error-driven learning
You might think that learning something new with an error-driven code example would risk introducing poor understanding of concepts, reinforce existing confusion or even introduce new errors for the student; and you would not be alone in this concern as it is also held by much of traditional curriculum teaching. However, this is only the case if there is no additional learning support – like highlighting where the example is wrong or prompting them to compare with accurate code. I am definitely not proposing you just abandon your new learners with poorly written code; because that’s generally called bug fixing!
Erroneous examples address misconceptions in code directly, by highlighting them instead of focusing on the “correct” code. In a world where “correct” code is an open debate anyway, understanding how something can be wrong is equally as important as understanding how something can be right. Research indicates that misconceptions can be really hard to counteract once they’ve taken root and can often damage learner progress across multiple connected domains if not addressed early [2], so tackling them head-on can be super valuable for learning advanced concepts going forward.
Initiating a learning session with incorrect code from the beginning also opens the learning area into a safe space for errors and mistakes. It gives the learner permission to ask questions and get things wrong and be vulnerable, without expecting perfect understanding from the start. Doesn’t that sound refreshing?
Also, a bit like a “spot the difference” puzzle, leading with an error-driven code example is naturally engaging for the dopamine-driven human brain. The brain thrives on learning new things, and puzzles are one of our favourites; whether it’s playing a game or doing a cryptic crossword (anyone?). A puzzle is engaging, it’s an open question – what’s wrong here? It’s an example of active learning and engages our current domain knowledge or what we think we already know. Also, who doesn’t love correcting someone else?
Another advantage of error-driven code learning is that it can promote learning by teaching not just the one concept of what is “correct”, but two concepts; what is also “incorrect”. This additional bit of learning is referred to as “negative knowledge” [3] and is helpful for the learner to build up a domain of expectations for what a solution should or should not look like; it will also feed in to an understanding of returned errors from the compiler/code/browser so is doubly useful!
What type of errors?
Obviously this won’t work with all types of errors, and the code needs to include enough accurate and recognisable signposts for the learner to be able to orient themselves i.e. the whole function can’t be a hot mess, there needs to be some seeds of sanity.
When I mention “types” of errors here, I mean that syntactical errors are probably not going to cut it in terms of conceptual learning and development. That is to say that leaving out parentheses, missing semi-colons or mis-spelling variable names count as errors, but aren’t really going to help with learning logical flow – unless of course you’re trying to get the learner to understand what the compiler or IDE notices, in which case fire away.
Realistically, semantic errors where there is a discrepancy in the underlying logic would be most useful when teaching a new concept. But – too many semantic errors, or errors that are too hard at the beginning are likely to just lead to confusion rather than learning! [3]. The trick is to be careful, making sure that learning is still being layered and support offered, so that the learner doesn’t rage quit.
Let’s look at a couple of example semantic errors that could be included for teaching some array manipulation concepts. Essentially leading the learner with an issue (unexpected output) and then opening to floor to a discussion around the concepts involved.