One step at a time
In the epilogue of “The Mythical Man Month” Frederick Phillips Brooks says that there are only a few people who have the privilege to provide for their families doing what they would gladly be pursuing free, for passion. I am quite lucky to consider myself to be among those people. In a hypothetical situation where I buy a lottery ticket and win the 8-digit prize, I’d most probably find myself not necessarily continuing programming each day, every day. Having said that, it’s quite nice to be employed doing what you love to do. But, as with all things in life, you can’t expect a steady level of “enjoyment”.
Years and years ago (I’m talking last century) when I was studying computer science at a university, one of the mandatory courses included a homework exercise doing a stopwatch in assembly. You had to write a program that gets user input in mm:ss format, and when the user hits Enter, starts counting down to zero. I think there was also the part where you had to track keyboard input and stop the timer, but my memory fails me at the precise details.
I hated that exercise. I absolutely abhorred the very notion of dropping so low to the metal. You know, pixels are my people. So I waited. And waited. And waited. Until the very last evening before the morning when the homework was due. And then I schlepped to the computer lab, plopped into the chair and considered the bleak night in front of me.
As a parent I tell my kids to not postpone the exercises and chores they don’t like until the very end. I tell them that if they start with things they enjoy, they end up with a clump of boring, tedious and dull things at the very end. Of course back then I didn’t want to be quite as reasonable. So as I forced myself to start with something, anything, anything at all, I picked up the less mind-numbing parts of the exercise.
I started with processing the user input. Something like look at the character that was just typed and beep if it’s not a digit. Then proceed to mirror the character on the screen and advance the cursor. Then, at least after one digit, also accept the colon. Then tweak the input validation to only accept digits from 0 to 5 in the next slot. Then tweak the input validation to only accept Enter after exactly two digits after the colon have been provided.
And then I stalled for a bit more time, tweaking the input processing routine to accept additional Enter strokes to treat them as decrementing one second from the timer. Which brought me to writing another routine that would update the currently displayed value, handling the transition from :00 to :59 state.
I distinctly remember the depression I felt at the very thought of tracking and syncing with the system time facilities. I tried to postpone it as much as I could. It was the farthest away from the pixels, and I left it until the very end. And then a wonderful thing happened.
As I kept peeling off those onion layers, I kept on getting a continuous stream of visual progress confirmation. My routine for accepting the initial timer value was working. My routine for rejecting invalid inputs was working. My routine for decrementing the current timer value was working. And as I kept peeling off those onion layers, and as I got the the very last piece, I found out that it was actually quite manageable. There was only this last thing to cross off the list. I did it and I didn’t even notice how smoothly it all went.
Fast forward to early March 2015 and the code base I’m working on. It’s been around for a while. I’ve been on it for a while, almost five and a half years. It’s seen some major redesigns. In fact, I can’t think of a single module or class in it that hasn’t been gradually (and completely) rewritten at least once. And it has a lot of baggage.
I’ve briefly mentioned this the last time Chet and Tor hosted me on their podcast. As we started down the path of bringing our app into the Material world, we had two choices. We could graft the various aspects of Material (keyline grid, in-screen animations, cross-screen transitions) on top of the code base that was, frankly, simply not built to be that flexible. Or we could rebuild the foundation (ahem, yet again) with an eye towards that flexibility and then bring those elements in.
Rebuilding the foundation is at most times a long, dull and unexciting process. You know that at some point in the hazy future when it’s all done, it will enable all these wonderful things (and you hope that by the time you get to that hazy future, the design hasn’t changed in any major way). But for now, and perhaps for a while, the things you’re doing are not resulting in any kind of user-facing improvements. If anything, the deeper you dig, the worse it gets for the overall instability of your code base (aka Things You Should Never Do – except when you really have to). And so you dig, and you dig, and you dig. And you get closer to that hazy future. One step at a time.
And then at some point you look at what you’ve built, and you see that it’s ready. And you make a 150-line code change and suddenly you have the hero image extending all the way into the status bar on the details page. And the next day you make a 40-line code change that builds on top of that and you have the same functionality on the profile page – because they share the same skeleton structure that you and that other guy on your team has just spent the last four months rebuilding from scratch. Oh, and there were these ten people scattered all across these other teams that built the components that enabled to rebuild that skeleton structure in only four months. But I digress.
And then the next day you have a 50-line code change that brings the same functionality to a more complex context that looks exactly like those other two you already did, but instead of a simple RecyclerView it’s a RecyclerView in a ViewPager that has a single tab which hides the tab strip where you don’t even know if you’ll need to display the hero image until after the second data loading phase that happens when you’ve already configured the initial contents of that ViewPager. But you didn’t start straight away from this complex case. You started from a simpler case, hammering out the details of how to even get into the status bar. And when you got to the ViewPager context, you were able to concentrate on only that one remaining case.
And so you go. Across the landscape of your code base. Sometimes it just flows and you don’t even notice how yet another week flew by. And sometimes you look at this craggy cliff and you just want to turn and run away. But instead, you work at it. One step at a time. And before you know it, the cliff is behind you. And then you take the next step. Because the next cliff is waiting.