The lost art of coding for the specific (not the general) case
Why ‘code reuse’ is still largely a myth, and we have yet to adopt the principles of agile.
Adaptation is one of the founding ideals of agile software development. Besides exciting new features and technological advances, changing business requirements, and competitive factors — there are always unplanned or unanticipated changes dictated to us. No solution should appear to be static or be expected to fit every case. We tend to be optimistic that our needs will grow, or third-party code will evolve, along the lines we would choose. Expectations of either change or stasis will be equally disappointing. This is life, and this is software.
We need to be cautious when we are tempted to solve the general case at the cost of autonomy and efficiency, with a fancy or trending methodology. Do we really find best practices bubbling up, costs reduced, and reliability increasing? Or are the added dependencies, learning curves, and deferred technical debt really worth it? Do our reasons and rationale stack up to the truth? Sometimes. However, they do give us the excuses to acquiesce to two other common human conditions as we make claims of ‘progress’ and ‘upgrading’ — ego and laziness. It is no longer considered ‘forward thinking’ to simply and clearly fix or build something correctly for its base purpose.
When I was made aware of a self-contained computer program (MiniChess) that could play chess against a human being, in fewer bytes of code than it took to describe the rules of the ancient game in English, I was floored. Did this mean that other tasks and systems could be designed even smaller than the explanation of their requirements and constraints? After all, that’s what we were promised in the computer revolution: that people wouldn’t have to really work anymore because machines would do almost everything for us very well and readily.
On the contrary, we have experienced a marked servitude of time, money, and attention to the devices and technologies that were meant to free us from the pre-occupation with work. What about progress? The technological tools we have in our lives, despite tech-deflation, have increased in cost, and reached a broader demand upon the average person. Our investment has also increased in terms of engagement and distraction.
The good news is that knowledge and connection have exploded exponentially, with many unforeseen wins for humanity and commerce. There is no arguing the grand payoff for many around the globe. Worldly participation, influence, potential for growth and prosperity, and the leveling of the playing field are to name but a few benefits.
But the unneeded obscurity, complexity, technical debt and productivity roller-coaster in software/technology can no longer be ignored. Forward progress, scalability, and sustainability in software call for a higher order adjustment to our priorities.
Software as a never ending process
We have seen the complexity and cost of producing a software tool to solve a business function rise from a couple hundred lines of code written in a few hours by a single person (even a hobbyist), to a whopping multi-million (or billion) dollar investment powering a team of engineers who need to be paid $100 per hour, for months or years. This may or may not result in a usable Minimum Viable Product (MVP), and may or may not drive a single dollar of revenue, and questionably results in value for the customer or investor. Rome was not built in a day, but many years ago, the prototype of eBay was coded in a weekend.
Let us not overlook the glaring fact that software projects may result in great loss, as security and financial risks emerge and grow to larger proportions. The conduct of tech companies, teams, and individual software engineers is expected to maintain the well-being of countless lives. Negligence is also epic, being a proprietary black box of people’s private moments and attention for sale. Stop reading right now if this sounds professional or acceptable to you.
Professionalism in software development
We expect a whole industry to uphold its ethics and legitimacy, with no standards or oversight. The problem is that government oversight would not be the right solution. After all, they ‘oversee’ the financial, medical, and commercial engines of the world, with mixed results, to put it mildly. Besides, as the famous saying goes: Who watches the Watchers?
Robert Cecil Martin, affectionately known in software circles as “Uncle Bob” Martin, holds a sometimes controversial position when it comes to condemning or defending the professionalism displayed in today’s software development field. Often citing sloppiness due to time or cost pressures, he decries the applying of new ‘tools’ to the process, which may ultimately further abstract the developers from the raw experience of crafting, analyzing, testing, and correcting their products and the critical services that depend upon them. He makes a huge distinction between code that ‘works’, versus code that is ‘correct’, and bemoans the lack of attention to testing and reviewing the software upon which we have become so dependent.
Uncle Bob, who still builds software (since 1970), teaches, speaks at conferences, and consults for business, belongs to the old guard of developers, from a simpler time. He would refer to as a more responsible time, because developers must have possessed a strict discipline and ability to create programs from scratch, that ran on bare metal, and did the thing well that they were tasked to do. Coders could not simply slap together some packages with configuration examples downloaded from forums, posted by amateurs and professionals alike, mixed together without discernment.
Dwindling common sense
I have witnessed in 3 decades the progression and degradation of the craft; a death by a thousand delegations and abstractions. No one can claim they understand how something works anymore, so how on earth can they take responsibility for its functions or its vital outcomes? I think this evasion of responsibility is now so embedded in our software development ethos, that we will be forever occupied deriving alibis for its whereabouts at times of failure and deficiency. Responsibility underpins autonomous power.
It seems we have a failure to communicate the true role of technology, how we steward it, and how we build an industry for that purpose. Have we become subservient to it, and to the process, by developing the way we have done so during recent years? Is there a way forward? How can we create blanket solutions for the future if we are not adequately solving today’s business/software challenges with the right mind? Albert Einstein posited an improvement of ethics along the lines that “a problem cannot be solved with the same mind that created it”, though he may not have quoted those exact words.
As one of the dozen founders of the Manifesto for agile software development years ago, Bob Martin cringes at many of the references to things that attempt to pass for ‘Agile’ today, and to be sold as goods and services under that moniker. They are simply not so. Conway’s Law gives us the vital insight that software architecture and style will definitely match the communication methodology of the organization that creates it. That sounds much like Einstein’s conundrum on solving problems!
You can’t ‘Do Agile’ without actual agility and better communication. Agility is not a discipline which can be enforced upon us, like the hand of a firm but loving parent or partner. But neither should it be paid mere lip-service and packaged as a product itself, for the aggrandizement of consulting firms and certification publishers. It must not simply enable new ways of solving problems, but essentially give us permission to avoid repetition of the mistakes of the past, otherwise known as ‘insanity’.
That is where we find ourselves today, circling down a never-ending spiral of complexity that claims it will save us from ‒ our own complexity. Well, there’s only one thing sure to capsize us worse than our own folly, and that is adopting someone else’s that we comprehend to an even lesser degree. Not faster, but worse. It doesn’t happen all at once, but it is only unmistakable once it is too late to turn back. There can be no grand re-design of the world at this point. We are still stuck with computer systems and software from the 1970’s, running mission-critical banking, industrial, and perhaps military systems. To be fair, some of it is still better than the new stuff, thanks to Uncle Bob’s ilk, and the diligent followers of sound software development and maintenance principles.
Specific situations call for specific solutions
The solution remains individual wisdom and differentiation of purpose. Specific attention, not generalization, needs to be applied to problems in software technology, as in business. We attempt to solve everything with myriad pieces of seemingly carbon-copied issuances of software. Simpler is more attainable than solving the general case, and is more easily subject to future revision and prevention of lock-in, as with anything appropriately built with agility in mind. Autonomy reduces dependency, and that is powerful too.
Some added benefits of implementing simple solutions:
1) Tightening feedback loops and preventing the huge loss of resources applied down the wrong roads, or barking up the wrong trees,
2) Being at the forefront of change, not lagging behind competitors who could afford to waste more money in a quicker fashion,
3) Leveling the playing field for smaller software vendors and solution providers, for a market which favors decentralized technology implementations, rather than concentrated, monolithic models.
4) Renewing an industry’s production capacity which is currently lagging behind demand,
5) Driving an industry by creative intelligence, rather than worshipping the artificial variety.
6) Freeing resources to apply to correctness, adaptation, quality standards, privacy, and security, not just basic functioning and stability.
7) Improving the degrading mental and professional health of practitioners in the software development fields,
8) Efficiency, reduction of overhead and wasted energy in team/project management,
9) Better software,
10) Reduced risk and increased safety for humans affected by software (who isn’t?),
11) Reduced planned and unplanned costs,
12) Operational efficiency,
13) Industry recognition and customer reputation,
15) Loss Prevention.
If all these tangible benefits are not the goal, then perhaps we have all sidestepped them in favor of attaining fear-based or ego-driven ones, based upon mere illusions. We can no longer afford to do this. We must mature and become more professional, to meet the growing demands of the industry: the customer’s industry, not our own.
The solution is up to us
How can this be accomplished? I believe discipline is the answer, and much practice along the correct lines. Likewise, we must train our handlers to adjust their expectations and to temper their temptations to use all the fanciest infrastructure. We need to respect first principles and directly solve problems, though it may come across as counter-intuitive. We need to adjust our very intuition in these matters. We need to resist trying to turn the next web form we need to build, or the next deployment script into a billion dollar startup idea. We need to throw out software, and we need to say ‘no’. It’s our responsibility because, as Uncle Bob says, that “we are paid to know, and they don’t know”. We must say ‘no’ to them when we need to.
We need to employ a different idealism of practicality, not fantasy and fallacy. Properly identifying the right tool for the job requires an ear and patience to the wisdom of our elders, such as those who sent humans to the moon, and returned them to earth, with about 64K of ram. Today, few developers would even know how to display a photo without a browser or downloading a 10MB graphics library and importing it into a GUI toolkit, compiling a 100MB Java application, and deploying it through a cloud pipeline with automation scripts. Because let’s face it, who can bundle code with a text editor by hand anymore, or parse binary data? Perhaps we need therapy for this obvious psychological (and likely emotional) dysfunction in how we apply logic to one of the most vital fields of human endeavor in 2022. We are tasked with generating and managing the software systems that will eat the world. It will only get irreparably worse if untreated. Even terminal.
Do One Thing and Do It Well
In years which have unfortunately left us behind, developers were respected and rewarded for diligence, rather than shortcuts and introducing misunderstood dependencies, no matter how ‘industry standard’ they were. Unless it came to the UNIX standards and philosophy, which are some of the last bastions of sanity in software development. This is demonstrated, year after year, by the sheer longevity and pervasiveness of that legacy and the Linux underpinnings of our modern world with respect to network and web technologies. The philosophy did not originate or end with software in particular.
The UNIX philosophy cements a mentality and a discipline that must never waver, if we are to survive the ever-increasing demand for software development, along with the inadequate rate of preparation of practitioners in this and related fields.
Professionalism, as Uncle Bob promotes it, must be exercised and defended from the bottom up, and cannot be imposed any other way.
In this developer’s humble opinion, this principle is the one essential ingredient in the recipe of integrity, which cannot be substituted by anything else, especially not by tools which hype their ability to solve everything, to perhaps the detriment of solving nothing well.