In spare moments over the last couple of weeks, I’ve been preparing for a keynote I’ll be giving in May. My talk is titled Timeless Design Principles, and the thrust of it is to demonstrate how the software design principles I teach on my Codemanship courses could have been applied going back through the decades with the technology of the day.
The fact of the matter is that no programming language forces you to write readable, simple, modular code that’s low in duplication. Sure, some make it easier than others. But not so much easier that we can just take our foot of the design-thinking gas and coast.
Let’s travel back through the decades to illustrate what I mean…
- 2009 – Ten years ago, Ruby was very much the language du jour. The fashion was very much to build on the Ruby On Rails framework, which is very database-centric. A lot of Ruby code I saw back then had a distinctly 2-tier “transaction script” flavour to it. Not much going on in the way of true data encapsulation, with everything tightly bound to the database schema or the UI. This wasn’t the language’s fault, of course. As a dynamically-typed OO language, there’s nothing stopping us writing effectively modular code. There’s nothing not stopping us, either. Does Ruby S.O.L.I.D.? Sure it does.
- 1999 – The reigning monarch of late 90’s programming languages – measured by how many people built software with it – was Visual Basic. In 1999, we were on to Visual Basic 6, which had some basic elements of OO. Again, the fashion was very much for database-centric GUI applications (and web applications) that had little in the way of effective modularity. To be fair, Microsoft’s own architecture advice kind of pushed developers in this direction, with “business logic” layers that marshalled database recordsets to the user interface and little else. But, again, you don’t have to do things this way. The secret modular source in VB6 was Microsoft’s Component Object Model (COM). Through the use of COM interfaces, we can hide data, make dependencies easily swappable and present client-specific interfaces.
- 1989 – In the late 80s, C ruled the world. And, again, the fashion for programming/design style wasn’t very modular. But, also again, there’s no reason why you can’t write modular code – simple, single-purpose, interchangeable modules that hide their internal data/workings – in C. It has everything a language needs to S.O.L.I.D. Indeed, if you know how, C can in fact be as OO as most OO languages. Or as FP as most FP languages (especially GNU C).
- 1979 – At the end of the 70s, Fortran was the most widely-used programming language in scientific and engineering computing. At university, I used Fortran 77. I was interested to see if it could S.O.L.I.D., and – you know what? – it kind of does. The dialect of F77 I used in this example differed from the language I remembered from university, though. Specifically, the F77 I wrote on Sun Sparc workstations supported data structures, which would have helped enormously with encapsulating data, in a C style. But, crucially, F77 had a basic form of dynamic dispatch, achieved by pasisng function references into functions and procedures, so a degree of swappability was possible.
- 1969 – Going this far back, the choice of languages gets much smaller. And I’ll be the first to admit that there weren’t many choices that had the features I needed. But there were some. I chose the highly influential Simula 67 – the first recognisably object oriented programming language – to illustrate. The rather bizarre thing about this little demonstration is how, in many ways, Simula 67 was more advanced than programming languages that came decades late, like Visual Basic.
- 1959 – Now we’re getting closer to the dawn of computer programming. The first 3GL, Fortran, only appeared in 1957. But was there really a programming language we could have applied the principles of Simple Design, Tell, Don’t Ask and S.O.L.I.D. in 60 years ago? One word: LISP.
What’s in vogue right now is functional programming. I hear devotees of FP say on a regular basis “Oh, FP is inherently S.O.L.I.D.” Oh, really?
Even in the purest of pure functional languages, the compiler won’t force you to write functions and modules that do only one job. It won’t force you to hide the data (indeed, some encourage us not to with data classes!) And it won’t force you to inject function dependencies to make them easily swappable. And it certainly won’t force you to write code that works, or write code that’s easy to understand, or write code that’s low in duplication and made from the simplest parts. We still have to think about all of these things in 2019. Just as we did in 2009, 1999, 1989, 1979, 1969 and 1959. And I have very little doubt we’ll still need to think about them in 2029, 2039 and beyond.