It’s not about the code, it’s about the system

Lucas Sunsi Abreu
The Startup
Published in
11 min readNov 18, 2019

Reflections on the conceptual distinction between code and system, and what the difference implies in our daily development life.

He is clearly just trying to remove everything that is not David.

We’re coders, right? We write code. We build systems from code. It seems pretty clear-cut, doesn’t it? But wait, where does the code stop and the system begin? Is there a system if there is no code? What about the other way around? Does it matter at all to think about the distinction?

I currently work full time as a full-stack developer at Magnetis Backstage. One of the cools things we got going on there is a strong culture of learning from each other. This means we interact a lot with each other’s code and even more so with each other in general. Pair programming, which is commonplace for the engineering team, puts you in close contact with the learning process of many different developers. That’s one reason why it’s great. It’s also what allowed me to pay attention to these learning curves, which made me curious.

Some people have more trouble understanding code than others. Some people can muster confidence about some piece of code way faster than others, and we know how confidence makes a difference in the job. The understanding of the code is not linear in relation to the confidence in the understanding, which is also interesting because it can and leads to some unexpected but very common situations.

Three paragraphs in and I think we can outline what this article is about. I’m interested in what makes understanding code generally hard. This question is the one my philosophical side is hassling with for the last months. The wondering is very broad, but this post is about some specific aspect of it: What is the code and what is the system? Is there a difference for this distinction? Does thinking about it help you be better at understanding code? I think it does, but do not agree with me yet. Let’s think together and see where we end up.

Coding the system

You know what code is. Code is the colorful poetry we have so many feelings about. As developers, we read and write code every day. It’s what many developers think the job is about, to the point some think it’s weird to spend a day without opening the editor (guilty).

But let me ask you something: Does the code you write matter? Do you write meaningful code? Why does it matter? If you went upstream to come up with the answer, quoting some goal of the project you are building or some aspiration of your company, then we are on the same page. The conclusion from this line of thought might be that the code on itself does not matter, but it does because it amounts to something that does matter. That is what I’m getting at in this post.

It is a simple idea with strong implications. Before there was code, there was an idea. The idea is about bringing together a group of remarkable snippets to see if they could become something more. See if they could work together and solve the problems we never did.

The idea is the system. The system has to do with the previous (but inexact and volatile) idea, the problem and solution pair, intended to be implemented by the code. That distinction is crucial. The system matters and because of it, the code matters. The system’s importance implies the code importance, but not the other way around.

From this perspective, the code is one of the possible manifestations of the system and it only matters as much as the system does. It isn’t the endgame of any developer to have many lines of code, but it might be to achieve some kind of system. The code is the tool that brings some imperfect version of the system to fruition, while also being the tool to iron out this imperfections on the (infinite) road to matching the system.

The reason for poetry

The code we write is our best chance to reach the system or at least something real that approximates it. We write code, so we can seek the system. We read code, so we can understand it. This feedback loop is what I call an interface. Code is what interfaces us, developers, to the current approximation of the system, while giving us a hint of what the system is.

Again, that’s a simple idea with strong implications.

While reading code, what are you thinking about? Of course, your mind is holding a couple of variables and running some loops while you try to understand the algorithm, but what then? More often than not, the algorithm you just read is part of a file, which is part of a folder, which is part of a project. How does the algorithm you read fit the system as a whole?

While writing code, do you know what problem you are trying to solve? Of course, you are trying to optimize the nested loops that make the algorithm on this particular file crawl, but how does this help the problem that started this whole folder, to begin with? Will this optimization approximate the system, or is it just gonna add complexity for the next reader?

The code is what builds the current approximation of the system. This information is strong because it helps keep your attention where it matters. The code is the best chance you have of understanding what is the current approximation of the system doing, which will hopefully be aligned to the system itself, providing us with valuable information about it.

The code tells you a story, but it isn’t the whole story. Further, the whole story told by the current code will be just an approximation of the whole story.

The system is not by design

Getting to the other side, there are some properties to note about what I’m calling system in this article. As previously mentioned, the system is the idea that required the existence of code. The system is about the problem/solution pair that pumps meaning to the colorful numbered lines.

The system is alive because the problem and solution are alive. You can say the system might align with someone’s vision. You may even say the system is your company’s product because it is inherently connected to what it tries to sell or solve. The system may be something your team is trying to uncover through discovery proceedings, and it may change when the goals change.

What all of these perceptions have in common is the vagueness of a definition, which is precisely what fits my purpose for this article. The system is not a specific implementation of a specific solution any more than the vision of your CEO is precise and ready for prime time. The system is imprecise and volatile, at least for us mere mortals. What we have are hunches and glimpses of what it should be, which will feed our code-based approximations. The coding part of our jobs is precisely that: Improving our current approximation of what it is. It is more craft than science to be sure, at least for most startup applications.

What the system is not: a design. The document you write your code to satisfy is not the system. The specification is a hunch of what the system is at some fixed point in time, made solid by another professional just like you. Because of that, it is much closer to the code you’re gonna write than it is from the system it was sampled from. Product design, for example, is about being close enough to the system that you can sample precise and clear specifications from it in order to communicate clearly throughout an organization.

This line of thought makes it obvious that the job of turning specification to code is redundant, to say the least. An specification matters just as much as the system it approximates. If it’s a bad approximation, then it’s worthless, just like the code we write.

The most important part is making good approximations, and that’s what we should care about deeply. Specifications and code are tools to be used in crafting and communication, but they are not the endgame. If you, as a developer, implement a specification that does not approximate the system, you are not doing your job. Worse, you just created some piece of needless communication (code) that might confuse the reader even more about what the system is and what the project is trying to accomplish.

Don’t lose focus on the endgame. You are solving a real problem, not a problem created by some managers in the corporate hierarchy you’re in (I mean, maybe you are, but I would like to think not).

It’s not a matter of scale

It is easy to see the two concepts from the perspective of scale. The code would be the micro, the cells, while the system would be the organism. While this parallel is interesting in some ways, it is predominantly misleading for one particular reason I’ll go into in a minute.

When we think about cells and organisms, we mostly care about the latter. We want to understand complex relationships that cause some specific illness, for example, so we study the micro to induce an explanation about the problem. From this, I can conclude that code is useful to understand the system, which is the correct order of implication for our needs.

What this parallel misses is that the system and the code are not on the same level. The code is real, it’s stored in a repository, it has controlled access and it is versioned. The code is a human language (yes, human) and it’s on the human level just like it’s users (humans). The system is an idea that can’t be written down without loss of generality and precision. It is what the code was intended to amount to, without anyone being able to fully test against.

In sum, thinking about scale might lead you to assume the approximation is the system or that any particular implementation is. If code and system were just on different scales, then one would be achievable from the other, which is a dangerous assumption to have for something that is, in fact, alive and changing every day. Coding is just playing catch up with the system, over and over again, until we die or maybe reach an IPO.

Get it? There are a lot of tools there. Code is the tool. You get it.

Code is cheap

What can we conclude about our daily lives from this? First of all, we can conclude that my philosophical side is getting the best of me and I have to choose how comfortable I am with this fact.

Second of all, we can derive some common development behavior that comes from missing the implication order between the code and the system, avoid looking for the generality provided by knowledge of the system or even missing the system existence entirely.

From a system-less project, it’s easy to think the code has intrinsic value. Our minds help us conclude this: We are being paid to write it so it has to carry value. From this point on, it’s common to observe many of the coding pitfalls warned by many to the ones new (and not so new) to the craft.

If code has value, then it will have more value the better written it is, with each people filling up the “better” part with its personal definition. Some will think better means faster, so they’ll optimize prematurely. Some will think better means prettier, so they will break architecture to satisfy their perspective of code beauty. Some people will think better means object-oriented, so you bet there will be a lot of small classes. Some people will think better means fast to deliver, which might lead to rapid prototyping of some useless feature that will just be overhead for the team to maintain without any system approximation value.

We can also think about what it would imply for the reading part. Reading code without the system in mind will many times result in fast local convergence, from my experience. The developer will be quickly satisfied with understanding a single file and will start writing with confidence that all the information needed is already gathered. Moreover, the quick confidence gained by looking at small parts of the approximation might lead to quickness to judge and criticize, which is particularly toxic for teams. Have you ever talked to a new hire still grasping to understand what the system, but very comfortable numbering the many mistakes he already found in your codebase?

Code mistakes only matter in relation to the system, they do not matter on their own. If you do not have a proper view of the whole picture you can’t properly asses the impact of code mistakes in general, and it’d be better to ask someone who does before assuming. Because you know, when you assume…

Feed on the system

Conversely and ideally, the system will be on our minds at all times, especially when reading and writing our beloved code. From this, we can also derive some behavior for the opposite situation from before: when you are feeding on your mental image of the system instead of ignoring it.

What does having the system on your mind imply on your reading and writing assignments? Firstly, reading code will always be an experience of discovery and reflection. Again, reading code means getting insight into the current approximation of the system, which you can use to build a concrete (and incomplete) image of what the machine looks like in your head.

The better this mental image is, the better your inference ability will be about other parts of the system. If you have the problem/solution in mind, it’s easier to see patterns throughout the code base and develop confidence (the good kind) in what you are doing. It’s also easier to see imperfections in the approximation because you have seen what it should be and are not limited to what it currently is anymore.

There is also a compounding factor. The more you improve your mental perception of the system, the more efficiently you’ll seize opportunities to validate and improve the perception. After a while you’ll realize reading the system’s code will become progressively easier to the point you’ll understand code you never read because you’ll infer and derive truths about the approximation from your connection to the actual intent.

What about writing? Writing becomes safer and quicker. That’s mainly because you know what you’re trying to ultimately solve. You have the system approximation running in your head, therefore you have a good idea of what risks are you taking on a particular commit. Taking confident calculated risks faster while iterating the approximation closer to the system is what makes you a good developer.

Coming back to Earth

The code is what is, but the system is what it should be. With this article I tried exploring the difference between those made-up concepts and how focusing on each one can catalyze or hold back your reading and writing abilities.

It’s important to note these concepts apply to development in general, not being restricted to new or old fellows of the profession. Of course, having more experience will give you more opportunities to tune your perception of what matters along with building better approximations of what the systems of the world are. That said, having more experience does not imply the right perception. The earlier we realize what matters in our jobs, the better we can start making the real difference.

From my perspective, code is just the tool we leverage to get the job done. Focusing on the tool provides value, but the returns are definitely diminishing. The scalable outcome is about figuring out what the best approximation of your product looks like and trying to go after that.

I would also take the time to point out that this perspective suggests development is more than coding. Thinking that software development is limited to translating specifications from English to Ruby is a limiting perspective I’m moving away from. To me, software development is about pairing solutions to problems and giving our best to build something that approximates this pair to our reality or die trying.

Preferably not die trying though.

--

--