How Introductory Computer Programming Should Be Taught

Hint: It’s not by writing Hello, world! first

Computer programming has been taught in the same manner for thirty or forty years, or at least since I entered the field. Have the student open an interpreter or compiler and write a program that displays Hello, world! on the screen. Then teach a few concepts, have the student write programs using those concepts, rinse, and repeat. There is a better way to teach programming, though, and in this article I’m going to share this new curriculum with you. This curriculum is based on a paper written by a group of researchers at the University of Washington’s Information School, with the lead author being Benjamin Xie.

A Theory of Teaching Computer Programming

Xie and his co-authors outline a sequence of steps for teaching and learning computer programming. I’ll outline the steps here and then delve deeper into each step in the rest of the article. The steps are:

  1. Learn to read code by doing variable traces, construct by construct.
  2. Learn to write construct syntax.
  3. Learn to understand how to read coding templates.
  4. Use coding templates to write code.

The authors’ beliefs are that writing code to solve problems before you thoroughly understand what a construct does and how its syntax is formed is getting ahead of the game. And, once you understand how to write the syntax for a construct, you’re not ready to solve problems using that construct until you’ve seen templates that demonstrate how to use the construct in a program.

Let’s break these steps down further to see what needs to be accomplished in each step.

Variable Tracing

The first part of learning to program needs to be learning how to read programs and understand what they do. The best way to do this is to write up a trace of all the variables in a program. Tracing variable values from the beginning to the end of a program demonstrates the learner can follow the flow of a program and understands all the nuances of the programming constructs used in the program. For example, here is a simple code fragment I often ask my students to trace (in C++):

const int SIZE = 5;
int grades[SIZE] = {71, 82, 77, 92, 84};
int total = 0;
for (int i = 0; i < SIZE; i++) {
  total += grades[i];
}

The trace students write looks like this:

SIZE: 5

i: 0, 1, 2, 3, 4, 5

total: 0, 71, 153, 230, 332, 416

Being able to trace code in this way does two things: 1) it shows that the student understands the semantics of the program; and 2) it shows that the student can predict the effect of syntax on the program’s behavior. These skills are very necessary before the student can begin writing their own programs.

Writing Program Code

Once the student becomes comfortable with reading and analyzing a program construct’s syntax, they are ready to write code for that construct. The best way to facilitate this learning is to provide the student with a clear description of the construct they need to code and have the student translate that description into a program.

An example from the paper by Xie, et.al. is taking a description of how to swap the values of two variables and turning that description into a program. Their description looks like this:

  1. Define variable x. Set it to 1.
  2. Define variable y. Set it to 2.
  3. Define variable temp and set it to x.
  4. Set x to y.
  5. Set y to temp.

The student who understands the basic syntax of writing assignment statements should be able to translate this description into a complete program, as shown below:

int x = 1;
int y = 2;
int temp = x;
x = y;
y = temp;

The problem with most programming instruction is that students are expected to be able to write code without the necessary practice in learning to read and understand code first.

Reading Templates

According to Xie, et.al., a template is a reusable abstraction of programming knowledge, and being able to read a template and know when and how to apply it to an appropriate problem is the next step in programming instruction.

The ability to read a template means the student can read the syntax of a code fragment and recognize that the code fragment implements a template, and the student also must know and understand the purpose of the code they are reading. So, when a student sees the variable swap code fragment shown above, they will recognize it and understand that it is the implementation of the variable swap template.

It’s important that before a student can successfully read templates they must be able to read code and be able to predict its behavior, which comes from lots of code reading and code writing. Not having this knowledge will lead to the student not understanding or incorrectly understanding what a code fragment does, leading them to misinterpret the template the code is implementing.

Writing Templates

The last step in programming instruction is for the student to be able to take a vague program description, determine the template needed to solve the problem, and being able to apply the template to that specific problem. The Xie paper demonstrates this with a word problem where a girl has two flashlights, one with more power than the other. The flashlight with more power breaks, however, so she needs to swap the batteries so that the working flashlight has the most power. The problem states that the amount of power in the flashlights is stored in the variables power1 and power2.

If the student has a strong knowledge of the previous three steps, developing a program to solve the problem above should be straightforward. However, if the student is deficient in any of the three steps, then attempting to move from a general template solution to a working program can lead to errors. If the student is deficient in code reading skills and/or code writing skills, they will likely make numerous syntax errors when trying to write the program. If the student is deficient in template reading skills, they will likely make logic errors when trying to apply the variable swap template to the flashlight battery problem.

Why Current Programming Instruction Doesn’t Work Well

The sequence of instructional steps developed by Xie and his co-authors demonstrate that when programming skills are properly sequenced, programming students learn more effectively and efficiently. The problem with most programming instruction today is these steps are either not followed or they are not followed with enough spacing between them so that students have time to get proficient in one step before moving on to the next step.

It would be easy to blame programming instructors for this problem, but to me, the real blame lies with the resources most instructors use for teaching programming – textbooks. I have written elsewhere on this blog about the problems with computer programming textbooks, but one problem is that these books do not follow this sequence of instruction, or at least they don’t follow the sequence with adequate spacing.

Programming constructs are introduced, two or three examples are given, and then students are asked to solve problems using the construct. Students are not usually asked to first demonstrate proficiency in being able to read and understand the construct’s syntax before writing some simple examples. And, very rarely are well-designed templates provided with programming constructs to help students solidify their knowledge of the construct.

A few textbooks provide some exercises in reading code at the end of a chapter before moving into the exercises to work. However, by placing these exercises at the end of the chapter, the student is not encouraged to work them first before moving on to more elaborate problems that require template application.

As this new theory of sequenced programming instruction becomes more widely known, I hope new textbooks and other learning resources are developed that follow this type of instruction.

If You are Learning Programming on Your Own

You can follow these sequences of topics if you are learning computer programming on your own and not in the classroom. To learn more about variable tracing, here is a great site from the University of Wisconsin’s Computer Science department: http://bit.ly/2OogxOg. There are many, many web sites devoted to teaching people how to write code. Many of them allow you to work in a web-based environment so you can get immediate feedback by running your code in the browser. Spend some time at w3schools.com or tutorialspoint.com to see if you like those sites, or just search for one more to your liking. As for working with templates, the paper by Xie, et.al. provides very good introductory information on using templates to teach computer programming. If you are very brave, the book Designing Pascal Solutions: A Case Study Approach, by Michael Clancy and Marcia Linn, provides many templates for introductory programmers. The problem is the book is written for the Pascal language, so it may be hard to follow if you don’t have any programming background. I will be writing more about using templates for learning computer programming on my blog in the future.

Learning to Program Can be Easier

Having taught computer programming for over twenty years now, I know that learning a programming language is a hard task for many students. However, by introducing programming topics in the right order, at the right time, and in the right dose, students will find programming a more pleasant topic to learn, and, hopefully, find useful for them regardless of what career they choose.

Become a Great Programmer Through Deliberate Practice: Focus and Coaching

In my series of articles on becoming a better programmer through deliberate practice, I have discussed how you can’t become an expert programmer without moving outside your programming comfort zone and becoming an expert programmer requires that you set performance goals so that you work to achieve higher levels of programming mastery. This article discusses another facet of deliberate practice: obtaining and maintaining focus on your practice and using coaches and/or teachers to improve your skills.

How to Get and Maintain Focus for Your Deliberate Practice

In this age of attention-grabbing and attention-hogging social media, it is harder than ever to focus on work, especially when it comes to working for self-improvement. There are already enough things pulling at your attention, from necessary things such as your work and your family, to less necessary things such as social media and streaming services. In order to improve your programming skills through deliberate practice, you need to be able to find time and energy for deep work.

Deep work is defined in a book by Cal Newport of the same name as “the ability to focus without distraction on a cognitively demanding task.” To be able to practice further developing your programming skills by going outside your comfort zone, must be able to focus on that practice. So how do you develop the ability to focus.

There are several productivity writers who offer lots of advice on how to obtain and maintain focus. I’ll discuss the ideas of two of these writers, Darious Faroux and Scott Young, in this article.

Faroux says that the way to manage your focus is to manage your attention. First, is becoming a better programmer through deliberate practice a priority for you? If it’s not then it’s going to be hard to focus during your practice time when there are so many other distractions.

Second, can you manage the distractions that are part of your life? Can you control checking Facebook every five minutes? Can you stop checking your email every few minutes even through you know there aren’t going to be any urgent emails? You need to be able to manage distraction in order to find focus for your programming practice.

Finally, if you’re finding it hard to maintain focus than you are having trouble controlling your life. You are letting external events dictate what you do and what you think about. Getting and holding onto focus requires that you be in control of your life in order to prioritize becoming a better programmer.

Scott Young believes that a great way to learn how to focus is to practice meditation, or at least learn about the techniques used in some forms of meditation. Young doesn’t believe that just practicing meditation will make you able to focus better because focusing on a task such as a new programming technique is different than meditation, where you turn your focus inward towards your thoughts and feelings. Instead, learning some meditation techniques such as breathing and focusing your inward thoughts will help you see what is involved in the outward focus you need for deliberate practice.

Young believes that there are two important requirements for developing focus: managing distractions and devoting chunks of time for focus. As with Faroux, Young states that you will never be able to focus fully on your programming practice if you are constantly being distracted by your phone, the internet, or any external stimuli. Your best bet for developing good focus is to keep all devices away from your practice area so that the distraction is out of sight and eventually out of mind.

Once you’ve learned how to manage your distractions, you next need to be able to devote specific chunks of time for your programming practice. This needs to be a time when there will not be any other requests for your attention. Many successful professionals find early morning as the best time for their personal improvement projects. If the morning is not possible, any other time of the day can be used for practice time if you can devote at least twenty to thirty minutes for your practice, if not more. It is a fact of learning science that twenty minutes of focused time in study and practice is better than an hour of distracted study and practice time.

A very popular suggestion for learning how to focus for a set period of time is to use the Pomodoro technique of setting a timer for a set period of minutes where you are going to focus completely on a task and when the timer goes off, take a few minutes break, then reset the timer and start again, if you have the time.

The ability to focus on a task is becoming harder and harder in our society. I strongly suggest you begin practicing developing your focus skills by following the techniques above or researching other techniques that will help you learn how to obtain and maintain the deep focus required for deliberate practice.

Teachers and Coaches

One of the most important facets of deliberate practice is that the learner has access to a coach or teacher who can help him or her develop their skills. As Ericsoon and Pool state in their book on deliberate practice, “you need a teacher or coach who assigns practice techniques designed to help you improve on very specific skills.” (page 100) A good teacher or coach knows what skills and knowledge are necessary to move forward in a field and have experience in designing practice sessions and projects to help advance their students towards expertise.

Teachers

If you are in school, you will have teachers who should be working from a detailed curriculum that is designed to develop your skills and expertise in computer programming. Most introductory programming curricula are designed to do this. The student starts out at the very beginning of programming, working with variables and data, and works his or her way up to designing software using objects or some other advanced technique, all in a sequenced manner where the new skill being learned builds on the previous skills already learned in the course.

Many students fail, however, in fully utilizing their instructors. Students should ask questions outside class, ask for advice on how best to learn the instructor’s material, ask for career advice from their instructors, and just pick the instructor’s brain as much as possible. Most students are afraid to approach their instructors in this manner, but most instructors are thrilled when they get the chance to talk about their field.

Coaches

If you are not in school, you will need to find someone who can act as your coach. The best way to do this is to look at your place of employment or in your area for people who are considered expert programmers. Finding experts in your company will not be too difficult and you can approach them about learning from them, either formally through coaching lessons, or informally by watching and learning from the work they do.

If you can’t or won’t find an expert at work, another place you can look is a programming interest group that meets in your area. The programmers who attend these meetings are clearly people who are interested in advanced their craft and can be a tremendous source of knowledge on expert programming practices. Just attending the meetings and paying attention to the presentations will be beneficial to you, but you may also ask around to see if any of the members is willing to mentor you. I have found that most programming user group members are eager to help newer programmers learn the craft and are more than willing to share their expertise with you.

When seeking out experts, however, you need to keep in mind the advice given by Ericsson and Pool in their book. As studies have proven, professionals with many years of experience in their field often have deteriorating skills when compared to professionals with fewer years of experience. If the professional has not been extending their knowledge through deliberate practice, their skill level has probably decreased from where it was when they had less experience but were still learning.

Computer programming, like many fields, does not have clear areas of expert performance, as do areas such as music performance and athletic contests. This means determining who the experts are in programming is harder than in more performance-based fields. This is where user groups and other meet-ups are useful because you can attend these meetings and determine for yourself who the experts are. Otherwise, you need to talk to co-workers and others in the field to get an idea of who you can approach for a mentoring/coaching relationship.

Another possibility for learning how expert programmers work is to read books that discuss the work these programmers do. A great example is the book Coders at Work by Peter Seibel. This book has interviews with several famous programmers who have designed and built several important and famous software programmers. Included in the interviews are Brendan Eich, the creator of JavaScript, Ken Thompson, the co-creator of Unix, Peter Norvig, who is the director of research at Google, and Donald Knuth, considered the father of computer science and the creator of the Tex document processing language. These programmers, all with others, discuss how they work, what motivates them, and what skills they think are important to become great programmers. This book is well worth reading if you want to become a better programmer by learning how the great ones program.

Programming Expertise Does Not Come Easily

The overall gist of the articles I am writing on becoming a better programmer through deliberate practice is that expertise does not come easily. You have to work very hard at becoming better and two of those ingredients are learning to be able to focus intently on programming practice and on finding a coach, mentor, or guidance in how to focus that practice so that you are working at incrementally improving your programming skills and not just practicing at the same level over and over again.

Become a Great Programmer Through Deliberate Practice: Goal-based Practice

The Goal-Based Programmer

In a past article I discussed how just plain practice is not enough for student programmers to become expert programmers or for expert programmers to continue to perform at an expert level. Gaining and maintaining expertise in programming, as in many other areas of life and work, requires deliberate practice that meets several criteria. My last article discussed how deliberate practice must take the programmer out of his or hers comfort zone in order to make the programmer better. In this article I’m going to talk about another facet of deliberate practice – it must be goal-oriented.

What is Goal-Based Practice?

As Anders Ericsson and Robert discuss in their book on deliberate practice, Peak: Secrets from the New Science of Expertise, people trying to become experts in their field work at practicing their craft toward some type of target performance. For example, for a musician, the goal may be a new piece of difficult music that has always been beyond their capabilities; for an athlete, it may be practice towards a new personal record or a medal in a competition. The point here is this – the effort of deliberate practice is aimed toward some specific goal and not just “toward some vague overall improvement.” (Ericsson and Pool, p. 98)

A musician trying to master a new piece of music will focus primarily on those parts of the piece that are the hardest to perform. They will work at these sections for long periods of time until they are able to perform the section with the same ability they perform already-learned pieces. An athlete, say a mile runner, will spend lots of time trying to build his or her speed by running short intervals many times a week. It is the development of speed that will help the runner win the mile event.

The point here is that, whatever the field, the person trying to achieve expert performance will concentrate their time and effort on the parts of the performance that are the hardest, and once they’ve mastered these hard parts, will combine them with the other sections they have already mastered into a complete, expert performance.

Goal-Based Programming Practice

How can we translate the way musicians and athletes perform deliberate practice towards a goal into something programmers can use to become better at their craft? We can break this down into two different areas – practice for the student programmer and practice for the working programmer.

Goals for the Student Programmer

It is easy to state the goals of the student programmer: learn and practice the various concepts and constructs that allow programmers to build and implement increasing complex programs in the programming language they are studying. We can break this down into three main areas (at least for non-functional languages such as C, C++, C#, Java, JavaScript, and Python): the imperative paradigm; the object-oriented paradigm; and data structures and algorithms.

Programmers first learning a language need to master the fundamentals of writing imperative programs. These fundamentals start at learning how to write simple programs that do arithmetic, using variables to store data. Next they move to decision making with if statements and Boolean logic. The next step is to learn how to perform repetition using while and for loops and the variations of these loop types. Most curricula introduce data structures (arrays and vectors) at this point, followed by functions. The sequence of these constructs moves the student programmer from writing simple, sequential programs to writing more complex programs where the control flow is manipulated using the newer constructs the student is learning. Some topics that are not part of control flow are introduced along the way, from scope to pointers, but this sequence provides the student programmer with the opportunity to practice writing more and more complex programs that improve their skill at programming by continually challenging the student in the difficulty of the material being learned.

The next step for the student programmer is to start to learn more about software design through their introduction to object-oriented programming (OOP). The student first learns how to perform encapsulation via the creation of classes, though some curricula, especially in C++, first introduce OOP via structures. Students learn how to design classes that more closely model the real world and learn how to manage complexity in their programs through the development of classes. The next step at this level is to learn how to leverage classes into hierarchies of objects using inheritance. Some curricula also introduce more formal definitions of composition at this point to make sure students don’t confuse modeling the has-a relationship using is-a concepts. The last step in OOP learning is usually learning how to use polymorphism to effectively utilize inheritance in the effective use of collections of inherited objects.

The last step in programming learning for most student programmers is the study of data structures and algorithms. Study and practice in data structures usually starts with arrays and vectors, moves to memory-managing structures such as dynamic arrays and linked lists, then on to stacks and queues. These are considered the lower level of data structure objects and once they are mastered, students move on to more advanced topics, including trees (b-trees, binary search trees, etc.), hash tables, heaps, and graphs, to mention most of the popular data structures studied. Usually at the same time, but sometimes in a succeeding course, algorithms are studied. Students first learn how to analyze algorithms for efficiency and then learn about the implementation of famous algorithms for sorting and searching data stored in various data structures.

There are other courses student programmers take that will challenge them to improve their skills as programmers – programming languages, compilers, and database courses. All these courses, as well as others, will help improve skill as long as the work is going above the skill level the student already has obtained.

The point of discussing this sequence of topics of study for the student programmer is to point out that in all cases, the material moves from the more basic to the more complex. Students need to master control flow constructs before they go too deeply into data structures and algorithms, and students should have a feel for the design, implementation, and use of functions before they study how to build objects that use functions (methods) in the implementation of their interfaces. If the student programmer continues to challenge themselves by continuing to move to more complex topics, their skills as programmer improve and they become more and more experts of their craft.

Goals for the Working Programmer

The working programmer faces a stiffer challenge when it comes to determining goals for their programming practice. First, there is a time challenge. The working programmer is already working a full day doing the various tasks programmers do, making it hard to find the time to improve their skills. Also, many of the programming tasks they perform day-to-day don’t really work to improve their skill since the level of coding they are doing is usually at the same level of what they are already do well. The challenge is to find time and find projects that push your skill level up. I won’t discuss finding time for deliberate practice in this post. That’s a whole topic. Instead, here are some ideas for programming projects that will challenge you and further develop your skills.

Learn a New Programming Language

The first idea is to learn a new programming language. If you work primarily in Java, learn Python. If you work primarily with JavaScript, learn C++. If you work primarily with object-oriented programming languages, learn a functional language such as Scheme or Haskell. Another option would be to learn one of the newer systems languages meant to replace C++ – Rust or Go. There are many, many programming languages you can learn. Pick one and spend a few months learning it.

How do you learn it? One way is to pick a project you’re currently doing at work and implement it on the side in the new language. If this isn’t possible, pick your own project and develop it with the new language. Having trouble deciding what project to work on? Develop a game. I like to learn a new programming language by developing a simple tic-tac-toe game in that language. Tic-tac-toe can be written using most of the features you need to learn about a new language – making decisions, performing repetition, modularizing the code with functions, and encapsulating the game in a class. I usually develop these games as console applications but if you want to get ambitious, you can also learn how to implement graphics in the language and build a graphical user interface for the game.

Build Something New in Your Current Language

If, on the other hand, you want to get better at the programming language you are currently working in, you can work on something new in that language. The key to this is that it needs to be something challenging. Is there a data structure you don’t use regularly in your work but might help out on some of your projects? Write a program that utilizes the data structure. Are you curious about how the hash table that underlies the data structure you’re currently using works? Design and implement your own hash table class. There are an unlimited number of projects you can work on to build your expertise in your current programming language. The project just needs to be something you are interested in and that will challenge you by extending your knowledge and skills beyond where they are right now.

The Key to Gaining Expertise is to Continually Have New, Challenging Goals

Once you’ve decided you have learned all you can learn, your skills start to stagnate and even decrease. This phenomenon has been observed in professionals in many fields, from artists to physicians. The key to gaining expertise in programming, and the key to retaining that expertise throughout your career, is to continually challenge yourself with new goals. It is not enough to just work at the level you are currently working at – your skills will atrophy. The old saying, “Grow or die,” can be replaced with this saying, “Grow your skills continually or those skills will die.”

Computer Programming Textbooks Suck: At Least Many of Them Do

I have been teaching computer programming to college students for over twenty years. The one thing I have found consistent over these years is that most computer programming textbooks suck. They don’t help students learn, and in my opinion, are mostly harmful to their readers.

Why Programming Textbooks Suck

The programming languages that suck suck in many of the same ways.

Textbook as Swiss Army Knife

The sucky programming textbook crams as many features into a concept or technique as possible. For example, a very popular textbook on C++ programming has a table that displays all eight possible integer data types, from short int to unsigned long long int. The working programmer surely needs to know and understand all these integer data types but the student programmer just needs to know one – int.

Textbook chapters combine too many features.

When learning how to program, especially when it is the person’s first language, the author should not combine several different concepts into one chapter. For example, one textbook introduces data types, variables, statements, arithmetic operators, comments, and scope in a single chapter. That is far too much material to be taken as one unit and should be broken up into at least two or three more chapters.

Textbook authors don’t use modern learning techniques.

Learning science and computer science education researchers have introduced many new techniques for students to learn computer programming. These techniques include interleaving, developing concept maps, working Parsons Problems, teaching how to read code before writing code, and many, many more techniques I’ll be talking about in this blog. Programming textbook authors are still teaching programming the old, let’s write “Hello, world!” way.

Textbook authors, who are mostly college instructors, don’t spend a lot of time writing programs in the textbook’s programming language.

I can say this with authority because I am a college instructor and I know how hard it is to find time to really write meaningful code. We spend most of our time now teaching, grading, advising, and serving on committees, not writing programs and working to advance our craft.

Textbook authors are often late to pick up changes in how professionals are using the language.

Since most textbook authors are college instructors, and they are busy with their teaching jobs, they don’t have the time to stay current in how professionals are writing code. I have seen this happening in C++ textbooks over the years. Professional C++ programmers have been choosing vectors over arrays for many applications for quite a while now because working with vectors is less error-prone than working with arrays, but until recently most C++ textbooks have covered arrays first and only mentioned vectors in a later chapter on data structures.

Another example of this is the use of blocks for all if statements, not just blocks that include multiple statements. I remember that when Douglas Crockford first published his book on the good parts of JavaScript, he advocated using blocks for all if statements. That was in 2008. Since then, many other programming professionals have adopted this use; Google has it in their style guide. And yet, most current programming textbooks aren’t advocating it. To me, this borders on professional malpractice.

Some textbook authors use questionable programming practices.

A very popular C++ programming textbook demonstrates how to write for loops by declaring the loop control variable outside the for block in many examples before finally, at the end of the section, demonstrating how to initialize the variable inside the block. This is deceiving to the student because most for loop variables should be local to the loop block and not be available outside the loop.

Another example exists in the JavaScript textbook world. Authors are still using var to declare variables in most situations when, since ES6 came out a couple years ago, it is now more advisable to use let to indicate local scope. There are lots of examples of this in textbooks on many different programming languages. In most cases, this happens because the author is not working that much at programming but very hard at textbook writing.

How Programming Teachers Support Sucky Textbooks

Those of us in the programming instruction business are largely at fault for the state of programming textbooks. Here are some reasons why.

Programming instructors are too busy to develop materials themselves.

Programming instructors are very busy people. If they work at a four-year college or university, they are probably either graduate students who are also working on their graduate degrees, or they are junior instructors working hard to get tenure through research and publishing, along with their other college commitments. They don’t have time to develop their own materials and instead rely on programming textbooks that supply all the material for them.

Programming instructors are too reliant on the exercise sets in textbooks.

Teaching people how to program involves having students work lots of exercises and problems. It takes time to develop these exercises and to also develop their solutions. For the busy college instructor, it’s a lot easier to rely on the exercises and problem sets found in textbooks, along with the solutions that many textbook authors and publishers provide.  

Not All Programming Textbooks Suck

There are some good textbooks for learning computer programming. I am primarily thinking of the “How to Think Like a Computer Scientist” series by Allen Downey. This series includes books for Python, Java, C++, and other languages. These books present material at the right pace and Downey recognizes that busy students, whether in school or learning on their own, are not going to read a 1000 page book or be able to effectively learn fifteen new programming language features every week. You can read more about Downey’s textbook philosophy at https://greenteapress.com/wp/textbook-manifesto/ and you can find his books at https://greenteapress.com/wp/.

What’s the Solution?

The best solution I’ve been able to come up with is for instructors to use trade publications as textbooks and either provide their own problems and solutions or find a resource that can provide problem sets and solutions that independent from any textbook. Having students read trade publications gives them exposure to the current practice in that programming language, written by programmers who are writing code daily. There are many examples in a variety of programming languages: C++ Primer, by Lippman, Lajoie, and Moo; Head First Java by Sierra and Bates, or Thinking in Java by Bruce Eckel; Python Crash Course by Eric Matthes or Head First Python by Paul Barry; A Smarter Way to Learn JavaScript by Mark Myers or Eloquent JavaScript by Marjin Haverbeke.

All these books take a non-textbook approach to teaching their respective programming language. Some provide exercises in the book and at least one, A Smarter Way to Learn JavaScript, provides exercise sets at the author’s web site. Several of these books also provide more information about the language at their web site.

It’s easy to say that because there are so many good online resources for learning programming now, from online tutorials to online video channels, programming language students don’t need books for learning how to program. I believe, though, that learning through reading is going to be an important element of every programmer’s career so they need to develop the ability to learn through books early on. Learning well, though, requires the right resource and steering you towards those resources is my goal in writing this article.

Become a Great Programmer Through Deliberate Practice

Become a Great Programmer Through Deliberate Practice:

Just writing code is not enough


By now, most of you have heard of the 10,000 hour rule. To become an expert at something, anything, it takes 10,000 hours of work or practice. This rule was popularized by Malcolm Gladwell in his book Outliers. However, it’s not just any sort of practice that will make you an expert at something – it’s 10,000 hours of deliberate practice, that is, practice that is not just mindlessly doing the same thing over and over again, but conscientiously practicing harder and harder tasks that extend your ability. In this article, I’m going to introduce you to deliberate practice and how you can apply it to learning computer programming. In future articles, I’ll dive more specifically into ways of using deliberate practice to improve your knowledge and skills in any computer programming language you choose to work in.

How is Deliberate Practice Different Than Just Plain Practice?

Everyone knows what it means to practice something. You want to improve a skill so you perform the skill continually until you feel like you’ve perfected it. The problem is that most people practice by doing the same thing repeatedly. This doesn’t lead to becoming an expert in a field; it just makes you better at that task. And in many cases, especially when practice just means doing the task professionally, you will get worse at the skill over time. In the book Peak: Secrets from the New Science of Expertise, Anders Ericsson discusses how, in studies on the quality of care provided by physicians, those physicians who have been practicing for many years do worse than physicians only a few years out of medical school. Why is this? Ericsson contends that it is because, rather than practicing deliberately, physicians are mostly going through the paces when they are performing their tasks rather than working to sharpen their diagnostic skills by working on new, harder cases.

The same is true in many other skills. People who take up a sport, such as tennis, will at first practice a lot and get better at better at the different skills involved in tennis – serving, forehand strokes, and backhand strokes. Most people, though, will reach a point where their tennis game is sufficient for their needs (they can win a few matches or at least look like they know what they’re doing), but they don’t really become expert at the game. In fact, over time, their tennis playing skills will atrophy somewhat, even if they are playing tennis matches on a regular basis, especially if they are playing the same opponent or opponents of the same skill level.

Psychologists who study expertise have found this true for many different skills and professions. Practicing, or performing, in the same manner over a long period of time does not improve your skill in your chosen field, in fact, your skill level will drop over time unless you modify how you practice and adopt the mindset of deliberate practice.

Deliberate Practice Defined

There are several characteristics that distinguish deliberate practice from regular practice. These are discussed in detail in Ericsson’s book and I will just outline them here:

  • Deliberate practice requires an effort that is outside your current comfort zone.
  • There needs to be a well-defined goal, such as improving a skill leading toward a specific event or performance.
  • Deliberate practice requires extreme focus and should follow a plan designed, at first by a teacher or mentor, and later by the practitioner on his or her own.
  • Deliberate practice requires that the practitioner receive feedback. This feedback should first come from a coach or mentor, but later practitioners must learn how to provide their own feedback.
  • Deliberate practice requires the use of effective mental representations of the skill involved.
  • Deliberate practice will always work to build on an existing skill and improve the skill incrementally. Doing this over and over will lead to expert performance.

Great Programming Through Deliberate Practice

So how can you use these principles of deliberate practice to become a great programmer? Let’s look at some of the principles above to see some ways we can apply them to learning to program as experienced by someone who has perhaps already taken one course in programming, say in JavaScript.

Deliberate practice requires effort outside your current comfort zone.

Let’s say you are learning about loops and arrays. You’ve already written several programs that display the elements of the array or sum the elements of a numeric array. You need more challenging problems. One place to look is codingbat.com and the AP-1 section. Here you will find several problems that are more challenging than you will find in most introductory textbooks. The problem solutions are in Java or Python but the problems are suitable for any programming language. They provide sample inputs and outputs (feedback) so you can know if your program is working or not. There are also many excellent books that present programming problems for you to work. Caution: selfish promotion ahead. I have several of these books in the works, which I’m calling my Worked Problems series. See my website thelearningprogrammer.com for more information.

Deliberate practice has a well-defined goal.

If you are currently a student enrolled in a course, this one is easy. The specific event or performance you are working toward will probably be either a test or a project. If you are a self-taught learner, this one is a bit harder. One of the things I do with my students is ask them to re-write some of the library functions in the programming language they are learning. These functions usually require knowledge of more than one programming construct so you are getting great practice in several areas in one program.

Deliberate practice requires extreme focus and should follow a plan designed, at first by a teacher or mentor, and later by the practitioner on his or her own.

Again, for a student enrolled in a course, the instructor will have a plan laid out for you that usually involves working with a textbook and the exercises in the textbook and/or exercises and tests the instructor creates. If you are studying on your own, you can follow a book on the language you are learning. If you don’t want to purchase a book, there are many free computer programming textbooks online you can download, as well as tutorial sites such as tutorialspoint.com and w3schools.com you can use as a guide into the language. A problem with books and textbooks is that many of the non-textbook books published don’t have exercises for you to work, and the textbooks that do come with exercises often don’t provide solutions to the exercises. Again, I’ll refer you to my website for a series of books that provide both problems for you to work and solutions you can use as feedback.

Deliberate practice requires feedback, first from coaches than from yourself.

Students in a high school or college course will get feedback from their instructor, though sometimes the feedback takes time to get back to them as programming instructors are usually very busy and are often teaching many students. Other sources for feedback include experienced programmers you know and problem sets that include solutions to the problems. One advantage of learning programming by implementing library functions is that you can use the built-in functions output as feedback for your learning. If your program has the same output as the built-in function, you at least know your program is working in that respect. My Worked Problems series is being written with providing feedback through worked computer program examples in mind for the self-taught programmer.

Deliberate practice requires the use of effective mental representations of the skill.

The least concrete of all the deliberate practice principles is the concept of mental representations. One of the definitions of being an expert in a field is having superior mental representations of your subject. The classic example is chess players. Master level chess players have memorized thousands of chessboards at various stages of chess games through the careful analysis of different parts of chess games played by other master chess players. They don’t develop this skill through playing more games of chess. In programming, you can study how great programmers write programs by studying open source programs and by reading books on writing good programs. Two such books are Beautiful Code, edited by Andy Oram and Gregory Wilson, and Code Reading, written by Diomidis Spinellis. Learning to program by reading great programs is not emphasized enough and every programmer should spend time reading examples of great programs, especially in areas that are outside your usual programming experience. Studying these programs will help you develop good mental representations to use in your own programming.

Always Be Learning

One of the most important skills, if not the most important skill, all budding programmers should be learning is how to learn. It’s a cliché to say that technology is constantly changing but in fact it is. Learning how to learn through deliberate practice will help you stay on top of ever-changing technology. More importantly though, becoming better at your craft of programming should be the goal of every programmer. You should be constantly trying to achieve the goal of being an expert at designing and implementing computer programs and the best way of achieving that goal is through deliberate practice.

In future articles, I’ll be elaborating on how you can become a great programmer using the concepts and strategies of deliberate practice as well as other learning and practice techniques.

Welcome!

Welcome to The Learning Programmer. This blog is going to explore the different ways that computer programmers can learn more about their craft. I will delve into many different learning strategies, such as deliberate practice and ultra learning, so that you can improve your programming abilities. I will also provide courses and resources for learning programming languages, as well as techniques for teaching computer programming to yourself and to others.

I am always interested in what my readers what to learn more about, so please don’t hesitate to email me at mmmcmillan1@att.net with suggestions for future articles, courses, or tips for becoming a better computer programmer.