Throughout my career as a software engineer, many people have told me that learning to write code is difficult. I challenge this claim. The real difficulty is that people are often taught computer science before they are taught to actually write code. By computer science, I mean fundamental concepts such as the number of bits in an integer or how various pieces of data are stored in memory. Most people would not fully understand these concepts no matter how well explained because they have no context from which to base an understanding. That context is provided by learning to write code first. When I say “writing code”, I mean it literally. The only expectation on a learner at the beginning is to type code and see that code execute. They should see software do meaningful things before any of the subtleties introduced in computer science are explained to them.
A lot of software engineers would disagree strongly with that last statement. Computer science is taught first because it explains how code works fundamentally and the thinking is that programmers who lack an understanding of the foundational concepts will produce substandard code. However, would you teach a toddler English grammar and linguistics theory first? Or would you start with simple words and sentences? Grammar cannot be understood without first learning the words to make use of it. Code is written in “programming languages” because there are many similarities between a programming language and a spoken language, and the method of learning should be similar as well. Much like how we first teach words to someone learning a new language, we should first instruct a programming student to write as much code as possible before introducing the “grammar” of computer science.
Furthermore, teaching computer science first introduces a pace that is not conducive to learning. Traditional methods of teaching will introduce the learner to a lot of theory and then require them to only write a small amount of software. Before they fully grasp the code that they have written and how the theory applies, they are taught more theory. This cycle of lecturing and reading, with very little practical application can easily discourage a new learner. People want to learn how to write code because they see all the fantastic things that can be accomplished with software. They want to be able to do those fantastic things as well! Personally, I did not write any interesting software until after I completed six months of college coursework. That is a long time to spend on something without a substantial reward for your efforts. For many, there is a temptation to say “programming is too hard for me!” and give up. This could very well happen within days from what I have seen.
So what would a lesson plan for teaching writing code look like? There is a saying that a product is not complete when there are no more features to add, it is when there are no more features to remove. The same goes for a lesson plan. What can we avoid teaching at the beginning? It is tempting for a teacher to introduce a dozen data types right when a learner is introduced to variables, one of the most basic programming concepts. However, in order to teach writing code first, that list should be cut to one or two data types. There are also seemingly basic concepts, such as division, that should be avoided until absolutely necessary. Trying to explain to a first time programmer why 2 divided by 4 does NOT equal 0.5 according to a computer is a nightmare, especially when the computer will display “0.5” on the screen when you ask it to display the result of 2 divided by 4. Plenty of software can be written without even touching that topic. Plenty of software can also be written by teaching 1-2 boolean operations (e.g. comparing 2 pieces of data to make sure they are equal) instead of a dozen. Lessons about how data is stored in computer memory can definitely wait. While being an essential set of knowledge for a programmer working on complex software, most of what a learner works on at the beginning will never actually hit an issue with memory.
This need-to-know lesson plan must be curated carefully, and is thus more work on the instructor’s part. The nice thing about throwing every possible boolean operation at a student at once is that the instructor no longer needs to keep track of which operator was introduced when. They can assume that past a certain point, a learner should know all of them even though they may have only written code that used a couple of those operators. To optimize the learning experience for the student and teach writing code first, the instructor must now know every specific detail of what they taught (and when) instead of general concepts. They must now ensure that every assignment can be completed by a learner using just what has been taught. This will also require many more smaller assignments because instead of one assignment for boolean operators, that concept must be taught over the course of a dozen. The task for the instructor is clearly more challenging, but it is essential to provide the right pace for someone to learn how to write code.
All this may sound as if I don’t care about computer science at all, but nothing can be further from the truth. Computer science is important and absolutely required for building complex software. However, it is less vital to those who have just begun to learn programming. They do not have the context to truly appreciate computer science. Teaching them how to write code first provides a smoother progression that is more fun and gives a greater sense of accomplishment. Eventually, they will start hitting limits with the software they can build and realize that there are gaps in their knowledge. At this point they will want to fill those gaps. Computer science fills those gaps. Teaching people to write code first teaches people why they need to learn computer science.
Top comments (11)
I'm right with you -- My first introduction to a programming language was dedicated to pointers, stacks and heaps, and memory allocation. It was hard to grasp why any of this mattered when there was nothing tangible to chew on.
I wish in hindsight I had started writing more high-level code, built something, and then was introduced to these concepts as they became relevant.
I think that's why so many people struggle to learn programming. I actually found myself going back to the concepts I was "taught" years after college because all the code I had wrote gave me enough context to understand those concepts.
We need to redefine what would be considered "basic knowledge". The "basics" should really be a certain amount of experience actually doing something. Understanding what happens behind the scenes are the advanced topics.
What the.. that’s too high a bar to cross..
I've been coding for almost 10 years when I started studying CS the first time. Having that much experience, I wasn't motivated enough to make my degree (had a good job anyway). A few years later I made a new attempt and it turned out that both, my experience from coding and from the first CS courses, were a big advantage.I learned and understood much more of the CS theory.
Don't forget: If you choose to become an IT professional, learning will never end. If you stop learning, you'll soon stop being a professional.
Agreed! I had a professor in college who said "There are developers with 30 years of experience, and then there are developers with 1 year of experience repeated 30 times."
My experience learning to code was slightly different than the typical CS program so may not apply directly, but I think has some merit in a certain sense. I went through an electrical and computer engineering program in which computers and software were taught from the ground up - literally. How do computers work? Well switches (transistors) are either on or off, etc. How are those used productively? To do things like add numbers, evaluate logic, etc. Ok, so when I say add these two numbers, I now know exactly what is happening in the machine. This progressively builds up to start learning higher level concepts/abstractions and along the way languages (c to java and so on). You start at the core and grow outward. This ensures you are always building on top of a base foundation of understanding, rather than having to dig through the confusion of lower abstractions. This may or may not apply to many whom never will leave high level languages built for web development, but still may be useful (not a web dev so don't know).
One valuable thing in this approach and maybe in the 'current' approach you mention (depending on how its done), is an understanding without mystery. When the computer spits back error messages at me or does weird things I (generally) understand why because I have working mental models of what the computer does - sure you abstract at certain points (I definitely don't think about transistors or gates), but I have the tools to be more self-reliant. Usually growing outward helps by starting with a smaller domain that a student need's to understand (something you are effectively describing here). In this case it is enforced by the tools rather than arbitrarily. To your boolean operator example, in my case we only had AND and NOT, so you learn the two that exist and then learn how to combine those into more complex operators.
I do completely agree with getting students excited early on in the process. Being able to have successes, no matter how small, is key to being motivated to continue the process. CS and learning to write code is hard, so feeling capable is important. This can be done starting with core concepts at low levels. I wrote a game in assembly my first semester of school. It was crap but I felt accomplished as hell and knew completely how it worked!
Thanks for the article - great read!
That's actually a very good point. Most CS education does not start with hardware so a lot of it does seem like mysticism at first.
I actually learned how computers work at that level (though in my 4th year of college) and I found it very interesting. However, I don't think it's necessary to know for most web development these days. It would be for more advanced computer science work, but most programmers don't work on products that require that kind of programming.
This is easily one of my favorite posts on this site. I don’t know how it took me so long to find it!
Thanks! Glad you liked it.
The analogy is in the art world, learning how to grind and mix paint versus learning composition and perspective.