Learning to program
Most advice on learning programming is poor
Do you know how to teach someone to walk or to read? (If you are an occupational therapist or trained teacher, just skip this paragraph, because you already know the difficulties of pedagogy.) Most people don’t because the skills needed to walk or to read have been ingrained to the point that they are invisible. Programming is similar. Pedagogy is hard.
I am not an expert at pedagogy, merely a dabbler with expert friends. I have learned enough to know what is invisible to me and to know what to look for.
There is a kind of magic in the computer.
It doesn’t come from it being smart. A computer has all the intelligence of your shoe. It has a menu of simple instructions it can follow.
But it can do billions of those things a second. There is a saying in physics: more is different. A billion operations lets us paint an image on a screen that imitates the control panel of a specialized system. It lets us generate the sound of a piano or any other instrument.
More importantly, a billion operations can mechanically translate from abstractions suited to what we are thinking about into the simple instructions of the machine. And there is the magic. That simple menu of instructions explodes into a world of languages. If we can express our intentions precisely in a precise language, the computer can carry them out. This turns out to have some astonishing implications.
So, above all else, you must learn how to express your intentions precisely in a precise language. Start with one. Which one doesn’t matter as much as whether there is a good system of pedagogy to guide you through it.
Programming is a skill, a knowhow, more than a set of facts. You don’t study it and memorize, you practice the act. It’s more like learning to play music than studying for a course. There are many facts that you need to play an instrument or to write a program, but those facts are not the actual skill to perform the act.
Step 1 (~3 months)
The two ‘How to Code’ courses are based on the book in the first link, but they elaborate the design recipes from the book further. All three use a free programming system called PLT Racket, which runs on Windows, macOS, and Linux.
I also have a rough guide with exercises that is more focused on imperative languages. I have also sketched out guidance on developing as a software engineer.
A buffet of further steps
From here it becomes much less linear. These are all study approaches, but you also need to write your own software. It will be slow and torturous initially. You will look back later at your code and think, “How was I such an idiot?” The steps below will accelerate that, but you are learning a craft. You wouldn’t expect to be a virtuoso the first time you picked up a violin or to make perfect dovetails the first time you picked up a saw.
So, in no particular order:
Understand the basics of concurrency
Dealing with multiple things happening at once and communicating, blocking each other, locking and sharing resources has gone from an exotic topic for specialists to an everyday concern, so you might as well get used to the idea now. I highly recommend this fun programming game:
Learn ways of organizing your thoughts
After step 1 you should be able to produce simple programs in the programming language Scheme. Now you need to learn the various ways that people have learned to organize their thoughts in precise language. The fastest path is through the classic book Structure and Interpretation of Computer Programs.
Read and pastiche code
Read other people’s programs. You will need to learn some additional programming languages to do so, but you should start getting used to that. The first few programs in a new language will take forever as you look through tutorials, books, and references to figure out what each piece means. After that things will speed up. Once you have understood a new thing or a new idiom, write a small program of your own with it. In the art world this is called pastiche, and it’s an incredibly useful tool for internalizing knowhow.
Some code bases that you might profitably trawl:
- The basic system utilities of OpenBSD (C)
- bein, a scientific workflow manager (Python)
- Idle, a small Python environment (Python)
- Handbrake’s library, an open source video transcoder (C)
Look for more from
- David Hanselman’s weekly source code, mostly on Windows software
- Open source Mac apps
- On Linux, most of what you use has source code available. Just dive in.
There is much more to be written on how to approach reading source code. I have such an essay in my writing queue.
As you read, you will probably start to appreciate good comments.
Learn to use your tools
Tools provide affordances. Really knowing how your tools work and how to use them lets you approach problems more effectively. For example, learn how to use git or the Java command line tools.
Learn to monitor and automate a operating system
It doesn’t matter if it’s Windows, Linux, or macOS. Whatever you’re using will work. They all have similar concepts, just exposed differently. Some tasks to learn:
- See what is running and how what is running is organized into processes and threads.
- See how much of each system resource each process is using, and what those resources mean.
- Start, stop, and restart parts of the system.
- See what information those processes are emitting as logs and events.
- Schedule things to happen at a later time and on a recurring schedule.
- Change the permissions of files.
- Install and remove software cleanly.
- Control who can log in and what permissions they have.
- Send commands to a running program.
- See what hardware is attached to the system, what the system knows about it, and what the system calls each piece.
- Learn how to get and set the system’s clock.
- Backup files to a disk or another machine.
You’ll need to learn the command language for each system. On Windows that’s PowerShell. On Linux, that’s bash. On macOS it could mean bash or it could mean AppleScript. One automates the lower levels, the other automates the UI. Oh, and learn how to do all of the tasks above from your command language as well as whatever GUI your operating system provides.
These skills pay off massively over time.
Algorithms and data structures are the building blocks of programming. You don’t have to do this all at once. When you encounter a topic or a named algorithm in your code reading, or a problem when writing your own programs, stop and look for existing literature. There is a good chance that a couple days of study can save you weeks of work.
There is a giant literature of textbooks, courses, and research papers on this stuff. As a starting point, I suggest Skiena’s The Algorithm Design Manual. The site Teach Yourself CS also has a curated set of books that are freely available online in a number of the core topics of a computer science degree. They are all reasonable choices that you would benefit from reading at some point.
Many programmers go through their careers ignorant of databases. Databases are one of the crucial, central objects of our field. They have a profound, universal mathematical underpinning (Codd’s relational model) and the major databases like PostgreSQL or SQL Server are among the most sophisticated, mature programs on the planet.
Codd’s relational model describes the semantics that a data store needed for most real world use. It made the translation of declarative queries into operations a finite, approachable problem. And it and unified all the expressive power of the other kinds of database in a single mathematical model. SQL, the language, was the result of a natural language project at IBM, and wasn’t what Codd originally intended, but it is ubiquitous and good enough.
So learn SQL and how to use a lightweight database like SQLite and a heavy one like PostgreSQL or MariaDB.