Someone asked me via email about my thoughts on the software engineering field, and what I would tell someone new to the industry.
(Relatively speaking, I’m also pretty new to the industry! But it’s 5AM, and I ended up going on a long semi-rant. I thought the rant might be interesting to some other people too, so here’s the rant.)
Interpretations of reality
If you look one way, mathematics is just a box of tools. Abstractions you can pull out to solve specific problems when we are faced with them. The field of mathematics grows by mining the space of yet-unknown facts to accumulate more and more powerful tools in this toolbox. But if you look another way, mathematics gives its practitioners access to a particular kind of worldview. It has its own vocabulary, its own taste of beauty and elegance. A world examined through the lens of combinatorics or statistics or graph theory yields qualitatively different understandings of the world. None are better or worse. Just defined from different abstractions.
I think software is very similar. Look one way, and it’s a set of tools for solving problems using computers, which are these interesting arrangements of wires we taught to mimic this ideal model of information processing. But eventually, if you take the deep dive I guess, software gives you its own set of abstractions and basic vocabulary with which to understand every experience. It sort of smells like mathematics in some ways. But software’s way of looking at the world is more about abstractions modeling underlying complexities in systems; signal vs. noise; scale and orders of magnitude; and information — how much there is, what we can do it with, how we can learn from it and model it. Software’s interpretation of reality is particularly important because software drives the world now, and the people who write the software that runs it see the world through this kind of “software’s worldview” — scaling laws, information theory, abstractions and complexity. I think over time I’ve come to believe that understanding this worldview is more interesting than learning to wield programming tools.
Another way to say this is that the software “industry” has bred a particular kind of culture, which is no different than any other nerdy kind of academic niche’s culture except that this one has lots of billionaires, and this culture drives the people building infrastructure that have leverage over important parts of society for better or worse. The culture not only influences how we build things, but also what we build, and what we don’t build, which is far more important in the long term.
I’ve found that looking at the software field through this lens (asking myself how it models the world, and our role in it) helps me understand it deeper than when I look at it as just a community of people building programs and tools. Ultimately those tools have to model reality, and to do that, we need an interpretation of reality. Software’s interpretation of reality is quite objective, model-driven, and based on repeatable, scalable things and a belief in a kind of purity in “information”. These values are reflected not just in the way programmers build things, but also in the way programmers (generalizing broadly here) interpret and try to influence the world.
But this way that the software industry interprets reality – this “tech culture” with its jargon and lexicon – isn’t immutable. It evolves over time, and it can be changed. To influence how the software world sees itself, a lot of software engineers would propose their routine solution: build better things, and let the market of ideas take charge. If your worldview (values, tool, program) is truly better than mine, people will adopt it.
A less expansive take on software: Bryan Cantrill says software is a very particular kind of machine: “software is both machine and information”. We can program it to do things, like a machine; but software is information. It can be freely copied and distributed, evolved, and survived for eternity. Software engineering is the community of people and lineage of oral traditions that have emerged around how we can keep these immortal, infinitely scaling machines running, and how we can build better machines.
Everything else — tools, frameworks, languages, patterns — are downstream of this grand challenge: programs like Google are giant, lumbering machines of colossal complexity. No single human understands it. How do we keep it running? How do we ensure it’s safe? How do we improve it without degrading existing pieces? The tools and frameworks and languages are breadcrumbs on our road to tackle these larger questions. They’re very fickle breadcrumbs with lots of little details that have to be learned, but they’re still ultimately details in this grand challenge.
Build many small projects, learning one new thing at a time, and do it quickly
Okay, coming back down to Earth: practical advice for entering the software engineering field.
When I was early in this space I frequently got annoyed with how slow/inefficient learning programming felt. Programming feels hard to learn in the beginning because it feels like learning knowledge, but it’s actually learning a skill. You’ll expect to be able to pick up programming as easily as you pick up facts about the French Revolution or the 5 steps of mitosis, but you won’t be able to.
You don’t expect to learn how to play the piano by reading a book, but you might expect to pick up a programming language or concept because you read about it. Really, it doesn’t work that way. You have to read it, and then use it and practice it and make a hundred mistakes, and then you’ll gain the skill to use that concept more correctly over time. I think if you treat it as a skill, and accept yourself for feeling inefficient — things like spending a whole day on a bug that seems impossible to fix — you’ll have a more pleasant time.
Besides that: find small (2-3 day) project ideas that require you to learn max. 1 new technology or idea, and build lots of such projects. Iteration speed is most important. To build lots of small projects, you can’t pick projects that are too large (because you’ll give up), and you can’t pick things that require you to learn 3 new things at once b/c you’ll get stuck too often and give up. I learned everything I know now by building many small projects quickly, incrementally picking up new skills. From talking to others, this seems like the best way I know how to learn programming.
← How we create