Learn Java, they said. It’s easy, they said.

As a recent graduate from the University of Wisconsin-Madison Computer Sciences Department, I have tutored a lot of friends and acquaintances through the Introduction to Programming course at UW, which uses Java. This is hardly unique — many universities have switched to Java in the past decade (usually from C++), along with the AP Computer Science curriculum, which switched to Java in 2003. A study done for the ACM in July 2014 indicates that of the top 39 U.S. CS programs, 22 of them use Java in some introductory course.

So, what (ostensibly) makes Java such a good teaching language? Looking at various sources, we can pull out a few common arguments:

  1. It has a relatively simple syntax (compared to something like C or C++) with few gotchas (again, compared to something like C or C++). Simpler syntax means fewer rules to explain to newcomers.

  2. Java makes it much harder to shoot yourself in the foot than more traditional teaching choices like C and C++. Many operations are automatically checked. Attempting to access an array out of its bounds or using a null object produces an exception, which, if left unhandled, stops the program cold with a nice stack trace telling you what went wrong and where it went wrong (down to the very line of your source file that caused the problem). Compare this to C or C++, where accessing a null pointer makes your program explode in your face without any helpful hints (unless you’re running it in a debugger, but then you have to learn how to use a debugger). Going past the end of an array in C or C++ is even worse, since in many cases it will just silently write over whatever was after the array in memory. Then your program crashes 20 lines later, your variables have mysteriously changed values, and you have no idea what’s going on. Madness ensues.

  3. Garbage collection means you never have to explicitly manage memory. You allocate an object with new, it lasts “forever” (i.e. as long as you have a reference to it somewhere in your program), and then when you’re done using it, it eventually gets cleaned up for you.

  4. Java is very widely used in the industry, so in theory, the skills learned in school transfer directly to real jobs. The TIOBE Programming Index lists it as the second most commonly used language. Regardless with whether you agree with TIOBE’s exact analysis, it is hard to argue that Java isn’t widely used.

  5. Java is object-oriented. You create objects that contain data and then write methods that describe actions you can take on that data.

All of these are true enough, but they don’t tell the full story.

Gratuitous handwaving

The first program almost any programmer writes in any language is “Hello World”. All it does is display some message (traditionally “hello, world”) and exits. Simple. Let’s look at Java’s Hello World:

public class Hello {
	public static void main(String[] args) {
		System.out.println("hello, world");

Someone brand new to programming is going to start asking questions, and now you, the teacher, have a problem. Explaining everything at once will likely overwhelm the student, so instead you have to start handwaving.

  • “What does public mean?” Don’t worry about it for now. We’ll talk more about that later.

  • “What is a class?” Don’t worry about it for now. We’ll talk more about that later.

  • “What does static mean?” Don’t worry about it for now. We’ll talk more about that later.

…and so on.

This is a Bad Thing™. When you teach any subject, you want to break it down into easily-digestible bits that build on top of each other. Encapsulation (the public keyword), object-oriented programming (classes and static), arrays (String[]), and command line arguments (args) are all important things that should be explained in due time. But to someone fresh off the bus who is trying to figure out what a program is and how one works, this is too much ground to cover on day 1. I have seen many friends, who are absolutely brilliant in other arenas, flounder about when all of this gets thrown at them. It’s like being introduced to algebra with something like

f(x,y)=i=1xi2yf(x, y) = \frac{\sum\limits_{i=1}^{\lceil x \rceil} i^2}{y}

Once you know what all those symbols mean, the function is not that bad. But to someone brand new, it’s terrifying. Worse yet, handwaving things early on encourages beginners to dismiss them as “magic” instead of analyzing what they do and how they work. This is the exact opposite of the mentality you want to be fostering as a teacher. On top of the Hello World example,

  • Java is strictly object-oriented and demands that every single function (or “method”, in Java parlance) be placed inside a class. If you have never read the excellent essay Execution in the Kingdom of Nouns, I highly recommend it, but it can be summarized with the quote, “advocating Object-Oriented Programming is like advocating Pants-Oriented Clothing”. Explaining object-oriented design principles to first-semester students who are solidifying their understanding of if statements and for loops is a bad call. Focus on behavior and how to break work down into bite-sized pieces which can be written as functions. Then maybe talk about OOP.

  • Java dictates that all objects be heap-allocated, so all object variables are pointers. Now you have to explain the differences between value and reference semantics, like why int, boolean, and float behave differently than strings when it comes to assignment and comparisons. Complications like this make forming a consistent mental model of how things work — which is essential for a programmer — more difficult.

Java may be an excellent language for developing programs (whether it is or not is outside the scope of this post), but it is certainly not beginner friendly.

So what language should we teach with instead?

So, we want to start with a few simple concepts and build on top of those. Java doesn’t let us do that very well. So where do we turn? There are two starting points that make sense:

  1. Start at a very low level and work your way up. Teach how computers work, then how you can direct them around in C (and possibly assembly). Then, start to build higher-level computer science constructs on top of this.

  2. Start at a very high level and work your way down. Teach computer science theory and use a language that can easily implement it without worrying about the details of the underlying machine. A language like Python is a good choice here, because it doesn’t suffer from the front-loading Java demands. Then, work your way down into how a computer actually implements this theory.

The second approach has been gaining a lot of traction, with Python surpassing Java as the #1 programming language used in introductory courses according to the study mentioned at the start of this post.

Whichever approach you choose, make sure your students have a fast path to doing something they find interesting. Few people are going to be awestruck by some text printing onto a console. If you take the low level approach, get an Arduino or some robotics kit so students can watch their code make things happen in the physical world. I was captivated by programming when I started writing C for a robotics team. Watching 120 pounds of steel and whirring motors move about because of my code was magical. Or, if you take the high level approach, use the myriad of libraries available to make a video game or some other graphical program.

import antigravity

Programming is incredible. You are limited by nothing but your imagination and how you express it. Find something your students find interesting, pick a simple starting point, give them the tools, answer questions when they ask them, and let them run wild.