The Landscape of Knowledge

A common refrain from people first drawn to coding is “I love to code, is there any way I can just code all day?” The short answer is “probably not”; the long answer is “what are you writing code for?”

The Uses of Programming

Programming is writing, and writing is a tool for communication. Fiction writers spend time understanding their world, their characters, and their plot before they are able to write a compelling story. Non-fiction writers spend time researching their topic, understanding their audience, and structuring their argument before they are able to write a compelling essay. Likewise, programmers need to understand the problem they are trying to solve, the users they are trying to serve, and the context they are operating in before they are able to write compelling code.

If you want to write useful, effective code for a business, you need to understand the business model and framework, the users and their needs, and the technical constraints and possibilities. If you write software for industrial systems, you need to understand the engineering principles, the physical systems, and the safety protocols. If you write software for scientific research, you need to understand the scientific method, the data analysis techniques, and you might even a solid background in the domain to make sense of the problem. In other words, to write a useful program, you often need some significant domain knowledge.

For this reason, someone with domain knowledge is often able to learn programming when they realize they need a computer to solve their problem; a programmer who wants to solve the problem will have to learn the domain knowledge as well. This is why many programmers find themselves working in a specific domain, such as finance, healthcare, or education, and become experts in that domain over time. The ones who really “only study programming” tend to work in academia, research, or open source software, where the domain is programming itself.

Being “Good with Computers”

“Oh you do programming? You must be good with computers!” is the same kind of mistake as “Oh you do accounting? You must be great with the economy!”, or “Oh you work in retail? You must be great with manufacturing!”

A computer has many parts and involves many systems, each with their own history, domain knowledge, and ecosystem. Computers interact with many other systems, each with their own history, conventions, and constraints. Even a programmer who “works with computers” may not be familiar with all of them.

A network engineer has to know how data is transmitted over the internet and how it “finds its way” to the right computer. A systems administrator has to know operating systems, file systems, and the quirks of the system utilities they use day in and day out. A cybersecurity specialist needs to know different ways that systems can be compromised, which involves broad knowledge of file formats, program execution, and network protocols. A data scientist has to know how different programming languages and systems represent data, and pitfalls of data sanitization and conversion. A UX designer has to know human-computer interaction and cognitive psychology, on top of the languages they use to program the interfaces that we use. A DevOps engineer has to understand systems engineering and concurrent programming to automate the deployment and scaling of applications in a robust manner. And so on.

Each of these areas is complex enough to be a multi-decade career for a single person. It’s not so bad if we go in with our eyes open. What more likely happens is we create our first RPGMaker game and think to ourselves “let’s make a game engine like RPGMaker, it sounds fun!” and don’t realize we’ve just signed ourselves up for a multi-year journey into graphics programming, physics simulation, event scheduling, artificial intelligence, among other topics. Or, frustrated that the ten calendar apps we tried cannot handle dates and times the way we want, we think “how hard can it be to make our own calendar app?” Dear reader, we would have signed ourselves up for a history of time zones, fifty ways to represent dates and times in different programming languages, the intricacies of internationalization and localization, at least five world-ending bugs waiting to happen in the next twenty years. And that’s before we get to all the quirks of how hardware devices, operating systems, and network protocols handle time.

The Right Level of Challenge

I’m not saying “don’t make a game engine or calendar app until you have learned X, Y, and Z.” I’m saying—you know how in videogame RPGs, if you were aware you are about to face a huge boss fight, you’d do a lot more preparation? And remember to save your game first? You do yourself a favor by recognizing that some projects are huge boss fights, and adjusting your expectations accordingly. As an old internet meme goes, “one does not simply make an app”.

At the same time, one should not expect to master multiple domains before writing one’s first useful program. You would likely be past working age by then! The path to mastery is littered with flawed attempts, dead ends, and false starts. Very few people can have their first five projects go poorly and still find the motivation to keep going. You want to have some early successes, and that means tackling something just out of your reach, but not so far that you get overwhelmed and give up.

Conclusion

Programming is a tool for communication, and writing useful code often requires significant domain knowledge. Being “good with computers” is not a monolithic skill, but rather a collection of specialized skills in different areas. To write useful code, one needs to understand the problem they are trying to solve, the users they are trying to serve, and the context they are operating in. Tackling projects that are just out of one’s reach can lead to early successes and motivate continued learning. Every useful program begins as a small bridge between what you already know and what you’re still learning.