Let me ask you a question: How much value do you think your source code has?
To answer this question, let me take you a few years back, when I worked with a small high tech startup. We were working on a pretty complex augmented reality system spanning all layers from low-level computer vision components to cross-platform mobile and web apps. Especially for the lower-level components, a good amount of research had been involved. We worked closely with an academic institute that specialized in computer vision.
In short, this project wasn’t something that anybody could just easily recreate. So one of the assumptions we had implicitly made was that our source code was one of the company’s major assets.
When we hired a new COO, who had mainly worked at bigger companies before, he was shocked to hear that all our code, communication infrastructure and internal systems were living in the cloud. He argued that we should move to on-premise solutions as soon as possible, partially out of fear of intellectual property theft, partially to appease investors with similar fears.
While I had no say in it, his arguments seemed somewhat unreasonable to me at the time and I couldn’t put my finger on it. But the CTO was on board. So we installed a cheapo server in one of our office’s closets, even though someone had just broken into our building earlier that month. We got rid of GitLab, and moved away from Slack and Trello in favor of an on-prem Jira installation. The whole ordeal took months to complete, and I’m guessing that all things considered, it cost the small company of ~6 people about half a year of development time. There was also the ongoing opportunity cost of no longer being able to use any new tools that involved the cloud.
But the whole thing got me thinking about an interesting question: What would happen if someone just took all our code? Going even further, what would happen if we ourselves just put it all on GitHub, with a permissive license like MIT? Short of making investors think we’re crazy, what direct impact would that have had on the company?
I thought long and hard about these questions, and I think in our situation back then, the answer would have been: absolutely none.
Your source code is worthless
Let’s face it, we were still a fast-moving startup, even if the above anecdote might give you the opposite picture. Our code was still changing drastically every couple weeks. Changes of the entire architecture or complete re-writes of components were not uncommon, as is usual for some early stage startups. And as you might expect in such a situation, the code wasn’t of the highest quality either: Half the time, the build would be broken. Testing and documentation were basically non-existent. It was unlikely that anyone from outside the team would even have gotten the thing up and running. Even if they did, it would be outdated a moment later.
One of the fears from management was that a big company like Google could take our code and build a competing service. After thinking about this in more detail, the idea now seems laughable to me: They would be much faster just building it themselves from scratch, than trying to understand the crummy code we had hacked together.
But let’s take a step back and assume the opposite for a moment: Beautifully written, clean code with complete test coverage. One-click build process. Exceptionally well-written documentation of the architecture and components. Would this have changed the situation? I really don’t think it would have.
You see, in 2017, there actually was an incident of a high profile source code theft: Panic, a company that makes high quality Mac and iOS software, had the full source code for most of their apps stolen by hackers. While the attackers demanded a ransom to prevent the public release of the code, Panic refused to pay. They came to the conclusion that the worst thing that could happen would be people building cracked versions of their Apps, full of malware. But that was already happening anyways (as with most software), even before the source code was stolen. Don’t get me wrong, I’m sure this was a pretty bad blow for Panic, and I’m in no way arguing that source code theft can’t be damaging. But even Panic says in their blog post that they were not too concerned with competitors using their code either, mainly because it would quickly become outdated:
“That source is already missing a ton of fixes and improvements we committed over the last week alone, and six months from now it will be missing major critical new features. In short: it’s old and getting older.”
So maybe code by itself is not that valuable, and yet, software companies still have value. If the tangible aspects of the technology, the code and documentation, are not the main assets of a company, what is?
What is programming
I couldn’t really wrap my head around the previous question until I stumbled upon a wonderful article, Programming as Theory Building, written by none other than Turing Award winner Peter Naur. If you’ve ever taken any formal computer science classes, you may have already heard his name: He’s the N in BNF, or Backus-Naur form, an important and widely-used notation for describing programming languages.
In the article, Naur describes his view of what programming really is. He argues that the main activity a programmer does is building a theory or model of the problem space in their head:
“[…] programming properly should be regarded as an activity by which the programmers form or achieve a certain kind of insight, a theory, of the matters at hand.”
He calls this view of programming the “Theory Building View” and puts it in contrast to what he calls the “Production View”, in which “[…] programming is regarded as a production of a program and certain other texts.”
Naur argues that the production view, while it is widespread, contradicts many things we observe empirically in software projects. In contrast, the Theory Building View allows us to explain many phenomena, such as the observation I made in this article, that the source code itself holds little to no value.1 One of Naur’s main conclusions is that making changes to an existing program (to accommodate changing requirements) is often more costly than writing new code from scratch, at least if done by people from a different team. This is because there are intangible aspects of the model/theory in the programmer’s heads, which can’t be expressed in code and documentation:
“A main claim of the Theory Building View of programming is that an essential part of any program, the theory of it, is something that could not be conceivably expressed, but is inextricably bound to human beings.”
When a new team obtains the source code, they thus have to first re-build the original theory in their heads, which, Naur argues, can be more work than building their own theory from the ground up.
Naur brings multiple examples of real life product development where teams were asked to modify or extend a program, but couldn’t do it without help from the original development team, or otherwise they would be “destroying its power and simplicity”:
“[…] the program text and its documentation has proved insufficient as a carrier of some of the most important design ideas.”
Naur further says:
“The conclusion seems inescapable that at least with certain kinds of large programs, the continued adaptation, modification, and correction of errors in them, is essentially dependent on a certain kind of knowledge possessed by a group of programmers who are closely and continuously connected with them.”
Since this knowledge is inherently intangible, it can’t be communicated through the code or documentation - it has to be experienced anew by each new programmer joining the team. While the previous programmers can help new team members in this task, the code itself and any written documentation is not very useful in this process. What are these intangible elements/aspects?
Intangible aspects of software
According to Naur, there are three aspects that are difficult or impossible to express in any written form of code or documentation, and yet the original programmer can easily explain them:
1) The programmer knows and understands the relationship of the real world problem and the program. They can explain how the details of the problem are mapped into the code and into additional documentation: “Thus the programmer must be able to explain, for each part of the program text and for each of its overall structural characteristics, what aspect or activity of the world is matched by it.”
While I think it’s possible in theory to make this knowledge more tangible through documentation, doing so exhaustively would be wholly impractical. And yet, Naur notes, an exhaustive understanding of the real world problem is necessary to understand the theory of the program:
“By far the largest part of the world will of course lie outside the scope of the program text, being irrelevant in the context. However, the decision that a part of the world is relevant can only be made by someone who understands the whole world. This understanding must be contributed by the programmer.”
Let me give you an example from my own experience. A few years back, I was working on a project that improved the processes of a production line in a factory. The workers there were still using paper checklists for quality assurance, making the process labor-intense and error prone. We replaced those paper checklists with a mobile app that runs on a tablet. While the app itself was fairly simple, the underlying business processes were complex - multiple different assembly lines and a variety of different machines were involved. Furthermore, the environment was changing and evolving frequently - workers often changed shifts around, the WiFi in the factory would go down or be unavailable in certain areas, machines would break down, etc. Since any downtime would incur significant costs, the app had to be prepared to handle all these situations.
Communicating the mapping of the code and the real world, as Naur describes, would have required us to document all these processes in meticulous detail. If we had tried to, I believe the result would’ve been multiple hundred pages describing the business processes, either as a separate document or somehow annotated in the code. This would on the one hand have exploded the budget, and on the other hand would’ve had little use for any new programmers onboarded to the project. Combing through all this documentation would’ve been so time-consuming and tedious that nobody would’ve done it.
However, this is a fairly weak argument - just because something is tedious, it’s not impossible. So let’s take a look at the second intangible element Naur describes:
2) The programmer can explain not only how the code maps to the real world, but also why such a mapping was chosen. This justification could be, according to Naur, for example: general design principles, quantitative estimates, and comparisons with alternatives. What’s important to note is that these decisions can’t be made only by blindly following rules. The experience and intuition of the programmer comes into play: “The final basis of the justification is and must always remain the programmer’s direct, intuitive knowledge or estimate. […] the decision that they are relevant to the situation at hand, again must in the final analysis remain a matter of the programmer’s direct knowledge.”
Going back to the factory example, let’s assume we would’ve spent the time to write down all the business processes as described above. Then, we would’ve had to also add explanations and reasoning for most technical decisions. For example, we could’ve explained that we included an offline mode in the app for when the WiFi in the factory goes down. On a high level this makes a lot of sense to document and we actually did exactly that. But as you go deeper into the problem, this again comes with significant cost, both in creating this documentation, as well as for any new programmers reading it.
However, I think the third intangible aspect Naur mentions is the strongest argument for the Theory Building View:
3) The programmer can respond to a change request: The problem in the real world has changed somehow, now the programmer has to judge how similar the new situation/problem is to the old one. Just like in the previous point, these decisions can also not be encoded into strict rules: “Designing how a modification is best incorporated into an established program depends on the perception of the similarity of the new demand with the operational facilities already built into the program.”
Here it becomes clear that this can’t be expressed in written documentation. It involves making decisions on how to deal with changes in the real world that couldn’t have been anticipated when the original program was written. Otherwise, they could already have been incorporated in the original design of the program.
Going back to the factory example: At some point during live user tests, we found out that the data entered by the workers in the factory was inconsistent. After much investigation, we realized that this was due to them sometimes taking unplanned smoke breaks during their shifts. It was pretty easy for us to make minor adjustments in the app to incorporate this new requirement. However, if we hadn’t caught the data inconsistency during development, making this change for an entirely new development team taking over the code would’ve been a significant amount of work. Of course, since it was a completely unexpected requirement, it would also have been impossible to write any kind of documentation or advice on how to deal with it in advance.
It’s important to note that Naur also says it’s possible to transfer a program’s theory between programmers, but it requires personal interaction:
“What is required is that the new programmer has the opportunity to work in close contact with the programmers who already possess the theory, so as to be able to become familiar with the place of the program in the wider context of the relevant real world situations and so as to acquire the knowledge of how the program works and how unusual program reactions and program modifications are handled within the program theory.”
He even compares these interactions to teaching a skill like writing, or learning a musical instrument, which requires constant personal instruction from a teacher.
Imagine an expert piano player. They could “document” in meticulous detail where exactly they put their fingers while playing. But even with the most fine grained detail, you wouldn’t be able to learn how to play the piano just by reading this documentation.
Conclusion
If we agree with Naur’s assessment of programming, what follows is that the value of a high tech company is inseparably interwoven with the development team, and the model of the problem domain in their heads. What this means, in essence:
The main value of a software company is the mapping of source code and problem space in the developer’s heads2.
This conclusion has important consequences for many aspects of a software company, but especially for management, hiring and overall culture.
Management & Culture
Most efforts to make software more flexible or modular, and thus programmers more replaceable are misguided. As Naur writes: “[…] much current discussion of programming seems to assume that programming is similar to industrial production, the programmer being regarded as a component of that production, a component that has to be controlled by rules of procedure and which can be replaced easily. […] At the level of industrial management these views support treating programmers as workers of fairly low responsibility, and only brief education.”
He argues that developers should be given more responsibility and regarded as permanent assets to the company.
If you’re in a management position, you need to realize that development is mainly decision making, which of course only works if you’re given the necessary autonomy to make those decisions. I believe this realization is one of the main reasons many successful companies have a better engineering culture.
Here are some concrete recommendations for management:
- Give your developers enough autonomy and decision making power. They need to be involved in decisions not just on How to build something, but also on What to build
- Put your developers as close to the customer as possible (and as they’re comfortable with). This is the only way they can build an intuitive understanding of the real problem they need to solve, and after all, this understanding is the main value of your company.
- Trust your engineers. When they ask for more time, there is probably a reason.
- Don’t attempt to measure developer productivity, since it’s an inherently unmeasurable quality. Sometimes, an afternoon of just thinking about a problem, without producing any tangible artifacts, can be the most important thing your company needs. After all, developers spend most of their time figuring out systems.
Hiring
- Teaching is an undervalued skill, especially in senior developers
- Retaining talent is even more important than you might think. It’s crazy that in an industry where the main value is tied up so much to individual contributors, people change jobs every two years
- The Theory Building View also gives us insights on how to structure onboarding processes. It helps to explain why new developers often takes a very long time until they reach full productivity
Really understanding why autonomy is important will not only help your company, but also improve your hiring processes. Your engineers will be much happier, and this will trickle down into hiring and make things much easier in the long run. It’s not an easy change to make but it’s worth it.
If you want to really improve your hiring and get some actionable advice, feel free to read my most popular essay on this topic: When hiring senior engineers, you’re not buying, you’re selling
You might also be interested in my book.
About the author
Hi, I'm Alexander, I'm a Senior Software Engineer from Vienna. I have many years of experience in Software Development, Product Management and Project Management. I've worked on exciting software in various industries, including Augmented Reality. Throughout my career, I've helped companies ship more than 25 different products, so I know both sides of the hiring process very well. I now do consulting and workshops on hiring engineers. Do you want to work with me or have any questions about hiring engineers, recruiting, or software engineering in general? Just send me an email, I'd love to hear from you!
Buy the book
More posts:
When hiring senior engineers, you're not buying, you're selling
Why your job description fails to attract senior engineers
- Naur noticed slightly earlier than me - his article was published in 1985 [return]
- However, I believe this statement is only true for software companies where the core technology is the main asset. For many software companies, the main value might not lie in their technology, but in other things, such as the network effects, relationships to customers, etc. [return]