The Importance of Cliche

Important messages warrant repeating. Repeating often enough makes it a cliche. When it becomes a cliche, people start to ignore it. Repeat the cliche often enough it falls off the radar. Since the important message has fallen off the radar, it is worth repeating. And the circle of life continues.

So, cliche or not, even at the risk of sounding like a broken record, keep repeating important messages be it at work or at home.

Consistency is a key component in communication to get the message across.

Those who really care

There are those who truly care and there are those who think they care or pretend to or we might be under the false impression that they care.

It’s easy to find out who’s who. If we are about to make a mistake or miss out on something, those who truly care will remind us or work with us before it happens. Others will wait for us to miss it so they can prove themselves right (either to themselves or to others) or go on to say “see.. I told ya” or “I knew exactly this is what would happen”.

When the other person sees it coming and we don’t, those who care will make sure we see it coming too, no matter how many times they have to. That’s caring.

What we believe in

There are certain things that we inherently believe in. We happen to “just know” or “just believe”- the gut feeling.

Then there are other things that we were led to believe in. Things that we think are true. This happens as we grow up, the memes passed on to us, the happenings and actions around us leading us to believe that this how things are, leading us to believe or take it for granted that it is the fact while it may or may not be.

It is important to know that such distinction exists and to know the difference between them.

It is important to know what we inherently believe in and what we were led to believe in.

Coffee Script

While many us love coffee for what it is, at times we also use it as a proxy for a few things.

I noticed many of us “hide” behind it – by holding the cup all day. Taller the cup the better. It is not necessarily the coffee that we want all day, but it is some sense of insecurity that makes us hide behind the cup.

It is our pause button. It helps us buy time. Take a quick sip or pretend to, when we need time to dodge a question or need time to come up with a (politically correct) response.

Coffee is also the default drink. Similar to how a plaster (adhesive bandage) is often thought of and referred to as Band-Aid (a trademarked name of the commercial product.), a mid-day drink is often the coffee. Need to drink something (hot), but don’t know what or don’t have much options, so we settle for coffee.

Coffee keeps us busy -not. As we keep sipping coffee, it gives the feeling of busyness. You know, the awesome feeling of doing something without actually doing anything of significance. Like a rocking chair – it keeps moving without actually taking us anywhere. It gives us the feeling of busy and others the impression of us being busy- at least we like to think so.

I’m sure we have all experienced productivity boost after downing some coffee. There is also another way to boost productivity with coffee -by putting it down. Productivity will also increase if we put down the coffee cup and give our undivided attention to the task at hand. Get the work done faster and then take your time to enjoy your coffee in leisure -perfect to drag busy coworkers into a trivial conversation.

Tea lovers, fear not. Much of what’s discussed here applies to tea holders too. I love coffee too much to single it out. 🙂

 

Perfection as a proxy for fear of failure

The fear of failure disguises itself in various forms and strikes us in many unsuspecting ways. Striving for perfection is one of them. It isn’t obvious at first but when we dig deeper and introspect, we can realize the fear of failure being the hidden driving force.

We want to do a great job and we want to push out a great product. That is fine and it has its merits. But after a certain point our strive for perfection becomes a proxy for our fear of failure. Perfection becomes an excuse. It’s easy to get caught up in this. We need to be aware and watch out.

When the deadlines skip for reasons of (lack of) perfection, it’s time to pause and reflect.

Are we losing sight of our goals?

What is driving our quest for perfection and not wanting to mark it done?

What is the benefit of the incremental perfection achieved or often perceived? After a certain point it is very minimal.

What will happen if you push out the product without it being 100% as perfect as you want it to be? We are our biggest critic. Clients/users of our products could be more forgiving.

Like artists, we need to know when to stop painting.

If we roll out a truly perfect product then it will forever be at version 1.0. Rollout a decent product and enhance it over subsequent versions. Perfection is after all something to chase without really achieving it. Prefer progress over perfection.

Keep the fear of failure at bay and strive for progress, not perfection. That’s the key.

Why Best Practices

Many of us agree that best practices are generally good and that it helps produce quality code, easier to maintain code, etc. But what aspect of the best practices gives it this characteristic?

I’d like to answer that with an analogy. Imagine you are driving uphill on a two way traffic street. Single lane on each side, separated by just a painted line with no physical median separating the bi directional traffic. You can’t see the oncoming traffic until after it’s too late to avoid an accident. Yet, we manage to drive without accidents time and again. As long as everyone does what is expected of them- driving on the correct side of the traffic indicated by the painted line- everything is fine and everyone is safe.

In software programming, how do we know what is expected of us to keep things moving smoothly? The best practices fills that gap. It is not just the generally accepted practice, it is also the generally expected practice. When we see a hint of a design pattern in the code, such as a class named after singleton, factory or visitor, or expressing the intent of the code in a test, or naming a variable to indicate its purpose, we know what to expect from that point on. It also increases our confidence and comfort level with that code. Once we are comfortable with the code, we are also more likely to attend to and refactor any ailing code, reducing the technical debt and improving the overall health of the system.

In the fast paced world with aggressive timelines, we could avail the help of anything to save us some time and increase our productivity. Best practices is one of the things that can help us.

Perfection is suboptimal

For all the energy that goes into perfecting something, I have found that the overall result is often suboptimal.

Perfection is hard to achieve. It takes a lot of effort, time and resources. When we set out for perfection, we often tend to allocate resources disproportionately. We often run out of time, energy, resource or all of the above before we could complete everything to perfection. That leaves us with something that might be perfect in certain aspects and other areas needing attention since we couldn’t get to them. That makes the overall result suboptimal.

We could rather focus on delivering the best as a whole as opposed to perfection in isolation.

One my previous managers used to say, “It is better to have a working Volkswagen car than a Bentley I can’t take out of garage.” No offense either of these cars. I’m just quoting him.

I’ve observed that the suboptimality of the result is directly proportional to amount of perfection we are seeking.

I’m not suggesting that we give up on perfection. But rather that (continued) progress matters more than the initial perfection that we are trying to achieve (and fail in many cases).

Prefer progress over perfection.

We should also inspect the definition of perfection. Everyone has their own. One definition to go by, that could help us, is “perfect enough for the job”. This is similar to “good enough”, but better than good- if that makes sense.

Spoiled by Abundance

Most of us are spoiled by abundance – in personal life as well as in programming life. The machines that run our code keeps getting better- faster, larger and cheaper. The things we need seem to be available in abundance.

This gives us a false illusion of unlimited resources. This is why we didn’t bother to conserve or recycle anything before. In programming life, this gives us a mentality of throwing more hardware to solve a problem, any problem, as a first and often preferred choice of solution.

I think this (state of affairs) is sad and it reflects unconscious programming.

The limited resource constraint is still very real. The machine you already have can only take so much RAM and the CPUs can only go so much faster. Of course, you could keep swapping out for better machines, but you might still be constraint by budget.

There are genuine cases where you need to swap out for better hardware. But I doubt if that’s the case for a large majority that opts for this solution as the default choice.

One who is resource conscious and the one who isn’t, both have the same thought process “I won’t do this because I don’t need it (or I don’t need to)”, but applies differently.

The resource conscious and the performance inclined could apply it thus:
I won’t make 2 calls to the database to get this data as I can get the same data in one call if I do X.

The other could apply it thus:
I won’t do X and do it the 2-call way as this had not proven to be an issue.

And there are others who don’t think about any of these. They are blissfully unaware of their mounting technical debt until the day when everything comes to a crashing halt and wonder what happened- well, its time for rewrite.

I’m aware of premature optimization and the issues around it. But this is not that. A simple ‘for’ loop could perform much better depending how we code it. This is a programming model, a paradigm and developer’s mental model (& maturity), rather than an optimization exercise.

Efficient resource utilization and high performance of the system should be given priority over developer’s convenience.

Perhaps one way to bring this awareness could be to have developers work on obvious and explicitly specified resource constrained environment as a side project or as a fun activity or a hackathon. For example: an app for a rural village in a underdeveloped country that would run on a 15 year old machine and they don’t have the means to upgrade. Or working in an embedded environment or even a mobile app, with clearly stated performance goals.

It would take willingness to participate in such programs and perhaps some enticing, some pushing even. But I think that such exercises, even if hypothetical, would still help bring awareness to the masses.

Whose job is it anyway?

In our young software industry, we are eager to compare with more mature industries. One such analogy is that of the assembly line. Each stop does its job and pushes it to the next in line to do theirs. Unfortunately, this idea went main stream with the waterfall software development methodology. Developers’ job is to write code and it is testers’ job to make sure that the code developers wrote works.

QA team exists to ensure minimum quality necessary to ship the product. But that’s not enough. Quality of a product is one of the main competitive advantages. We can’t skimp on it.

When we care about what we produce, it shows and people take notice. When we don’t care enough, that shows too. A well architected solution, a well written code, a well thought out and implemented user experience- all pay off. The payoff may not be obvious in the short term, but it definitely pays off in the long term by way of customer loyalty, retention and word of mouth advertisement (recommendation). When the users are delighted using our product, they come back for more. That’s a win for all.

We typically measure our (developers’) performance with how fast we churn out code, how fast we could check off the backlog. This is further fueled by the aggressive timelines. Quality isn’t part of the equation. When we bring in quality and robustness as KPIs (Key Performance Indicator), things will shift for better.

Quality KPIs help in multiple ways.

  1. It communicates the organization’s emphasis on quality.
  2. It creates a wall/hall of shame effect and we don’t want our names up the leaderboard in red.

These promote a quality conscious culture.

But the onus is on every developer to produce high quality software regardless of what happens at a broader organization level. It is not up to them, it is up to us to produce something that we could proudly put our names on.

“The best code is the one you didn’t have to write.”

Some of us have come to believe that there is no such thing as bug free software. But bug free softwares do exist. You just have to find the bugs before others do, and fix them.

“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.”
– C.A.R. Hoare

Software has become an integrated part of everyday life- from traffic lights, to self-driving cars, to spaceships and everything in between. A simple software bug could be fatal. Producing high quality product and keeping it consistently good is no easy feat. But quality is not about doing what is easy, it is about doing what is right -even when nobody is watching.

Build quality into your everyday work. Move away from a typical developer’s definition of done towards clients expectation of done.1

“The long-term value of software to an organization is in direct proportion to the quality of the codebase.”
– Douglas Crockford

Quality is everybody’s concern. Every line of code you touch can take you towards or away from your quality goals. Be a conscious programmer. Write every software statement intentionally.

An aristocratic lady once asked Sir Henry (of Rolls Royce),

“What would happen if the factory at Derby produced a bad car?”

Sir Henry answered, “Madam. The man on the gate would not let it out of the works”.

More quotes from Sir Henry Royce, as parting thoughts:

“Small things make perfection, but perfection is no small thing.”

“Whatever is rightly done – however humble – is noble”

“The quality will remain long after the price is forgotten”


1 DEFINITION OF DONE

Typical developers’ definition of done:
I just barely got it working with some really clever hacks.
Typical stakeholders definition of done:
The work is complete in every sense- development complete, tested and fine-tuned. The work/product is robust and ready to ship. If this is not the case, then the work is incomplete.


The Sacred To Do List

When we have the to do list as a catch-all list we dilute its importance and effectiveness. It becomes just another list and the tasks remain collecting dust.

Treating the list with reverent has its benefits, giving a bias towards action. Add a task to the list (only) If it is important enough for you to do it. And if the task was important enough to be on the list then make sure you do it. Don’t have second thoughts about it. You can add a note to the task to remind yourself why you wanted to do this task, its nature, importance and the benefits of doing it.

Things do change over time. So when a task that made to the list is no longer important, take it off the list immediately. Don’t let it linger around. If you want to hang on that for keep sake, then create a (hidden) “someday/whatever” list if you want and move the task to that list. But take it out of the main to do list. Keep the list pristine and clean.

Having such a focused list keeps you motivated to get this done. A simple to do list now becomes a powerful action list.