Programming is Taught in Exactly the Wrong Way

22 Oct 2018

This story was featured on Medium.com. Please check it out over there.

I learned programming through a relatively unorthodox method. I wanted to make a video game for my high school senior design project, and I found myself on the Unity3D learn page. If you’re unfamiliar with Unity, it’s basically a framework for creating 3D video games and involves some scripting in C#. It provides a game engine and an interface for manipulating game objects and assets, so you can intuitively put everything together. Unity is very well documented and provides a healthy amount of resources for learning how to develop with the platform.

However, this was not an easy way to learn how to write code. I did not know the first thing about a program, and the tutorials go pretty fast without very much in-depth explanation of the process. I could follow along easily enough, but when it came time to write code of my own, I was met with hours of frustration. Every time I tried something, it didn’t work. I was unable to efficiently identify the cause of any problem, and I would take an entire day or even a week to scour the internet for a kernel of understanding.

Despite the frustration, it turns out that this was the best way to learn how to write code. The unwavering sense that I was totally lost motivated investigative problem solving and prepared me for the daily struggle that comes along with programming. The key characteristic of this experience was this: I had a clear directive. I already knew exactly what the video game was supposed to look like because it was an adaptation of a board game that I created for a different school assignment. The challenge was translating it from physical game pieces to lines of code.

When I was working on the game, I knew what I was trying to do. I knew that, for example, the game needed to have cards. Each card behaved a certain way and was associated with certain values. I just had to figure out how to represent these behaviors and states in C#. This is exactly where the classical method of teaching programming goes wrong.

Programming is usually taught by starting with the simplest idea (variables) and working towards more complex ideas (methods, objects). It makes sense to approach it this way, but it is incredibly ineffective. Before I go any further, I would like to point out that I am primarily talking about the instruction of object-oriented programming (and I will be using Java as a specific example) but the main idea of my argument is applicable to other modes of programming as well.

As a teaching assistant for the intro-level computer science course at my university (Introduction to Java Programming), I have worked with dozens of students who are being introduced to programming. The course is structured like so:

  1. Variables and types
  2. If/else statements
  3. Loops
  4. Arrays
  5. Methods
  6. Objects and classes

This structure is bottom-up. The students start with something simple: what is a variable? Then, they work up to something more complex and abstract: what is an object?

In the Introduction to Java Programming course at my university, the students are currently experiencing step 6 — which is learning what a class is, what an object is, how to write classes and constructors, instantiate objects, and use these things to do something useful. As you might imagine, this point in the semester represents a major shift in the way that a student understands programming. It is very challenging to make this transition. If everything goes right, the struggle leads to a more wholesome understanding of how Java works. However, it is an unnecessary threat to the student’s understanding and enjoyment of programming.

This way of teaching programming is completely backwards. Object orientation is the programming paradigm that the students must carry forward, but it is one of the last ideas to which the they are exposed. Variables, methods, loops, and if/else statements are nothing more than the tools that we use as programmers to define a class — but we often teach how to use these tools without explaining why they exist.

Instead, programming should be taught top-down like so:

  1. What is an object?
  2. What is state? What is behavior?
  3. How do we represent the state and behavior of an object?

There are two reasons this structure is superior. First of all, it puts the student in the object-oriented mindset from the start. This allows the student to tie every new thing that she learns back to the idea of an object, instead of being forced to cram a bunch of random things that they have learned into an object. Psychology teaches us that we learn best when we are able to connect the ideas that we are learning to something that we are already familiar with. It’s difficult for a student to connect the idea of a variable to something with which he is already familiar. The idea of an object, on the other hand, fits perfectly into a student’s understanding of the world. We should take advantage of this from the beginning. The very start of any object-oriented programming course should pose this question: how can we use a computer to represent information that exists in the real world?

The unattractive aspect of a top-down structure is it does not allow students to begin programming right away. A student will not be able to sit down and write a class just because she understands what it is supposed to do. The student must instead begin by learning the abstract concepts that guide their development as programmers without programming. This method of instruction, though seemingly backwards, is far superior to the traditional method. It gives students the clear directive that allows them to have a higher-level understanding of programming and be more purposeful with their work.

More concretely, this method addresses one of the greatest challenges associated with learning programming. When a student is just getting started with Java, he might be shown something like this:

public class HelloWorld {
    public static void main(String[] args) {
        String message = "Hello world!";
        System.out.println(message);
    }
}

If you have any experience with Java, this is easy enough to understand. If you’ve never seen a piece of code before, it may as well be mandarin. Nonetheless, the student is taught: message is a variable of type string that holds “Hello world!”, and System.out.println(message) prints the value of the variable to the console. The student is told, “Don’t worry about the ‘public class HelloWorld’ or ‘public static void main,’ you will learn more about them later.” The student is expected to take the instructor’s word for it, and continue to use these statements without understanding what they do or why they are necessary. But hey, he knows what a variable is!

Later on in the semester, the students are required to loop through each character in a string and check if it is uppercase. They must produce something that looks like this:

public class HelloWorld {
    public static void main(String[] args) {
        String myString = "Java Programming Is Fun!";
        for (int i = 0; i < myString.length(); i++) {
            if (Character.isUpperCase(myString.charAt(i)))
                 System.out.println(
                 "Uppercase letter at index: " + i;
    }
}

For this assignment, the student must use: a class definition, a main() method definition, a string object, the length() method, the character wrapper class, the isUpperCase() method, and the charAt() method, and the System.out.println() method without having any idea what a class or method is or why they are important. They are once again expected to take the instructor’s word for it… “charAt() gives you the character at the specified index, don’t worry too much about how or why…” because the point of the exercise is to practice loops. You could certainly argue that this is simply a terrible assignment, and I would agree with you. The point remains, however, that it is very difficult to do anything in Java without using objects and methods. This is quite confusing, and feels pointless, if you don’t have any idea what an object is or what a method is. Why doesn’t the course start with these ideas? The bread and butter of object-oriented programming should be introduced at the beginning of an object-oriented programming course.

Thanks to Grace Quereau.