Last time, I covered some generalities and anecdotes about minimizing complexity in my life. Today, I have a few more thoughts about complexity as it relates to software.
Software engineering has continually evolved since the inception of computer programming languages. One way of looking at that evolution is to see it in terms of improvements on complexity management. (This is a bit simplistic, since computers have simultaneously become much more complex.)
The first computers were simple by today’s standards, but the programming methodology was very complex: dials, levers, buttons, or physically connecting wires. Then machine language was developed binary code could be entered on a card, later memory, and interpreted.
These early languages required a perfect familiarity with the machine. If the machine changed, the code changed.
Over the years, the advances in languages have largely been a process of hiding the machine’s underlying complexity. ALGOL came around and hid the machine code and provided the foundation for FORTRAN and C. C built further by providing both structured programming tools and an abstraction of the machine’s language–one foot in each world.
Terminals began to have graphics capabilities and SmallTalk was developed to further hide the complexities of both growing code modules and user interface elements. Java hid the complexities of lower-level code like C and C++, and even took away the concept of a physical machine and substituted its own virtual machine, theoretically consistent across all physical platforms. C# has done much the same for Window–hiding the complexity of thousands of APIs in a hierarchical, intuitive framework of managed code.
Modern processors are beasts of infinite complexity and power compared to the early hulking iron giants, but the languages which we use hide nearly all of the complexity that our forebearers had to deal with on a daily basis.
Now it looks I’ve been really writing about abstraction. It’s extremely strongly related, but I don’t think it’s exactly the same thing. Abstraction is thinking at a higher level; minimizing complexity is thinking less.
Modern languages both abstract away lower level concerns and provide tools to minimize the complexity of things at the highest level.
There is increasingly a proliferation of visual tools, begun with GUI editors, but now including visual code designers.
Aspect-oriented programming and attributes are allowing complexity to be further minimized.
In the future, tools such as these, and increased use of COTS will become vital to accomplishing anything. Software complexity will only increase, but hopefully the trend of tools that minimize complexity will also continue.
Perhaps somebody (not me!) should investiage the theory of a total complexity quotient–a measure of the complexity of a system and the complexity of the tools to develop and manage that system. With this number we could measure if complexity overall is increasing or decreasing, and what/when is the crossover point.
Check out my latest book, the essential, in-depth guide to performance for all .NET developers:
Writing High-Performance.NET Code, 2nd Edition by Ben Watson. Available for pre-order: