Programming paradigms and methodologies don't matter all that much
I've barely been writing in this blog that I purposefully set up to just yeet stuff out there, out of fear of publishing half finished thoughts. But that was the point in the first place. I write so many things on mastodon or on slack that I think are actually worth publishing in blog form, but then never do because I feel too precious about my output. No more! This is a blog of drafts. In fact, a blog of first drafts. You have been warned.
The topic of SOLID and its value came up in one of my slacks this morning. Discussion of methodologies and how to do them right and all the jargon they come with is something that I don't really understand, and thus irritates me (things I don't understand or think are unimportant but people attach a lot of importance too irritate me. A character trait that I'm not really happy with, but it's the main driver behind my writing and thinking, and hopefully it makes me less of an apparently angry confrontative interlocutor in person).
These software design principles, these manifestos, these angry rants and preachy blog posts were written up and designed by very small groups of individuals who in software engineer fashion believe that there is a single solution to the problems of the field at large and that somehow they were the one to find it. Besides the element of self-delusion inherent to such endeavours (ignoring things that might not work so well in their own practice already), these principles don't transpose easily to other teams, projects, company structures, incentives and timelines.
Being extremely curious and naive, I've tried and embraced many “miracle solutions” to the problem of software complexity over the years, from functional programming, hardcore low-level “unix philosophy of simplicity”, lisp “program the language”, heavy-weight object modeling, design patterns, go “concurrency is easy if you just use channels”, test-driven development, microservices, you name it. I can save you the time and effort to try all of these out by summing them up with “it depends” (more seriously, please go ahead and learn as much as you can, take all of them seriously, they are all ideas and concepts that people have spent a lot of time creating and refining, there is a lot of value in each of them).
I think that at the heart of all these approaches, names, workflows, methodologies, talks, youtubes, conferences is the desire and the need to find a common vocabulary and set of practices to allow a team of developers to tackle problems with the amount of complexity that a large scale software endeavour entails. More important than the details of each is the fact that programmers collaborating on a piece of software agree on their meaning and the intent behind them.
A shared vocabulary, a shared set of design patterns, a well-oiled workflow are valuable because they reduce friction agreeing on what needs to be written and how. If shortens feedback cycles and makes onboarding easier. It gives the team a set of tools that they might already know, or can look up in published literature (vs having to learn it by osmosis, if there is anything to learn at all). If the team agrees on using typeclass heavy Haskell, which typeclasses should be used, then the team will be able to communicate in shorthand and reuse abstractions well. Similarly, a team well versed in object oriented design applying SOLID principles will be able to use shorthand when discussing design or giving feedback in code review. We all know by now that functional programming works, just as microservices work or object oriented design works, because successful products have been built by respectable engineers using them. Debating finer points is only useful in as far as you can apply the insights gained in the debate to your thinking and programming.
Getting people to agree on something that they hold dear is always a fraught endeavour-I think the key to success applying any of these principles lies less in the methodology itself, and more so in the way it gets shared and revised. It is more important to achieve consensus and a shared understanding through all the negotiation and facilitation and documentation and communication that goes with it than to perfect the technical details. They will inevitably change as the product requirements change, as new people with different backgrounds join the team, as the zeitgeist evolves, as the burden of legacy grows or technical shortcomings of the chosen framework become apparent.
I think that this explains the value of code review, RFCs and ADRs, the glue work of staff engineers, writing and blogging and whiteboard sessions and prototyping. It is all about helping different people understand each other better to build and maintain a common artifact.