June 2009

Every once in a while, I need to merge something using clearcase’s command-line cleartool. It always takes me a few minutes to remember how exactly to tell Clearcase to do what I want, so I’m writing it down in hopes that I remember to look here next time I need this.

So, I ran “cleartool ci”, and got an error about the version I was trying to check in not having the right parent version. To fix, I ran

cleartool merge -to my_file.txt my_file.txt@@/main/LATEST

After that, my checkin worked just fine.

Whilst we may muse about engineering, architectural or craft metaphors for software development, there is no denying that, in essence, programming is writing. It is a form of communication that has two distinct audiences: us and the machine. Although there are times when it might not feel this way, the machine is easily pleased, demanding little more than well-formed code. We, however, are a little more complex and discerning: we demand that our communication communicate.

As a discipline of composition much of what can be said for writing natural language is directly applicable to code. There is no virtue in long-windedness and, by way of balance, there is also no virtue in code that is unreadably terse. As ever the appeal is for well-written code. Code that is simple and clear, brief and direct.

— Kevlin Henney in “Minimalism: Omit Needless Code

While reading the article quoted above, I was reminded of the first big leap I made professionally. Engaging the part of my brain that deals with composing and editing English prose enabled me to move from being an entry-level developer to a “Senior Software Engineer”.

The circumstance for my “aha” moment was the transition between two very different projects. I had just returned to the home office after being offsite for 14 months. My offsite assignment had been a testing job, during which I had written scripts for doing some test script prep and data analysis, and to maintain my sanity. I came back and started working on a .NET web service that served as an integration point between a legacy Visual C++ app, some legacy C++ code extracted from the app, and a perl/CGI/Oracle web application.

I was working on a team with a couple of Senior Engineers. My first task was to write a component that would handle the compression needs of the application. I wrote a class that abstracted zip files, and let you list a zip file’s contents, extract one or all of the files in the zip, add files to the zip, etc. Essentially, I wrote a subset of #ziplib. It was really sweet, and had 0 (that’s right, zero) unit tests.

Unfortunately, all the application needed was two functions: Zip and Unzip. It needed to add a single file to a zip at one end, and pull it out on the other end. Added to that, my code was generally sloppy. The code review was a bit painful.

During the project, there were many more code reviews. This was the first project that I was on that had code reviews, and I really hadn’t gotten the hang of it at that point.

When we were close to finished, one of the engineers asked me to review a paper he had written that gave guidance about exception handling. I like reviewing and marking up documents — I’m one of those people who thinks that bad grammar and bad spelling detract from the value of written things — so I had no problem printing out a copy and taking a red pen to it.

During the document review, something clicked for me. I realized that during code reviews, I needed to engage the same part of my brain that I used when reviewing prose. Code, like prose, tells a story. There is some reason that you’ve written the thing. You’re starting in one place, and going to another. You’re building arguments that you can fall back on later. You’re using the results of other works to build up something significant, at least in the current context. I was now able to use that part of my self that wanted to be a writer, and my professional growth took off.