Orthodoxy
Programming is neither a science nor an art. Science proceeds from hypothesis through test to confirmation, and art is as much about the means of expression as it is about its themes. Software, by contrast, is written to solve a problem that’s fundamentally more important than the means of its solution. Often that solution has existed since ancient times and simply needs to be encoded as an algorithm that works in the particular environment of the software’s patron. I’ve written at least four implementations of accounting ledgers, for example, and those motivated the earliest writing systems1 and have existed for centuries in their modern form.2
Instead, the best category for programming is the craft. We work in a well-understood material to solve well-understood problems, but face (and erect) significant barriers to entry in new problem domains and the craft as a whole. The closest analogue to what we do is the medieval artisan. A glove-maker or silversmith from the 14th Century wasn’t pushing his craft forward, and usually wasn’t working on pieces that expressed his own inner creativity; instead, he was working in well-understood materials to solve well-understood problems.
Like artisans of that era, modern software developers and their patrons are also deeply concerned with competition. There’s a tension here. Developers are valuable, relatively independent, and insecure. Patrons—companies and investors—are cost-conscious and primarily concerned with solving their ancient problems. I doubt we’ll see anti-worker legislation like the 1351 Statute of Laborers,3 but the difference in motivation is still there.
Medieval workers in skilled crafts often responded to the tension by organizing themselves into guilds. Guilds held knowledge close—sometimes so closely that it has been lost to history. They also controlled competition, even resorting to beating or killing people who violated the guild rules on the practice of a craft. They limited the labor that the “uninitiated” could perform, keeping non-guild labor limited to low skill and low pay tasks.
The effect on the craftsman was to encourage a sense of orthodoxy. A man wasn’t a glovemaker until he had learned the craft from a master, and his choice of master affected the techniques that he viewed as “correct.” Only slow progress and change was possible, which was expected: the worldview underlying the “guild mentality” was one of stasis. The Medieval world assumed that society was a steady state. Labor shortage was understood as a moral problem among the peasantry, not the result of population loss during the plagues. Inflation was because of greedy merchants, not because of the debasement of coinage.4
It’s counter-intuitive to think of the craft guilds as parallel to modern software development. Of all industries, software has changed the most in its short history: it didn’t exist a century ago, and constant change has characterized the possible within the craft, because of the constraints of technology rather than technique. As that environment has stabilized, however, behavior patterns have emerged that I believe would look familiar to any historian of the European middle ages.
First, a lot of us tend to seek an orthodox approach that will allow us to learn “the one true way” and ride that wave through our career: object-oriented programming in the 1990s, XML-based “service-oriented architecture” in the 2000s, NoSQL and microservices in the 2010s. Each of these waves consumes a “generation” of new programmers, largely supplants its predecessors, and ultimately proves susceptible to the same problems that it purported to solve, or worse ones. It’s almost as if there’s no silver bullet.5
Second, once we’ve found our preferred orthodoxy, we defend it rabidly. If you criticize a microservices approach online, there are people who will descend on you like the Wicked Witch’s flying monkeys. Explain failure modes you’ve seen using dynamic language frameworks like Django or Ruby on Rails, and dark figures will begin lurking outside your house. Laugh at Go’s error handling or Rust’s syntax and moderately unhinged YCombinator and lobste.rs comments are inevitable. It’s a difference of degree, not of kind, from the protectiveness and clannishness of the medieval guild.
Last, both the orthodox approach itself and the defensiveness it inspires fail to accomplish the goal of future-proofing our careers. Just as guilds could not cope with changing socioeconomic realities and lost most of their strength by the 16th Century, software orthodoxy fails to protect the average developer’s productivity and job prospects. As waves of new orthodoxy arrive, the old faithful are supplanted. As technology changes, tasks and roles that were taken for granted disappear, while new ones appear and are not accounted for.
Guildsmen didn’t face these fates, because the pace of change was so much slower, but a typical developer who began in the 1980s has already weathered at least three waves of new orthodoxies. How do we escape the cycle? Some developers escape into management, retreating into meetings and, too often, defense of their orthodoxies from on high. Others fail out, eventually becoming unemployable or marginally so. The keys to the “good escape,” where a developer remains valuable and valued are curiosity and openness. As I discussed in “Information Curation for the Programmer,” there is knowledge available to us from other disciplines that can be digested and applied to our own discipline. Seeking out that knowledge and wisdom allows you to develop a well-rounded perspective with more tools to apply to new problems than a single off-the-shelf orthodox methodology can offer. More critically, a lot of the orthodoxies aren’t even particularly deep: object oriented “patterns” often offer a vague description, for example, and can leave the initiate floundering when dealing with a problem that varies slightly from the canonical examples.
More concretely, experimentation with new tools and techniques is a critical practice. In “Generative AI and the Programmer,” I laid out what I think is a pragmatic approach to using LLM-based generative AI. I’ve developed that from an initial period of absolute skepticism by experimenting with them myself. Similarly, trying a framework like Django or a language like Rust or Go is the only way to develop an informed opinion about those tools.
Last—and probably most controversial—is the social question. Don’t defend orthodoxies. If you find an online comment infuriating, breathe. Remember that many developers are going to “flame out,” and as a high-value and high-visibility craft, programming attracts many glove-makers who have never sold a single glove, so to speak. Close the tab and open your Anki deck6 or your Obsidian vault.7 Focus on building your own set of tools and helping those with whom you have a direct connection, and you can stand calm as the waves of orthodoxies break around you.
-
Proto-Cuneiform tablets were used to record accounts in grain, beer, and other goods as far back as Uruk, in the fourth millennium B.C. ↩︎
-
Luca Pacioli, a Florentine contemporary of Leonardo da Vinci, is considered the “father of accounting” because he explained an essentially modern double-entry accounting system in the 15th Century. ↩︎
-
This law attempted to control the price of labor by requiring that people work when asked, setting fixed prices for many tasks, requiring contracts rather than day rates, and codifying strict penalties. ↩︎
-
If you’re interested in these topics, Dan Jones is an approachable author on the subject, with Powers and Thrones being a good, general Medieval history. (Note: This is an Amazon affiliate link.) ↩︎
-
Fred Brooks’ 1986 paper, “No Silver Bullet”, should be required reading for any practicing or aspiring software developer. ↩︎
-
Anki is a spaced repetition flashcard program, very useful for learning subjects like foreign languages. It’s available for free. ↩︎
-
Obsidian is a personal knowledge management system that is excellent for managing learning resources and taking notes, with many extensions. It’s also available for free. ↩︎