Harder Than It Looks
Simple is hard. Consider the following:
I guarantee an order of magnitude more work went into the first two of these three interfaces.
Simple is hard. Consider the following:
I guarantee an order of magnitude more work went into the first two of these three interfaces.
Does anyone else have a hard time finishing a project? I suspect it’s a common theme among developers. At the beginning, a project is fresh and new, and it’s fun setting up new tools, cleaning the slate, and getting that first prototype up and running. But as time goes on and the needed features pile up, excitement wanes. Your clean initial bits of code have been cluttered by refactoring and redesign as requirements evolved and unexpected complexities emerged. What was once new is now routine when you’re adding feature 42 of 50, and by the time a task is 90% done, you’re tired of looking at it and desperate for something different.
You’re not alone in this feeling; it’s a well documented phenomenon across a variety of creative disciplines. But fight that tendency, my friends, and push through, because a finished imperfect project is better than a perfect unfinished one.
My theory is that the inability to finish is a combination of the 80/20 rule, unavoidable code rot, and the Creator’s Curse. Naming these issues is the first step to mitigating them, so don’t be afraid to call them out when you see them, both on your team and especially in your own work.
I know personally it was a barrier to getting this blog going again, and it’s a problem I still fight. Am I totally happy with this post? No, not really (writing it while trying to listen in on a teleconference doesn’t help). But I’m clicking publish anyways.
Want to know what happens if you don’t follow the Boy Scout Rule of software development? This.
That being said, it can be really easy to get into a vicious cycle of constant rewriting and never releasing. We’ll talk about that tomorrow.
Yesterday we looked at how theology can inform software development, today we consider physics. The second law of thermodynamics states:
The total entropy of an isolated system can only increase over time.
This statement has a specific technical meaning which is worth investigating on its own merits, but the general principle is that systems tend towards decay. Software systems are no exception to this rule, variously described as software entropy or code rot. Anyone who has worked with software for any length of time knows firsthand how clean code quickly devolves into spaghetti.
How can one combat this seeming inevitability? The key lies in the second law and the little phrase “of an isolated system”. Essentially entropy can be held steady or even reversed in a system if it is properly influenced from outside that system. In the world of software this means that every time a change is made, one should not just do the minimum required to implement the change, because any edit likely increases entropy. Instead the developer must go further to leave the code better than she found it (what Uncle Bob described as the Boy Scout Rule). The best developers work to make this second nature.
Yes this takes more time in the short run. But it’s essential to the long-term health of a software system.
Yesterday I made a broad claim about the applicability of various subjects to the task of software development. Today I want to give a specific example from the realm of theology.
The notion of sin is foundational to a number of world religions. Without belaboring the details or arguing the validity of any one definition, what cannot be disputed is that humans have been wrestling for a long time with their own limitations. Why is it that none of us are able to live up to our own ideals, let alone the ideals of a faith tradition? Why must it be that “nobody’s perfect”? To quote Saint Paul,
I do not understand my own actions. For I do not do what I want, but I do the very thing I hate . . . I have the desire to do what is right, but not the ability to carry it out.
Great stories confront us with the fickle imperfections of human nature as well. Is not human frailty and the conflict that arises from it the very foundation of an epic tale? Nothing proves this truth quite like “fiction”.
What does this have to do with software? Let me repeat myself: software is made by humans, and the results are subject to their constraints. That means you can expect both errors of omission and commission, and both unintentional mistakes (e.g. a developer fails to adequately review code) and deliberate laziness, cheating, pride, etc. One certainly hopes for few instances of the latter, but they do happen. It’s not just time you have to plan for.
A process must be designed to recover from its own imperfect implementation, else it is doomed to fail.
Good software engineers read. And not just technical blogs or books on coding, but on all manner of subjects. Politics, mathematics, philosophy, science, history, and theology have much to contribute to the work of professional software development. But even more important to cultivating a healthy creative mind is the reading of fiction.
Maybe it’s just me, but I feel that a rich diet of fiction has fallen out of favor in our culture, especially in contrast to the consumption of technical information. That’s unfortunate, for stories have a unique power to shape the mind. For me, classic science fiction in particular has inspired me to consider how technology can be of benefit to humanity, and warned me of ways it might be a danger. No O’Reilly book is going to tell you that.
While I’m on the topic, can I say how much it bothers me that we categorize books as “fiction” and “non-fiction”? Those are horrible labels. Novels and other stories can communicate truth in a myriad of ways, and it’s quite possible for non-fiction to be either mistaken or outright false. If you tell me “I only want to read things that are real, not fake” I will absolutely make fun of you. Consider yourself warned.
Show yourself grace, but get back on the horse as soon as possible, right? Fortunately I happen to have some free time this morning. Did the breakfast dishes while listening to some Pink Floyd, which took me right back to high school when I was an obsessive fan (circa “The Division Bell”). It got me reminiscing as well about the various kinds of software development I’ve done over the years. Here’s some significant milestones:
Well, that was fun (for me, at least); I probably could have doubled the length, but I’ve already spent too much time on it. If you’ve read this far, I thank you!
I was busy today doing actual work. It happens. See you Monday!
Yesterday I was speaking with a fellow engineer about the state of our new user interface implementation. We’d crossed a major functionality threshold, but there were still several obvious bugs. I argued that the significance of the functions that were working merited deploying to our integration server for others to see, but he resisted saying that he’d rather wait until a couple of the blatant problems were ironed out.
The above is a common conundrum for developers. Put your work out there for others to see too soon, and they’ll be quick to point out all the flaws. Wait too long, and managers start breathing down your neck because they’re not seeing tangible results.
Personally, I think the wise manager understands the idea of a work in progress, and should appreciate seeing said progress without getting overly critical of early blemishes. It’s a bit like posting photos of a newborn baby. Obviously everyone loves their little nugget, but reality is most newborns aren’t super cute in their first couple of days. But would anyone ever dare point that out to proud parents? Let’s surely hope not! The birth of a child is a momentous event to be celebrated; there’s plenty of time later for the kid to grow into his adorableness.
Likewise a software application. Publish early, and let that baby grow!
Everything takes time.
Plan accordingly (which also takes time).