Monday, August 25, 2014

Time to say goodbye to "Hello World"

If you have taken any programming class in your life, you've probably written a "Hello World" program. When I first learned BASIC, it looked like:


In a modern programming language like Python things often start out pretty much the same. At the "Eliza" lesson, the first program is a "Hello World" program. Most intro programming books still start out with a HW program.

The point of a "Hello World" program is to show the student that they can give the computer a command and make it do something. Then you might write a simple program that asks for your name and says "Hello " + name + ", how are you today?" Then you might write a "for" loop that counts to 10.

And it could be exciting at first.  Sure, you could just tell the computer to say your name now, but pretty soon you'd be writing Ultima IV! It's the same kind of optimism that makes a kid slogging through Heian Shodan in Karate for the first time imagine that if they just keep it up they'll be like Jackie Chan.

But then again, when we were kids it was a lot easier to believe. When I was a kid we played computer games on the Apple II++, almost all of them illegally pirated off pre-Internet bulletin boards we dialed into with modems like Matthew Broderick used in Wargames. Though we couldn't write games like that ourselves, they used simple blocky graphics not too different from the blocks and circles we could draw after a few weeks of learning BASIC.

Some of the games were even written in BASIC, with code that we could see and modify. Most of them were compiled into machine language, of course, but even those could be tinkered with by getting a hex editor program and screwing around with the code. We were mostly trying to break the copy protection, which was usually found in the place were there were lots of FF's. Of course back then we didn't know that FF represented
the maximum value of a byte, or what language these compiled programs were originally written in. But there seemed an accessible bridge between the simple code we were writing and the code we were using day to day.

But imagine a student today trying to see the the bridge that goes from "Hello World" to games like Halo or Skyrim. When I was young, many video games were written by a single person, or at most a small team of three or four people. Kids today may not realize that a few people with a laptop couldn't program Call of Duty any more than few people with a video camera could make Guardians of the Galaxy; both call for multi-million dollar budgets, enormous teams and expensive equipment.

But that's not the biggest difference. Because today, even programmers working alone rarely write a whole program from scratch, any more than a mechanic builds a car from scratch. Nearly every programmer out there is hacking away at enormous existing legacy programs, most of which they don't understand, usually by cannibalizing interfaces and classes from other working programs that themselves were codged together out of older, working code. There is just too much useful code out there for programmers to waste their time rewriting Wheel.class when there are countless different versions of it that can be downloaded and plugged into your program.

But starting from "Hello World," students don't realize this. They look at these sprawling pieces of code, like the programs that make Netflix or YouTube work, and despair of ever writing anything like that. No wonder they want to quit. A Little League baseball player can look at what Derek Jeter does and see that he is doing pretty much the same thing they are, just way, way better. A beginning programming student looking at modern code is more like a kid making a lego car looking at a Formula 1 machine.

Sure, you can try to tell them that the programs they use everyday were made by thousands of people standing on the shoulders of thousands more, all putting together little blocks of code made of other people's code and putting it on top of even more existing code. But if all you're doing is teaching them syntax, such as the command for taking input or drawing circles or counting from 0 to 10, they are missing a big part of what programmers do today.

Most programming languages that are used commercially today, such as C++, Java and C#, are "object oriented." This means that programs are written as modular chunks, known as classes or interfaces, that do things and store data and can be reused in many different contexts without having to change the code inside. If there is a class that already does what you need, you figure out how it works and plug it in. And there are thousands of useful classes in most modern languages that do everything from transferring data over a network to drawing sophisticated 3d images to encrypting your information.  This kind of modular programming is so useful that even languages like Perl or Python that weren't originally object oriented now have OO features.

On top of that, programmers today use sophisticated development environments like Eclipse or Visual Studio that automatically highlight compile errors as you write your code, organize your different classes and files, autocomplete your commands, and take care of a lot of the boring details like importing packages.

None of this is to say that programming is easy. Professional programmers will routinely spend 12 or more hours slaving over an algorithm trying to get it to work they way they want. Any longtime coder can tell you stories about looking up at 11pm and realizing they haven't eaten since breakfast. But it's hard in a different way than beginning programming students think.

So how can we teach students to program in a way that prepares them for today's world? I am still figuring this out myself, but here is my manifesto:

1) Instead of starting from scratch with simple programs that do almost nothing, have students start working on existing programs that do interesting things, and show them how to make simple changes to them.

2) Instead of starting with simple commands like "print()" and "drawrect()" show them how to put together larger classes that do complex things into a more sophisticated program.

3) Object oriented programming should no longer be seen as an advanced topic to be gotten to after learning all of the simpler syntax, but rather the basic element of all programming. Creating objects, using their methods and passing them arguments should happen almost immediately.

4) Focus less on the syntax of a particular language and more on the big ideas of how programs and computers work. The first languages I learned were BASIC and PASCAL, neither of which anyone I know uses anymore. (I don't even remember a single command for PASCAL). Since then at various times I've written programs or scripts in many languages, including PERL, Python, Flash Action Script, JavaScript, PHP, Visual Basic and Java. I can learn these languages because most of the same kinds of structures occur in every language, such as conditionals, collections and loops. When you know how to write a for/next loop in Python, writing one in C++ is as simple as Googling the syntax. Of course each language has its own unique features that other languages don't have, but when you have a foundation it's not so hard to learn. When you know how a computer accesses memory it's a lot easier to understand how a pointer in C works.

5) Most of all, don't teach beginning students to write programs that do abstract, boring things. There was a time when getting a computer to do anything was an accomplishment, but those days are a long time ago. Sorting an array is a valuable skill for a Computer Science student, but pretty boring for a young kid learning to program for the first time. Teach them to do things like make video games, put their messages into secret code that only their friends can read, or make interactive Web pages.  Have them put together existing methods and methods you've created to make something exciting. Sure, they still won't be as good as professional-quality programs, but they will see the connection believe that they can get there if they stick with it.

I think we're just beginning to understand how to really teach programming. It's not like teaching math, where you need all the basics of arithmetic before you can do anything interesting, and it's not like teaching language, where you're building off skills that are instinctive. It's a completely different kind of thinking, and its application goes way beyond computers. I fantasize about a day when school is for reading, writing, 'rithmatic, and...some synonym for coding that starts with 'r.' 

But it's never going to happen until we learn to teach it right. 

No comments: