"It is usually considered good practice to give people instruction in their occupational activities. Now, the occupational activities of children are learning, thinking, playing, and the like. Yet, we tell them nothing about those things. Instead, we tell them about numbers, grammar, and the French revolution; somehow hoping that from this disorder the really important things will emerge all by themselves."
— Seymour Papert, "Teaching Children Thinking"
It's been a while since I've written anything here. That's because I've spent the last month or so focusing on another endeavor— developing a program to teach kids to code. When I described this work to a new roommate, she asked: "Why does a 7-year-old need to know how to code?". A fair question, and one that deserves a thorough answer.
My intent here is to organize my thoughts, justify this teaching endeavor, and condense the best books, essays, and conversations on the topic (at least the ones that I've encountered so far) into something that's hopefully somewhat useful.
Of course, this isn't the only relevant question. For example, "Why should I teach kids to code?", or "How should I teach kids to code?", or "Why do I want to do this?". But I'll save those for another day.
Why Learn to Code?
Learning to code comes with a lot of wonderful, highly-emphasized economic opportunities. These get the attention, but they probably shouldn't be the first priority for kids (or perhaps for anyone). Far more important are the ways that coding teaches you how to think and how to learn. For better job opportunities, high school or college (or later) is a fine time to start coding. But because people of all ages will benefit immediately from better thinking and learning, there's a benefit to starting sooner.
In general, school and society pay much more attention to the objects of our thinking and learning — the accumulation of facts (dates, names, definitions) and the ability to execute memorized processes (long division, the five-paragraph essay, etc.) — than to the thinking and learning themselves as skills to be developed.
As a result, many people graduate not only unprepared to tackle new problems, but unaware of the source of that deficiency. We see this misunderstanding in the debates about which set of historical facts to discuss and in the insistence that schools ought to teach students how to do their taxes. The real issue — missed entirely by this rhetoric — is not that students failed to memorize the right set of facts or procedures, but that they cannot think or learn effectively enough to accomplish new tasks on their own.
Not only do we fail to recognize this inability, but we lack a sufficient vocabulary to discuss it. Without that vocabulary, this idea can be hard to conceptualize, so I've tried to make it more concrete (for myself and for you) by outlining some of the skills that might comprise better thinking and learning. I've also tried to justify why learning to code is an especially good way to foster them, even though I don't think it's the only way.
Usable Formal Logic with Feedback
Compared to higher-level math or philosophy, coding is an accessible, applicable, and enjoyable introduction to formal logic. Reasoning about the correctness of a solution or the implications of a policy are important skills rooted in rigorous, logical thinking. But because the mindset that they require is rarely found outside of advanced textbooks, it can be hard to practice.
Coding presents the topic as a tool to be used, not just a series of rules to be memorized. And, it comes with a constant, reliable source of truth (the computer) that can help confirm and calibrate a student's thinking.
Precise, Systematic Thinking
At its core, coding consists of breaking a conceptual process into increasingly simple sub-processes until they're specific enough to be executed by a computer.
Stated more generally, this strategy — breaking up a task into sub-tasks until they're all actionable — also works well for solving non-computer problems. But doing this successfully requires paying very close attention to our own thinking and then very precisely describing what needs to happen. And because most activities don't really require such an exacting level of attention, it's easy to avoid developing it.
Taking the time and effort to systematize a task helps us to organize and improve our thinking, and then it leaves us with something concrete enough to be debugged.
In some endeavors, like an exam, it's tempting to hope that you're right and then forget about any "wrong answers" as quickly as possible. But software, like any complex creation, is basically never right on the first try. Getting something to work requires making updates. This shift in expectations removes the stress and shame of getting a wrong answer and encourages you to ask why something isn't working and how you might be able to fix it. A debugging (or growth) mindset helps replace stress with curiosity, and leads to faster learning and better outcomes.
After being exposed to just a few preliminary coding concepts, a student can ask "what does this do?" and then actually find an answer for themselves.
In subjects like science, history, or math, this kind of experimentation is often too dangerous, too expensive, or just out of reach for beginners, and so students learn to rely on a teacher or textbook to answer their questions. This reinforces the mindset that learning requires an expert to guide you along, and that it's something outside of your control.
But when learning to code, as soon as you encounter a new concept (arrays for example), you can start experimenting with the edges of the definition and functionality. You can look at the list of available methods, call them, and figure out for yourself what they do (using the applied formal logic discussed above to ensure correctness). These kind of discoveries feel much more interesting and valuable, and they give students a sense of ownership of their learning.
The role of the teacher, then, is to balance guidance and open experimentation so that students feel empowered to ask questions and trust that those questions will be generally productive.
Confidence with tackling hard problems
Even for the most experienced engineers, making sense of a complex new program or codebase can be frustrating and intimidating. Fluency with this process can make it more tolerable, and each successful attempt will develop students' belief that they can systematically accomplish hard things.
The first and most obvious audience for your code is the computer, which you have to satisfy by producing something that's correct and efficient. This requires the sort of rigorous, systematic thinking I described above.
Moving on to reading code reveals your second audience: humans (sometimes just yourself), who are looking for something that's clear and understandable. This requires empathy, style, and a clear understanding of your own thinking process.
To satisfy everyone, you'll need to combine these skills, carefully weigh tradeoffs, and make nuanced decisions.
To the extent that good thinking and learning are developed (via coding or anything else), it often happens in a roundabout sort of way — as a side effect that no one really talks about. By describing these concrete sub-skills, I'm hoping to both justify my decision to teach and to focus myself on the real — if sometimes nebulous — goal.