Fail and Fail Again: The (not so) secret path to learning how to code successfully
My son’s reading book from school the other day was about Steve Fossett. His summary after reading it was how Fossett tried, and failed, six times to cirgumjavigate (difficult word for a six-year old) the globe before he finally succeeded. Our children are often told in various contexts that failing is OK and that they should keep trying to get better at things.
But the world they (we) live in ignores this dictum. Failure is perceived as an inherently bad thing by most of society. Matthew Syed’s recent book “Black Box Thinking” explores this topic in detail, opening with a powerful comparison between two industries: aviation which uses every failure as an opportunity to increase safety (hence the ‘Black Box’ in the title) and healthcare which often stigmatises failure, leading to the same errors reoccurring.
While reading the book I was thinking about two other fields I am closely linked to that also fall on either side of this divide.
The first is science, my ‘first’ profession. From the outside science is often seen as an enlightened profession, and many things within it are, but the culture within the scientific community is not too different from the healthcare one Syed describes. Funding models, University structures, journals, they all “discourage failure”. I’m yet to see a Journal of Negative Results or the Proceedings of the Annual Meeting of the Society of Failed Experiments.
Programming, on the other hand, thrives on failure. No computer program works perfectly the first time round. Every programmer knows that, and expects that. There are three aspects which are central to programming that rely on failure and which make that failure central to the process of coding, and by extension becoming better at programming:
1. Errors: one of the first things a beginner to coding needs to learn is how to understand the error messages that are output (compiler or runtime errors). Indeed we rely on well written error messages when we code — and haven’t we all cursed at the developer who couldn’t be bothered with writing readable error messages when using a certain package or library? Error messages can themselves be a useful source of learning as they can provide insights into some of the inner workings of a programming language. Their role is primarily to help the programmer fix the error but we can and should use them to learn more about why that particular error occurred.
2. Bugs: the industry has not only given a name to the process of removing unexpected behaviour in code (debugging) but has also produced tools to help find and remove these bugs (debuggers). Debugging is probably the single most important process through which a programmer can become more proficient. It forces the programmer to look deeper into their code and its structure, and to understand better the tools and methods they are using. As with errors, the debugging process should be seen as an opportunity to learn not just a means to fix a problem.
3. The third in my list is a more subtle type of ‘failure’ which the programmer often does not identify as a failure in the first place. This is when a program works, without errors or bugs, but has been written poorly and/or inefficiently. The fact that code works does not mean it has been written well. Often this ‘failure’ comes to light when the programmer tries to extend their code or add complexity and finds that it is impossible to do so. Often these failures occur when the wrong data structures are used or the wrong coding techniques.
Beginners, especially if they are self taught (or taught badly) often pick up bad habits such as creating several variable names for similar objects (ball_1, ball_2, ball_3, ball_4…) instead of collecting them in the appropriate data structure, or using global variables as the default way of accessing variables across their program (author’s note: never ever use global variables). How can we learn from these failures? In part by reading code written by others. Platforms such as codewars.com are a good starting point as they provide coding challenges for the user to attempt and then allow you to view the solutions posted by others.
One of the biggest barriers some novices face is when they perceive themselves as expert programmers and settle into their comfort zone instead of looking at their own code in a critical way. I personally set aside a bit of time every week to practise coding, trying to explore areas I am not that comfortable with or methods that I have never used. Most proficient programmers do so.
One cannot learn how to code without being ready to fail and fail again. Anyone with a fear of failing will never get past day one of their journey to learn programming. So if you needed another reason to teach your children how to code, here it is: it will teach them how to fail, and how to learn from that failure in order to succeed in coding, and in life.
Now, off to check whether my son has learned how to say ‘circumnavigate’…