Learning Online

September 29, 2014

That we’ll learn school-ish things on the internet seems inevitable, but most people seem not to learn very much or very quickly online; Sebastian Thrun admitted as much in a Fast Company interview a few months ago. To figure out how computers actually could help people learn, I spent the summer teaching students and building software.

This post is about the summer: how much students learned, the software I built that helped them, what worked and didn’t, and where I think we should go next.


AP Computer Science seemed a good place to start. We’re still pretty bad at teaching programming, and programming presumably lends itself more naturally to computer-aided pedagogy than, say, geography. Programming is also horribly — and unnecessarily — unfriendly to beginners.

It takes eight months in a classroom to cover the AP Computer Science curriculum. It took me 20 hours in person or over Google Hangout to do the same. I’m neither brilliant nor in possession of a killer methodology; learning is still hard – very hard. And though the software I built helped (I needed to explain, debug, or unstick each student less as it improved) students still had to slog through problems they’d never seen.

The College Board offers a standardized curriculum for the AP CS class and an annual test. High test scores often grant college credit at a public university – which means, very tangibly, needing fewer credits and tuition dollars to graduate – or a “you took a hard class” gold star (though no credit) at a private university.

The AP Computer Science curriculum is standardized and small; it’s an introduction to object-oriented programming in Java that stops at ArrayLists.1 It’s unimaginative, but there’s curriculum, textbooks, and labs scattered online. I ended up centralizing some of the best I found and made in a free, open-source repository: Teach APCS

Java is a poor language for beginners; its syntax is obtuse and foreign-looking, it makes graphics unnecessarily tedious, and it requires the heavy Java Virtual Machine. But because it’s the language of the AP test, more schools teach it, and it’s a better choice for beginners than learning nothing.

For all the hemming about programming languages, the hardest part for these students was solving puzzles in English, not Java. Often, they’d skip to the Java, glossing over their logic. This didn’t work, but “forget Java for a moment; what are you trying to do in English?” and “How would you explain what you’re trying to do to a 5 year-old?” were the two questions most likely to unstick them. Once they explained the logic – “go through all the letters. If you find an A, swap it with the prior letter” – the Java came easily.2

Why code?

The AP Computer Science test is a carrot for high schoolers, but it’s not a very tasty one. The students who take the class either have been coding for awhile, though probably not in Java, or are motivated by the AP credential but don’t yet understand computers.

Before beginning, I asked students what they wanted to make, if they could make anything:

  • “I would make an app that would help people in need.”
  • “Animate a film”
  • “An awesome videogame”
  • “Time machine”
  • “a tool to learn a subject on your own if you are unhappy with the class in school that the school would accept for credit.”
  • “An application that helps improve networking on many different things.”
  • “A train network that was fast, efficient, and safe, and connected all of the us with minimal stops.”
  • “I would make a cure for cancer, that causes no pain for the patient.”

Some of those ideas lend themselves better to software than others, but more striking, I thought, was how general they are; there’s no “I’ve been dreaming about making an app that does X” or “I really want to make a webpage for Y, this idea I’ve had.” So many of today’s learn-to-code tools focus on making specific apps or sites, but these high schoolers hadn’t figured out what they wanted to make yet. They just thought coding might be fun.

Why not code?

Scary “code or be coded” rhetoric haunts some of today’s learn-to-code initiatives, which is ridiculous; you shouldn’t learn to code if you don’t actually want to. You’ll not be eaten by computers any more than folks were eaten by electricity 100 years ago.3 More practically, learning anything new is hard, and Catholic guilt (“Oh, I really should learn it though ... ”) isn’t enough.

I don’t mean to be dissuasive though; writing software can be excellent, and — I feel strongly about this — you should know you can do it should you want to.

Meta learning

Overall, it was surprising how quickly students learned. Those who hadn’t yet learned calculus seemed to learn faster, which isn’t crazy: variables and functions in math and CS are related but not the same, but students who weren’t confronted with the difference didn’t think about it.

By the end of the summer, the stronger students were those who had made more mistakes: they’d tried more things, compiled more bad code, hit more runtime errors, and confused the REPL more soundly. Their banging produced better mental models, so they could anticipate what code would do when run. (If environments like Xcode Playgrounds and LightTable succeed, tracing through full programs in your head might become a party trick, but it’s necessary today.) When students experimented in logical ways, they developed confidence in solving problems with code.

Undirected banging (aka “type random things and maybe it’ll eventually work?”) is worse than unhelpful; it’s demoralizing. Without any ideas for how programming’s pieces hang together, computers are incomprehensible. Letting a motivated person loose, unguided, on today’s programming tools is probably the fastest way to exasperate her.

What we did

Tutoring started with two hours of guidance through a REPL, with only primitives, no variables, to impart a sense of the underpinnings of programming. (“Why’s division weird? When you fire up a random number generator, how long until you can get a random number? How does substring work exactly?”)

A REPL is a simple environment to explore tools; inside one, it’s easy to try new things, and messing up doesn’t break anything or take much time. The REPL’s prompts, honed by tutoring, introduce new tools and suggest things to type. Hitting return runs an experiment, and the feedback’s instant. Students quickly began to develop a mental model of what it means to talk to their computer. Here’s an automated version of what I did:

REPLs are limited — no one writes a full program inside one — so we moved to simple scripting in the editor. We used code snippets that built on the tools they’d learned in the REPL, like this one:

int wallet = 100;
System.out.println("I have $100");

while(wallet > 0){
    wallet = wallet - 25;
    System.out.println("Spent $25.");

System.out.println("No money left!");

That’s Java written to be understood, without nice things like graphics, a visual language, or step-through evaluation. Before being run, the snippet was wrapped in a main method and class so only one new thing — while in this case — appeared.

When you ask a new programmer what that code does, she’ll probably tell you it “Spends all the money in the wallet and then tells you there’s no money left.” Ask how many times it’ll spend $25, and she’ll say 4. Indeed, that snippet prints:

"I have $100"
"Spent $25"
"Spent $25"
"Spent $25"
"Spent $25"
"No money left!"

Then, ask her to modify the code so that it prints what’s in the wallet immediately after it spends $25:

"I have $100"
"Spent $25. I have $75."
"Spent $25. I have $50."
"Spent $25. I have $25."
"Spent $25.  I have $0."
"No money left!"

Change the code a few more ways; each time, the student’ll get more comfortable with the while tool. Piecemeal introductions, like this one, allow learners to build up a set of tools and the skills to use them.

Tools in hand, we began solving puzzles; students made Magic 8 Balls, Bitcoin, Hangman AIs, Chatterbots, and more. They made these things on their own, using the tools they knew, and their successes were sweet because they took work. Here’s a speedy video of a student solving FizzBuzz:

Early conceptions of computers’ power focused on machines’ ability to augment human intellect, but some learn-to-code initiatives seem to take a dim view of learners; they preference typing over problem solving, and their “problems” deal with swapping variable names or values. Ask people to re-type or edit text in single-line text boxes, and they’ll do so really quickly — but they’ll only become bored. Equip people with tools, then ask them to solve puzzles — even trivial ones, like FizzBuzz — and learning might become valuable.

Tools that helped

A beginner who’s never ridden a bicycle doesn’t want training wheels; she wants a rideable bicycle. Similarly, I don’t think there’ll ever be a successful beginner’s editor; there’ll be editors that beginners can understand that programmers use too.

Unfortunately, most editors aren’t so smart and aren’t so easy to use. Their standard interface is borrowed from the command line, which is neither friendly nor forgiving, and it doesn’t acknowledge what makes code different from text. What you actually want is an editor that’s both smart and easy to use.

Here’s a few ways editors can be nicer for everyone, including learners. All the demos take place in an environment I made, but the same principles could be applied elsewhere:

Code Snippets

Go directly to the tools that interest you. They’re grouped by what they do rather than what they are because that’s how you think anyway.

When you click one, it’s inserted into the editor, as you see it — example text and all. (Autocomplete snippets work the same way.) The placeholder text gives a starting place; it’s a lightweight nudge to recall how things work.

Inline REPL

As you type in the editor or use code snippets, that code’s loaded into the REPL. The interplay between the REPL and the editor lets you chisel your code as you write it, which is powerful; you need not wait until it’s done to use, and you can experiment as you’re coding in a way that’s not possible otherwise.


Every word in the editor explains itself when you hover over it; these make code more understandable, so you can concentrate on genuine programming concepts rather than fancy terminology. They transform the editor from a dumb mirror to a more helpful guide, and they’re especially helpful to those unfamiliar with programming’s 10-cent words. They’re not meant to replace formal instruction though; if you’ve never heard of static methods, but have to use one, a tooltip probably isn’t going to explain enough. But the tooltip does give a better starting point than a confusing term amongst a sea of confusing terms.

Variable explorers

Two of the trickiest concepts for this summer’s programmers were variables and variable scope. Prior environments have tackled these with variable boxes and colored method backgrounds. In my experience, neither were quite right. The best explanation I found was showing variables directly in an explorer. Then the environment tracks the variables and values, underneath a header of where they’re seen. It also leaves the computation to the computer.

Lints and error translations

Lints and errors help, so long as they’re comprehensible. That often means parsing text from compilerish to English. (When tutoring, this was one of students’ primary frustrations — “yes I know my program is broken, but I can’t understand what you’re telling me about it being broken.”) There’s good reasons that compilers speak compilerish, but there’s very few good reasons for humans — especially those starting out — to learn compiler.

Comparing classes to spreadsheets

Classes are strange and seem useless at first. The analogy that works — and that everyone understood — is spreadsheets. A class is a sheet, its attributes are columns, and constructing an instance means filling in a row. Here’s a simple example:

Here’s a few instances:

Going forward

Much tutoring and building later, the idea became simple: if you show people how programming works, and guide them toward thinking systematically, they’ll learn on their own. Most programming tools don’t help students think through logic, experiment quickly, and recover from failed experiments, but they should. It’s what the fastest learners do on their own.

I’m optimistic there’s more to do in online education, across subjects, especially when we think about inciting and feeding students’ curiosity. Allowing students to mull puzzles and stumble on solutions worked for me this summer. That’s not a new idea; Seymour Papert’s Mindstorms — published in 1980! — advocates it. But it seems not to have been pursued whole-heartedly, and my summer implies it has a good chance of succeeding. We’re still in online learning’s early days, and we can already see glimpses of what works; we just have to let students guide us.

Try beta software and stay updated

Contact me

If you’re interested in working on these tools, let me know.

I tutored some students for free — generally, girls who’d attended a Girls Who Code summer camp and wanted to keep learning — and some students for fee — generally folks who replied to my Craigslist ads. I also help teach an AP CS class in an SF public high school through TEALS. Some of the teaching is in Java, and some in Python, but it all hewed to the material on TeachAPCS.

[1] What’s left? you might (reasonably) ask. Not much. There used to be more — searches, sorts, preliminary Big-Oh, Hashes, and LinkedLists — but the College Board dropped all that because so few students took the test. But that’s not quite fair; it wasn’t the students’ fault. So few students took the test because so few teachers taught the material.

[2] When you start programming, you quickly realize how much intuition you have — and how much a computer doesn’t. What, for example, does it mean for two things in a list to be adjacent?
“Two things are next to each other?”
“How do you know if two things are next to each other?”
“(Because they’re next to each other? )”
“What if you have them in an ordered list already? Then how do you know they’re next to each other?
“Their positions in the list are one off?”
“Okay ... what does that mean?”
“Well, the thing in list position 2, what’s that next to?”
“The things in positions 1 and 3?”
“So it’s like position number plus one and position number minus one?”
“Ah, okay, in that case ...”

[3] If you’re interested in this sort of thing, you absolutely should read Ernest Freeberg’s The Age of Edison: Electric Light and the Invention of Modern America, which includes gems like:

Electricians often joked about the public’s “wild views” about electricity, but some in the industry considered this ignorance no laughing matter. Journalists and politicians with half-baked ideas about electricity were bound to demand the impossible from electric companies and stir up public fear and resentment against their business. Better education seemed the answer, and many industry leaders called not only for technical training for electrical workers and engineers but the addition of electrical science in the high school curriculum. The public’s irrational fear of electric power was bound to fade, these men hoped, when “wider education” gave more Americans a chance to explore and understand electricity for themselves.


The [electricity] industry had much to gain, of course, from what it called this “high mission,” since it would cultivate young people eager and able to contribute to the growth of the business. By the turn of the century, various electrical trades employed nearly a million people, making electric light and power one of the nation’s largest and fastest-growing industries. Progressive educators did not care so much about producing good employees for the electric companies, but they agreed that every American student should receive at least the rudiments of a technical education.

The most solo-seeming efforts often owe the most to others. Tremendous thanks to: Barbara Andersen, Ryan Bednar, Tom Blomfield, Christina Bognet, David Boylan, Libby Brittain, Avi Bryant, Britt Caputo, Gary Chou, Peter Coles, Patrick Collison, Harold Cooper, Leigh Ann DeLyser, Georges Duverger, Eric Florenzano, Pamela Fox, Leo Franchi, Avichal Garg, Elad Gil, Erik Goldman, Jonah Greenberger, Marc Hedlund, Oliver Ho, Bob Ippolito, Vichi Jagannathan, Joy Kesten, Nina Khosla, Evan Korth, Sasha Laundy, Dana Ledyard, Greg Leppert, Roxanne Leung, Roddy Lindsay, Ted Lee, Hannah Ma, Amjad Masad, Naseem Makiya, Ben Newman, Akshay Patil, Peter Pawlowski, Ben Plesser, Jason Prado, Geoff Ralston, Myles Recny, Josh Schwarzapel, Star Simpson, Jon Steinback, Matt Spitz, David Tisch, Matt Wahl, Albert Wenger, Ryan Williams, Fred Wilson, Tash Wong, Christine Yen, and Ivan Zhao.