Who do you want to KISS? - About simplicity in coding
What does the programming KISS rule really mean? How do you write KISS code like required by TDD for phase two when going from red to green? To answer that we need to know what simplicity is. Wikipedia says
"Simplicity is the state or quality of being simple. Something which is easy to understand or explain seems simple, in contrast to something complicated."
Well, that helps, doesn't it? No, I don't think so. Because it begs the question: What is easy to understand?
I was wandering in the dark for a long time myself. Couldn't really get a hold on simplicity. I had the feeling I knew what it meant - but then it still was hard to explain. But fortunately those days are over.
A definition of simplicity
What one day cleared my understanding was a simple sentence I read on a page of B.J. Fogg:
"Simplicity is a function of your scarcest resource at that moment."
Suddenly simplicity was easy to recognize and to apply.
But let me explain what my understanding of this definition is:
- function of: Simplicity is related to something. Simplicity thus is relative. There is no absolute simplicity. Rather it's in the eye of some beholder.
- resource: Simplicity pertains to time, space, or any other resource. If something is simple more of a resource is left than if it was complicated.
- scarcest: If more than one resource is involved in a matter then effort to create simplicity should focus on the most limited resource or the resource that's hardest to replenish.
- at that moment: Simplicity is no only relative in terms of resources but also in time. What is simple today might no be simple anymore tomorrow. And which resource to focus on today to relieve through simplicity might not be the resource to focus on tomorrow.
Now, is this a simple explanation of simplicity? :-)
Taking it seriously the answer has to be: It depends. It depends on the resource it tries to unburden.
What could possibly be resources involved here? How about:
- Screen real estate
- Memory on your computer
- Memory on some server
- Bandwidth
- My time writing it
- Your time reading it
- Your time applying it
And what's the scarcest resource in this list? The physical resources are plenty today. Those couple of KB are no burden on any of them. Which leaves us with time.
Is my time the scarcest resource? No. I'm willing to put it in. I'm writing pretty fast and it's fun. No need to minimize its use - especially compared to your time or time combined time of all readers. If I put in 2 hours instead of maybe 1 but thereby save each of a thousand readers just 1 minute in reading of applying the explanation... then that's an hour well spend as a producer to save 16 hours on the consumer side.
So it's about your time. But is this supposed to be a simple explanation with regard to your time reading it - or in the end applying it?
It seems a text like this should be succinct to save you time reading it. The average attention span on the web is short anyway. But I think that would be a misunderstanding. Striving for succinctness to make it a quick read is not targeting the really scarce resource. Your time right now might the short - nevertheless you're investing it in reading. Reading, learning, that's what you want to do in this moment.
Sure, the more you can suck in during that time the better. Your time for reading surely is limited. But what's even more limited is your time designing a solution or writing code or setting up infrastructure. And it's during that time you don't want to get distracted by complicated definitions of simplicity. You need a simple definition to save your scarcest resource: production time.
If you have 1 hour to accomplish a task in a simple manner then it would be counterproductive to be force to lengthily ponder some definition of simplicity and how to apply it.
It's certainly worthwhile to meditate over Leonardo da Vinci's "Simplicity is the ultimate sophistication" - however I doubt this will lead you in a straightforward manner to a simple solution in your day to day work.
Or how about Bruce Lee's "Simplicity is the key to brilliance"? Does that inform you whether to use recursion or not to achieve simplicity while coding a function? Again, I doubt it.
What to optimize for
But what about B.J. Fogg's "Simplicity is a function of your scarcest resource at that moment"? In my view that's immensely helpful!
Think of the typical TDD situation. You just wrote a red test. Now you're about to code a little to get it to green. You want to do the "absolutely simplest thing in the application code in order to get [the] test to run". But how can you judge which approach to solve the problem posed by the test is the simplest one?
- Ask yourself, what the scarcest resource is. Examples:
- Do you want simplicity to save time during runtime?
- Do you want simplicity to save memory consumption during runtime?
- Do you want simplicity to save coding time now?
- Do you want simplicity to save reading time in the future when someone needs to understand the code?
- Do you want simplicity to save modification time in the future?
- Ask yourself which approach would save most of the identified scarcest resource.
I think the answer now is very easy: The scarcest resource right now during TDD is coding time. You need to get feedback quickly about whether you understand the problem and are capable at all to solve it. The simplest code then is the code you can come up with and type fastest.
But then, as we all know, code is more often read than written/changed. In the long run the scarcest resource therefore is reading or modification time.
As the explanation of simplicity made clear, the simplest code with regard to the coding time resource might not be the simplest code when looking at it from the perspective of another resource. What does that mean for the application of the KISS principle during TDD?
It means, you need to find time to optimize for reading/modification later. Interestingly TDD has this time built in. That's what the refactoring phase is for. During refactoring you apply the KISS principle once more - now creating simplicity for reading/modification time. If thereby the simplicity for coding time is destroyed so be it.
As you can see: There is no such thing as absolute simplicity. You can't create a simple solution once and for all. What is deemed simple depends on the scarce resource, which changes over the course of a day, across the lifecycle of a software, and varies for team members.
This final point is not to be neglected. Simplicity is not just relative with regard to resources but also depends on the beholder's competency.
Even if two developers agree on the resource for which simplicity should be created they might disagree on which solution should be called simplest.
A recurring example for this in the .NET community is the use of lambda expressions. Some developers are very familiar with them and find their application to lead to simple solutions - regarding the coding as well as reading time resource. Other developers are not familiar with lambda expression and thus don't use them at coding time, to keep their code simple. And they don't like to be confronted with them at reading time; it takes them too long to analyze what's going on in the code.
A simple solution for one person can be a complicated solution for another person. Sad, but true. The only way out of this is to keep all team members close together in their competencies (as long as there is a chance one member needs to deal with another's simple solutions).
What does that mean for technologies like Linq, Angular.JS, functional languages, MongoDB, Pubnub etc. etc. which promise to make it easier to code simpler solutions? Well, simplicity has a price. It's that simple ;-)
There are levels of simplicity that can be reached within a given technological horizon. But once you reach the top level you hit a glass ceiling. If you want more simplicity you need to invest into learning a new technology first.
So before you get lost in arguments whether a given solution is simple or not, first check if the discussion suffers from misunderstandings:
- Is there a common understanding as to what the scarcest resource is for which simplicity should be created?
- Are knowledge and capabilities of the participants in the discussion homogenous?
I guess in general you could say, solutions with less detail or more abstraction are simpler than solution with less abstraction or more details. But then... people not familiar with the abstraction may find more detailed solutions simpler.
This is also true for lines of code (LOC). In general solutions with less LOC might be deemed simpler. But then there is always a point where even less LOC make a solution harder to understand.
Sometimes that's matter of taste. But more often it seems to be a matter of experience with some technology or the problem domain.
So we're back at simplicity is relative. But at least you now know what to look out for when trying to apply KISS. Be very clear about the scarcest resource. And once you have made up your mind try to minimize the burden on it.
It's like a friendship kiss for a dear team member; an expression of sympathy, even empathy. Or if you don't like to kiss men ;-) think of a manly man hug.
P.S. Just in case you're still in doubt: In my view the chronically scarcest resource in software development is usage time. That includes the time users actually work with our software. But mainly I mean developers using code because they need to understand and modify it, plus developers using tools and applying processes.
It can hardly overestimated how well invested an hour writing/setting up a solution is if that helps to reduce the time to use it. This pertains to production code as well as screen designs and usability and infrastructure.
Simplicity focused on the scarcest resource is not a matter of beauty, but a matter of economics.
Image source:
* Kissing lips: clipartbest.com