Code Incomplete


A semi-fandom stroll through the multiply bifurcated path paved with varied indentation but set on an eerily accepted foundation, loosely affiliated to the corresponding SWEBOK V4 Knowledge Area (KA), already gone through Public Review[1], and currently being worked on its revision.
«The American people finally adopted the term because, I think, it sounded elegant and they thought that “programmers” would make more money than “coders”.»
- Grace Murray Hopper
Software construction, a.k.a. coding, refers to the minutiae creation, modification, and deletion of text, most likely in a high-level programming language while employing some arcane techniques and blob imagination involving coding per se, its concurrent verification, testing, and debugging, to write up a description of a system capable of execution as expected by a given computing device.
It’s a recurrent activity, unfolding at every stage of the software development process life cycle as it swirls in the middle of a back-and-forth flurry between nitty-gritty design and obsessive-compulsive testing.
Software construction typically produces the highest number of configuration items needed to be accounted for in a software endeavour, preferably subjugated to proper software configuration management.
You’re building it, for God’s sake!
The written code is the construction’s ultimate deliverable, hopefully abiding by stated software quality guidelines and a functional criteria of usefulness drawing on the foundational knowledge of computer science and software engineering that supports the whole of software development at largesse.
The written description of a software system, other than a toy - a trivial one - is no simple matter, as it gets complicated rather quickly and, before you know it, complex, which is complicated with lots of curly hair and sticky mud.
Brace for complexity
Hence, the first key goal in software construction is to minimise complexity, an inexhaustible attempt that applies to its every aspect. Our world is too complex, and our abilities too limited[2] to convey meaningful intent to computers and, particularly, to see it through to wishful conformity.
Very much like since Aristotle, the things of this world have been bestowed with accidental and essential properties, seen in software as difficulties[3], the essential ones being the core problems meant to be solved, not removed; accidental difficulties are the problems brought along with the solving, inherent to the crocheting of software in general.
Complexity arises primarily from variety, which, incidentally enough, is a requisite[4] for systems viability under the give and take between design and what emerges from all its interrelating rubbing parts.
Other mundane sources of complexity are the overall size of the system, the extent of functionality provided, and the aviary’s population density[5].
From a bean counter’s perspective, complexity hinges on the increment in bug or defect rates, lower defect-removal efficiency, descending development productivity, and higher maintenance staffing needs[6].
Embracing change
Borrowing from Heraclitus, we can say what is truly constant in software is change and only change. It’s the coded evolution, dissolution and reanimation of the evanescent user story enmeshed in novel insight and foretold legacy, where structure and chaos meet at the regenerative fountain, intersecting all wonders of open possibilities.
Embodied solely in its spectral functionality, software is an organised assortment of statements, routines, classes, and packages that tie and tethers itself under the pressure to change in tandem with a culturally bound shebang of users, applications, interfaces, and laws constantly in flux.
Incidentally, software can be changed with relative ease as it’s made of pure thought stuff, infinitely malleable, eluding the earthly, materially constrained reality embedded in physical space.
The awareness and anticipation of change in software should help build flexibility and adaptability, making it extensible enough to allow the incorporation of changes with the least possible difficulty.
Somewhat ideally, an evolutionary environment can provide flexibility and adaptability by building evolvability into the software architecture[7].
Evolvability is the ability of a system to adapt to changing requirements and is closely linked to the system's simplicity and sound abstractions, which can be maintained through fashionable Agile working patterns and technical tools such as test-driven development (TDD) and refactoring.
A steady flow of software tidbits in a sequence of cumulative increments through a continuous integration and deployment (CI/CD) pipeline can help develop robust software in a frequently changing environment, minimize the risk of introducing bugs when making a change, and maintain the ability to understand and reason about the system to tackle hidden assumptions, unintended consequences, and unforeseen interactions.
Evolutionary architecture practices and design patterns such as abstraction, layering, and generalization can help address an ever-changing business landscape by being kept in the mind’s eye while writing code[8].
Trust but Verify
A mild success in minimising complexity while navigating the ever-changing essential and accidental difficulties of writing functionally understandable code implies that such a wonderfully resulting assemblage is also amenable to verification.
However crucial it may be, program verification is a challenging task requiring significant resources and expertise. People are generally better at programming than verifying, leading to a gap between what can be programmed and verified[9].
Verification can be static, involving the perusal of code to ensure that coding conventions are followed to facilitate code review and automated testing, namely by static analysis tools that can check the code for errors and vulnerabilities. Dynamic verification includes the typical quality assurance tasks such as unit and functionality testing, executing the code with different inputs to test its functionality and performance.
Restricting the use of complex or difficult-to-understand language constructs, or so-called clever code, usually pays off handsomely during verification and quality assurance.
Reuse
One of the most chimerical, Fata Morganic Holy Grails of software development is the reuse of software assets, including frameworks, libraries, modules, source code morsels, and commercial off-the-shelf (COTS) functionality.
One can either build software for reuse or build software reusing some of it, both approaches involve balancing the benefits of reduced costs and increased productivity with the challenges of increased coupling, decreased flexibility, and potential complications in maintenance and modification.
In a nasty, off-putting sense, reuse increases dependence between the code that’s, well, reused, leading to the accidental difficulties that hamper ease of change, particularly of the kind one wants to apply to some instances where that code is reused and not to others.
Therefore, software reuse is the process of reusing software that was originally designed to be reused. It’s not software salvaging, that is, reusing software that wasn’t designed to be reused, and it’s also not just carrying over some code from one version of an application to another[10].
Hold on to that Ariadne’s thread
Once inside the labyrinth[11] of software construction, to achieve at least some good of the above, one should follow some standards; even if only a sort of pirate guidelines, following them consistently will be paramount.
Though you might not have much control over most of them, there are some items about which a proper selection should be made, such as the programming language you will be immersed in, the conventions that hold the relationship between the system’s conceptual integrity and its low-level implementation, such as guidelines for variable, class, and routine names, text formatting and commenting conventions, as much as the programming practices related to coding and teaming that, in turn, depend either on where you find yourself on the adopted type of development life cycle, and the technology wave du jour[12].
“Every damn thing worked. We didn’t have much to deal with, but everything worked…
With me the accomplishment is getting the ideas. As soon as you got the ideas, anybody could build it.”
- John Atanasoff, describing his 1939 prototype
[1] SWEBOK Evolution - IEEE-CS SWEBOK V4 Public Review (3rd Batch) – Comments Closing 9 January 2022 - https://www.computer.org/volunteering/boards-and-committees/professional-educational-activities/software-engineering-committee/swebok-evolution
[2] William C. Wimsatt (2007). Re-Engineering Philosophy for Limited Beings: Piecewise Approximations to Reality. Cambridge: Harvard University Press.
[3] Joseph Ingeno (2018). Software Architect's Handbook. Birmingham: Packt Publishing
[4] William Ross Ashby (1958). Requisite Variety and its Implications for the Control of Complex Systems. Cybernetica. 1 (2). http://pespmc1.vub.ac.be/books/AshbyReqVar.pdf
[5] Richard Anthony (2015). Systems Programming - Designing and Developing Distributed Applications. Morgan Kaufmann.
[6] Capers Jones (2007). Estimating Software Costs: Bringing Realism to Estimating, Second Edition. McGraw-Hill.
[7] Martin Kleppmann (2017). Designing Data-Intensive Applications. Sebastopol: O’Reilly Media.
[8] Neal Ford, Rebecca Parsons, and Patrick Kua (2017). Building Evolutionary Architectures. Sebastopol: O’Reilly Media.
[9] Charles Pfleeger and bunch (2024). Security in Computing, 6th Edition. Pearson Education.
[10] Will Tracz (1995). Confessions of a Used Program Salesman: Institutionalizing Software Reuse. Addison-Wesley.
[11] Doob, Penelope R. (1990) The Idea of the Labyrinth - from Classical Antiquity through the Middle Ages. Cornell University Press. Open Access edition: https://www.cornellpress.cornell.edu/book/9781501738470/the-idea-of-the-labyrinth-from-classical-antiquity-through-the-middle-ages/
[12] Steve McConnell (2004). Code Complete, 2nd Edition. Microsoft Press.
Subscribe to my newsletter
Read articles from Rui Vale directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
