Profile

Depa Thoughts

Back to Essays

On Great Software Engineers

TechnicalMay 30, 202512 min read

"I am not a prolific writer, a fabricator of compendiums, an earner of fees, a person who aims with his writings at the approbation and assent of a minister; in a word, one whose pen is under the influence of personal ends. I aspire to nothing but the truth, and I write as the ancients wrote with the sole object of preserving my thoughts, so that they may one day benefit those who know how to meditate on them and appreciate them"

Schopenhauer, The World as Will and Representation, Vol. 2

Introduction

We live in a world stirred by the arrival of artificial intelligence, where we're told that many industries will change, including software. We may be witnessing a revolution unique in hundreds of years, one where the structures, customs, and dogmas of our industry creak with each algorithmic improvement. The Turing test, once considered the hill to conquer, already lies in the past. Fear and uncertainty spread among both those of us who have been here for many years and the newcomers arriving in the industry. New forms emerge that coexist with old forms, with companies expecting more in their pursuit of automation. Entrepreneurs believe (perhaps erroneously) that they can replace entire teams of engineers with AI. Startups appear and disappear in what resembles a contemporary search for computational gold. Engineers suffer: those with jobs fear being replaced; those without suffer from unemployment. The industry —which once seemed to require so much talent— now tries to employ the fewest engineers possible, and the old forms of evaluation resurface. Technical tests, leetcode, and similar assessments proliferate, returning to their former prominence in the interview process.

In all this chaos, we still struggle to answer the crucial question of our industry, that remains and will continue to be relevant: what does it mean to be a great engineer?

Some would argue that having a degree is a requirement, though (having studied two software engineering degrees myself) I'm not convinced it's necessary. A credential can never guarantee knowledge. Others point at the experience one gains by working with a great engineer (in their work they see their greatness). These distinct poles—which philosophically we might place near rationalism or empiricism—clash with the main problem of our era: pretending to be often supplants actually being. It's not those who know most who write and make themselves known, but those who generate the most content. The community becomes confused and the foundations built by the ancients crumble. Many lies and pseudo-truths spread, leading our industry to reaffirm its dogmas and abstractions. Those who ask questions and seek to go further are often constrained by the current way of doing things. Defenders call this approach "idiomatic," almost switching off the mind with such terms. The code that AI writes tends to proliferate incorrect ideas. Only in a handful of cases do people understand and guide AI toward correct ideas, since truth is never found in what the majority does.

I've been thinking about the question itself based on my past experiences and great engineers I've worked with. I've come to the conclusion that it is a combination of innate personality traits, capacity for understanding, experience, and communication. These characteristics reach their peak in those we consider great and become evident in each of their interactions. Many other programmers who lack some of these characteristics can identify those who possess them but fail to understand what they do differently. They have an intuition of their greatness (they recognize and praise them), but when these great engineers try to help them, they struggle to assimilate the lessons being taught. Software teams are built on this distinction, where the difference is one of degree. On one side are beginners; in the middle, those with some experience; further along, the experienced; and finally, the great engineers.

Unfortunately, our industry is extremely poor at evaluating the latter. It's not an easy task: candidates lying and little (or no) technical excellence on the recruiter's side makes evaluating engineers quite difficult. We accept that talents are filtered by recruiters who usually know nothing about code. They're also evaluated by programmers who, despite limited experience, lecture those they interview on how to program. They don't realize that their professional existence depends precisely on those they dismiss, treating them with hostility or indifference while trusting that technical interviews where memorizable exercises are the standard demonstrate developer quality. It is my intention to steer the question in a different direction. If we don't know what it means to be a great engineer, how can we evaluate them? But besides the interviewing process, it can also help other engineers to understand what it means to be a great engineer, and how they can become one.

Fundamental Pillars

To answer what it means to be a great software engineer, we would first have to understand the essence of software. As a prerequisite, we'd need to answer the question: "what is programming?" My current conception (which I'm developing in another essay) is that programming is an understanding of a computational problem. This understanding is transcribed in code, but has its origin in the minds of the programmers who build it day by day. In other words, programming is understanding, and as a corollary, if one does not understand, one is not programming. I won't go through the details of this definition here, but I will say that it is a definition that has been evolving for me over the years, and that I consider it to be the most accurate one I've found so far.

Derived from the definition of programming, the great engineer is one who is extremely good at understanding systems. Understanding systems is not an individual activity, since it's usually done in collaboration: not only with colleagues, but with the tools with which we interact with (i.e., compiler, operating system, databases, browsers, etc.). We also communicate with our users, whether internal or product users. Therefore, a great engineer knows how to communicate.

However, these qualities alone do not make a great engineer. Certain personality characteristics are essential to software practice: curiosity, responsibility, and proactivity. Combined, we conceive the great engineer and characterize them as follows: one who is always investigating, who cares about their ideals while pursuing solutions, who doesn't remain indifferent to how things are done, and who is always present (even when absent). They stand out for their ability to teach, their capacity to ask questions, and their refusal to accept what they learned as absolute truths.

1) Understanding Systems

The great engineer typically works with multiple programming languages and diverse systems. When confronted with new problems, they surprise with their adaptability. They possess fundamental knowledge of languages and their patterns: they understand programming paradigms and design patterns. They know them in their true essence, not merely speaking of them descriptively or superficially. Sometimes they may not recognize the formal names, but they understand their nature and can implement them in practice. They pursue beauty and perfection in everything they do, aligning their systems with their particular rhythm. They tend to program quickly, but don't stand out for being the fastest, since the fastest often forget that programming's main activity is not writing, but thinking.

We think that knowledge and understanding belong to art rather than to experience, and we suppose artists to be wiser than men of experience (which implies that wisdom depends in all cases rather on knowledge); and this because the former know the cause, but the latter do not. For men of experience know that the thing is so, but do not know why, while the others know the 'why' and the cause. Hence we think also that the masterworkers in each craft are more honourable and know in a truer sense and are wiser than the manual workers, because they know the causes of the things that are done (...) And in general it is a sign of the man who knows and of the man who does not know, that the former can teach, and therefore we think art more truly knowledge than experience is; for artists can teach, and men of mere experience cannot."

Aristotle, Metaphysics

The great engineer understands the nature of the problems they are set to solve. This understanding isn't casual (it takes years of practice) nor is it solely from experience: it's the combination of all the aforementioned qualities (curiosity, proactivity, communication) with experience that leads to the great engineer. They assimilate this knowledge as part of their engineering identity, which feeds back into how they act and think. They learn that problems have certain solutions, but more importantly why they have them, and they develop their own principles for approaching each problem. They know that every problem they investigate has a cause, and therefore they must first understand the problem and, once solved, verify that it has been fixed. They don't deliver solutions arbitrarily, not even under time pressure or when something works by chance. Moreover, there is no "functioning by chance" in the mind of the great engineer—they cannot conceive of not understanding a problem and are never satisfied with apparently having solved it.

"As I then desired to give my attention solely to the search after truth, I thought that a procedure exactly the opposite was called for, and that I ought to reject as absolutely false all opinions in regard to which I could suppose the least ground for doubt, in order to ascertain whether after that there remained aught in my belief that was wholly indubitable”

Descartes, Discourse on Method

It's clear to me that troubleshooting a bug comprises two distinct processes: (1) understanding the causes of the problem and (2) implementing a solution.

Understanding the Causes

We know an approach exists for solving problems where cause detection is explicitly separated from solutions. It's not "try this or that," but rather understanding the causes of the problem we're solving. With the intention of clarifying the process, these are the steps engineers take to solve problems:

  1. We have a bug to solve
  2. We understand the problem
    1. We try to reproduce it
    2. We read the code
    3. We attach evidence to the task (screenshots, logs, etc.)
  3. We continue at 2. until we can affirm that we found the causes of the problem to solve
  4. We verify the causal nexus: we verify that the cause we found in 3. is really it

Up to this point we don't propose any solution, we don't program yet, we don't push to master a commit that magically saves our problem.

To avoid the risk of preaching what I don't practice, I'll show some of my own public interactions to illustrate point 2:

Solving the Problem

Once we understand the causes, we can proceed to solve the problem. I know many engineers who skip this work, jumping directly to trying solutions without understanding the problem. Some always try to delegate the first part to artificial intelligence, wanting it to understand something that only programmers can do (since we cannot equate cause-effect understanding with pattern repetition). I don't criticize AI use, but only an engineer can ensure causal relationships in code.

This is easy to see especially in complex problems with multiple solutions. Try designing an experiment where you consult an AI about a problem that isn't in the code itself, but where you only have symptoms (logs, stack traces, or user comments). You'll see this experiment is extremely difficult for AI to solve. As it doesn't understand the causes, it will try to guess correlations between your code and the problem. This isn't what engineers do, the methodology differs. AI doesn't arrive at their solutions due to understanding of causal relationships, but from training on vast quantities of examples (of very low-quality code in most cases). Therefore, I can't conceive how AI could be taught to detect complex cases where the problem doesn't originate in our available evidence, or where the problem is multicausal and not immediately verifiable (i.e: problems with sockets, memory, or performance).

Problems can have many solutions, and it's not unusual that they originate not in our own product, but in some external component.

Having said this, if we already identified the problem, we will try to solve it in the following way:

  • If possible, we will write a test that must fail and demonstrate that we could isolate and reproduce our issue
  • We prioritize the solution by analyzing its correctness and simplicity that best suits our problem
  • We verify it works and that the problem is solved

You'll notice I've kept the process of investigating issues and finding solutions general and indeterminate. This isn't intentional evasion—while these patterns are clear, many individual details depend on developers and teams, not processes. Therefore, having the right people matters far more than having the right process: processes emerge from people. Don't tell great engineers what to do; present them with the problem—they'll know how to solve it.

2) Communication

Our industry is always changing. Roles like "product engineer" are introduced, but one should ask: isn't it what we've always been doing? We seek to divide what should be conceived as a whole. The main difference between software engineer and product engineer lies in communication. However, communication is part of our responsibilities. We communicate with users through interfaces and products. We communicate with teams using tools like Linear, Jira, Github, and others. We communicate with other developers and with systems using programming languages and code. Communication is in our essence. Yet little attention is paid to it. Few engineers keep their backlog in order, correctly describe their work, or appropriately communicate their status. Some write documents about how to fix code issues instead of fixing them, while others, due to their nature, fail to notify colleagues, teammates, or often even end users. There are absurdities like developers who believe any code comments should be eliminated, thinking that code's purpose is simultaneously present in the code itself. Others design collaboration rules for their teams only to skip them later or, worse, be the only ones not following them, when they should be the primary exemplars.

Programming and Philosophy

Those who know me know that I studied and continue to read philosophy for many years. Being extremely curious, I found in philosophy the destination where programming led me—to its deepest concepts.

Philosophy speaks of very relevant topics for software, such as identity, change, substance, objects, time, equality, being, knowledge, understanding, reasoning, causes, abstraction, and universals.

Years ago, I believed I knew these concepts, but didn't realize I was missing what philosophy provides. Today I think that despite knowing much, I knew little—and that today I know less than I might know tomorrow.

"Time seems so completely and utterly self-evident to us that we are prone by nature not to become clearly conscious of it, but instead to notice only the course of the changes in it, which in any case are known strictly empirically. Hence it is already a significant step towards philosophical education to focus for once straight on time itself and ask with complete candour: What is this essence, which can neither be seen nor heard, but into which everything must enter in order to be real; which advances with inexorable regularity, without anything being able to detain or accelerate it in the least, as one is able to do, by contrast, with the changes of things occurring in it, in order to deal with them properly in given time?”

Schopenhauer, Parerga and Paralipomena II, §29

The current state of the software world is that of a technically sophisticated but philosophically naive discipline. Programmers who can implement complex design patterns cannot articulate the metaphysical premises on which we're based. It's unsurprising that the industry jumps from fad to fad, paradigm to paradigm, never resolving its fundamental contradictions.

I consider that great engineers can be philosophers, even without realizing it, and that this is the path that remains when we reach that stage. If you're someone interested in philosophy and feel that programming is missing something, or if you feel there's something more, I invite you to that path.

"For philosophizing the two foremost requirements are these: first, that one have the courage to allow no question to weigh on one’s mind, and second, that one bring everything that is self-evident into clear consciousness, in order to conceive of it as a problem”

Schopenhauer, Parerga and Paralipomena II, §3

Tags

Software Engineering
Career
Reflections