Learning to program good
And do other stuff related to computers good too in the 21st century.
I keep saying we’re not doing it well when it refers to teaching programming, which, after all, it’s the core of computer science, in this time and year. We’re doing it wrong. However, saying things are wrong only takes you so far. Below are my thoughts on how to teach programming from scratch.
Use several languages. All of them.
Hey, languages are free. Why not use them all? A new language is as far as typing a few things into the terminal (and yes, we should use the terminal). Why should we settle in a single language when teaching to program? Most projects will use many of them. Any programmer, hobbyist or career, will need to have a whole quiver it her résumé, new projects will sometimes bring new languages along with them. Polyglot programming is a thing, so why not embed it into the practice of teaching to program?
The idea here will be to use several, maybe 3 or 4 languages, for every example I show; these languages will vary from one example to the next.
Focus on tasks, not on syntax.
For some reason I really cannot fathom, most programming coursed proceed down the reference manual of the programming language, hammering down commands and syntax until it’s tattooed on the soul of the learner. Let me tell you something: syntax does not matter. If you don’t get it right the first time, informative error messages will tell you what’s wrong and if you still don’t get it there’s the whole Internet to help you. Focus on tasks going from the simplest, like finding out the result of a simple operation, to the most complex, implement this very complicated algorithm with a good big-O complexity.
Start with the familiar.
Why start, as many courses do, with compiled languages such as C++ or functional languages such as Haskell? Programming is a life hack as well as a career endeavor, and the tools to program are already in our pocket and desktop. Any spreadsheet or office suite is programmable, but the browser also is, with a development environment embedded in it. There’s also this thing called the command line. These programming languages can only take you so far, but they can be used to learn the simplest things: variables, expressions, loops. Why not start there, and then proceed to other languages?
Start with expressions and one-liners
Why start teaching the whole scaffolding of programming, from editing to compiling or interpreting, when most languages have an excellent REPL which can not only interpret the language, but also give you meaningful errors and show you output? Work with the REPLs, and then proceed to other development environments which can also help you learn programming while knowing what the student is doing.
The moment to teach debugging is when the program has more than one line.
Most people choke when they write a 20-line program and it does not work. They can’t figure out where the thing went wrong, when the answer is right there, in front of them, if only they’re able to show the variable values and where the program actually is every step of the way. Introducing IDEs, and in the polyglot spirit, a slew of them, not a single one, including excellent online environments such as c9.io. is essential to learn fluidly to write correct programs.
That is also the correct time to introduce comments and tests.
In fact, tests should be deferred to when you teach functions, but still the spirit of test-driven development should be infused from the get go. Also the spirit of show and tell what you’re doing from the very first moment. Show how to start each block with a small explanation of what’s done and what should be expected. Good documentation also starts with consistent practices when writing your code: meaningful and consistent variable names, code indentation and block delimiters placement, all that should be embedded from the very beginning. That will make whoever learns that way to recognize code or understand it independently of the language it’s written. Except if it’s Erlang. Erlang is tough.
Use the environment
Very few applications today will use standard input and output. Do not waste people’s time by making them input variable values by typing them every time they are trying to run a program to debug it. Millions of hours of millions of CS students have been lost entering the values of 3 variables or more every single time they run a program to test it. Use the environment! Any operating system or IDE allows you to set environment variables that can be reused every time you run a program, avoiding typing them again. Besides, environment variables are used in modern cloud development, so you get that for free. cin appears almost ten million times in GitHub. Really. Why? Show how to read a file from the get go. Even better, show how to read a JSON file and interpret values. It will save them a lot of time and yourself too, if you’ve got to grade them.
Include the batteries
Module installers, makefiles or suchlike, linters, documentation generators… How can you learn to write a program in C without knowing how to create a Makefile? make clean should be like the second thing to learn after knowing how to compile something, since you’ll have lot of crap lying around after you compile or before you ship it. Applications are created to be delivered, and they always need these batteries either to go along with them, to compile them to a particular target, or to create the actual object that is going to be delivered. Better use it.
Do not forget the cloud.
The cloud is the environment to run applications. It’s no longer the desktop or the production server. And that not only means that you’re halfway to finishing your job when the application compiles OK, it means that you will have to ship, or rather deploy your application to the cloud to run it. But this also has a series of implications on input/output and that kind of things. Baseline is: the console is all but dead, but also you will have to include shipping applications such as Fabric or Capistrano in any computer language. Is it complicated? Maybe. More complicated than the concept of compilation or inheritance? Definitely not.
Programming is done in teams.
And this should also be taught from the beginning. Meaing, basically, git. But also a certain way of writing programs and documenting them so that they are open to collaboration. Meaning also open source, of course, but I mean here using README.md and CONTRIBUTING.md generously so that it attracts collaborators. Also, issues and milestones, code review, and so on. A lot of programming is done on somebody else’s code. Why not include code review as part of the skills you want people to learn? Why focus on writing programs from scratch? There are billions of lines of code there, some of them are wrong and some of them are beautifully written. Learning to work on other people’s code is essential.
And this makes ten
Which is probably enough for the time being, although I intend to continue with this, and I have all the intention of writing a book using these principles and maybe others I’ll find along the way. Any feedback will be appreciated.