Tom MacWright

tom@macwright.com

Advice to the newish programmer

I occasionally field questions about computing and the industry from people starting out, whether it be friends switching jobs or just internet denizens. My answers are opinions, but I wish I had formed some of these opinions earlier. For someone’s benefit, here they are.

Elegant, readable, and a lot of other words don’t mean anything

You’ll be asked to produce readable, elegant code. You won’t know what they mean by that. Neither does anyone.

We all sort of know what bad code is - we know it when we see it. But readable or elegant is, more than anything else, in the eye of the beholder. And generally, it’s meaningless. I’ve worked with people who insist that 4 space indentation is readable but 2 space indentation is completely unreadable. Or that there must be spaces between the () in a function declaration and its parameters. Is it more elegant to use currying and other functional-programming flavor, or just use traditional for loops? Nobody knows.

This is all nonsense. I once wrote an internal blog post for Mapbox, declaring our code style: it was to follow the existing conventions of the project, and that’s it. Don’t reformat your functions to K&R style, don’t add or remove semicolons. Just be consistent. It doesn’t matter.

If you want evidence that style doesn’t matter, look at the code style of three.js, the enormously popular WebGL library. It has over 900 contributors, and an unusual style that I haven’t seen anywhere else. The style hasn’t alienated or puzzled contributors, or caused regressions or bugs. It doesn’t matter: the style works for the author.

Which is the cruel thing about “readability” edicts: they’re a disguised way of saying “code like me.” Some senior engineer wants to see code that agrees with them.

Nobody knows all the levels of the stack

The web is a deep stack of things to learn: browser quirks, networking, CSS, HTML. Below that, JavaScript interpreters, browser rendering engines. Below that, process isolation and the OS. And then the hardware abstraction, the hardware, the power supply, the transistors. The electrons that flow, and the paths etched in the microprocessor. Then sub-atomic particles and quantum dynamics, so you can understand random number generation.

The truth is, I and 99% of people working with computers just have to trust that everything inside of the metal box is doing what it’s supposed to do.

Long ago, the magic of industrialization made computers so powerful and complex that nobody would be able to build one from scratch. We can - and should - dive deeper, understanding each layer as we become able to. But almost all of us start from the top down, understanding heavily abstracted technology like JavaScript before we understand fundamental mechanisms like microprocessors.

Don’t worry if you understand computers as enchanted aluminum boxes: everyone does. It’s not really a problem for your programming career.

You’ll need to work without documentation

Everyone should write better documentation, but nobody does. You will constantly find incomplete or incorrect docs. Raging into the void does no good.

The dirty truth is that everyone who wants to work quickly is reading the source code. Again, this isn’t ideal, but it is reality. Learning to explore and read unfamiliar codebases saves you from the slowest and most unreliable thing in the world: other people. And it helps you be a better open source citizen: instead of opening a ticket saying that the documentation doesn’t work, you can figure out why and propose a fix, upfront.

There’s a broader point here. Debugging strategies are generally worth more than the ability to write code quickly. Debugging is the thing that people spend mythical amounts of time on - “I spent 12 hours debugging this!” - often because (and not to blame the victim here) their debugging strategies consist of re-reading the documentation and guessing code. Guessing is bad: read the code, look at the code that’s actually running, whether it’s in your local copy of a library, or Node.js’s source, or on GitHub. It’s worth it.

Expect chaos always

Programming is a partially-professionalized craft that’s built on compromise and elbow grease. As a result, usually nothing works.

Which means that, even the most elite programmers are constantly dealing with mistakes, whether their own or mistakes that they’ve inherited from programmers before them. Even if you’re batting 1000, your perfect application might be vulnerable to a bug at a way lower level, like the Meltdown vulnerability.

Which isn’t to discourage you, but to reframe the craft: what we’re building are solutions to problems. Things that reflect the environment, history, and limitations of their form.

It’s good for you, emotionally and practically, to expect this going in: that computing is long divorced from mathematical purity or conceptual elegance. The two may reunite, but in this era we’re mostly solving problems as best we can with the means provided. Anticipate the chaos and the catastrophes, just aim to end up with less chaos than you started with.