It is a distressing thing to see how much of programming today is still discussed in terms of all-or-nothing propositions. Whether it's the insistence that one language, or type system, or model of development is inherently and universally superior, I find the lack of nuance troubling. Life has taught me well that most of the benefit of techniques and technologies lies not in their absolute or universal application, but rather in using them with discrimination.
- Enterprise architects challenged to manage data explosion
- The IT Manager's Guide to Deploying Social Business Software
The dogmatic insistence on using one exclusive approach rings of inexperience or, if proclaimed by an experienced hand, a lack of thoughtful consideration. When young I was and green, I had all kinds of ideas on how code should be written. Since I was inexperienced and didn't appreciate how inexperienced I would passionately argue for techniques and tools that, in retrospect, I only partially understood. Mostly, they appealed to me for some aspect whose limitations were a sealed book, but whose benefits were completely obvious if only I could get others to recognize them, too. I was full of wonderful ideas and remedies. I was living the life of an insufferable fellow, but enjoying it because, dang!, I just knew so much. And where I lacked specific knowledge, I relied on people I admired, who used this or that tool or some special technique. If it was good enough for them, well, it was good enough for me, let me tell you. (Today's more common equivalent is, "My professor says that…")
Maturity brought wisdom and I began to realize that few indeed were the tools and practices that could be recommended universally. I also started to see that even for proponents of various techniques, there was always wiggle room. Exceptions to blanket rules were not to them evidence of imperfection in their beliefs, but validation that the real world could not be entirely reified to comply with a single edict.
For example, let's take a practice that seems to elicit more religion than many others: test-driven development (TDD). The steps in TDD are all well-known, formulaic, and perfectly set up for doing all things exactly one way. A key principle of TDD is that you write no code without first writing a failing unit test. But in fact, if you talk to the principal advocates of TDD (such as Kent Beck, who popularized the technique, and Bob Martin, who has taught it to thousands of developers), you find that both of them write some code without writing tests first. They do not I should emphasize this view these moments as lapses of faith, but rather as the necessary pragmatism of the intelligent developer.
It is tempting to view programming in moral terms because we so often refer to code as good or bad, but programming lacks the defining overarching moral imperative towards which good things tend. To wit, the frequent example of the three divergent poles in programming: good, fast, and cheap. Different projects work within the constraints imposed by individual blends of these properties, which is why a CRUD app has more tolerance for errors than a pacemaker and why holding that some practice is the right way in all circumstances is bound to be wrong. Such a view, in my opinion, is a meta-level code smell.
Even if we limit ourselves to a smaller segment of software for example, pacemakers the way forward is certainly one of discipline and rigor (within the constraints of quality-performance-cost), but not orthodoxy. Where exactly is the line drawn? It is, in my opinion, wherever activity that is valid in one area is extended beyond the area of its benefit. Let's choose a simple example: commenting. If the rule is to comment all code, then orthodoxy has prevailed over pragmatism. Such excessive commenting is likely to be costly, slow, and bug-ridden. That is, all three vectors point the wrong way. 100% test coverage of is a more subtle example. It's the extension of a good idea to every aspect of an activity almost always a sign of orthodoxy. I could go on with other instances, such as language selection, agile and DevOps practices, testing, and nearly every other aspect of development.
The best programmers I've met are not only intensely pragmatic, they actively pursue pragmatism. They look at new technologies, so as to avoid choices made inadvertently orthodox by ignorance of alternatives. They use tools in a balanced way that ruthlessly seeks delivery of intended results within the established project constraints. The more I work like them, the better programmer I am.