The elements of software style

July 27th, 2012

I love movies. By a rough estimate I’ve already watched thousands of them, and I hope to watch thousands more in my time. Some are forgettable, some stay with me for a long time, and some have prompted me to delve deeper and start a series of interviews on how movies are made. Despite all the technological advances in home entertainment I still find myself going to the theaters every week, sometimes more than once a week. Twenty five years ago I would have to buy a weekly newspaper that had a special section detailing all the movie theaters and shows in my area, or call an automatic service provided by the closest theater to check what is playing, and when it is playing. Times have changed, and nowadays there are plenty of online resources to check the show times, browse the upcoming movies, watch the trailers and in general be much more informed.

The informed part comes at the price of a wide variety of features available from these online resources, both web sites and native mobile applications. A first-time visitor would have to spend a few moments getting acquainted with the overall structure before locating the path to the information that he is after. After a few visits you know where this information is located, and you can either bookmark it (if the surrounding platform supports this) or remember the sequence of scrolls and clicks that get you to that destination. What is my most frequently visited destination? I go to the theater after putting the kids to bed. So I am looking to see what is the first show of the specific movie in that specific time frame (say, between 8:30 and midnight). And if the movie is not playing in the theater next door, where is it playing, and how the driving distance is going to affect the beginning of my target time frame?

Of course, this information is available in the list of all today’s shows in my area – except that I need to mentally filter out all the noise of the movies I don’t intend to see, and all the shows that fall outside my time frame. Or I can explicitly search for the specific movie and deal with less noise – at the expense of an extra step of the search itself. And every once in a while I start daydreaming about writing a small application that would do just what I want. After all, I write software for living.

And so I start imagining a very focused flow where I select a movie, then the location service kicks in and tells the app my location, and then I tell the app what is my preferred time frame, and the app takes all that and shows me the specific show that is the right match for me. Or maybe a couple if it’s a blockbuster that’s just out. And then I start thinking.

What if I’m at work? I don’t necessarily want the app to use my current location. That’s not my scenario after all. So I’ll need some way to persist the home location so the app can search there. But wait. I work remotely, and visit the main office campus every once in a while. Wouldn’t it be nice to change the default search location for such trips? And while I’m at it, my time frame restrictions are different, as the family stays home and I can go to an earlier show. So I’d expect the app to allow me to change these filtering parameters. But then, when I get back home, I don’t want to spend time configuring the location and time frame. So, hey, let’s support profiles.

I went to see “Moonrise Kingdom” a couple of weeks ago. It’s a wonderful movie, and I already went to see it another time. There was a problem though. It’s not a blockbuster, and the distributor (Focus Features) has opted for a longer but slower rollout in the theaters. During the first few weeks the closest show was about an hour drive away, and I didn’t want to see the movie that much. And so I waited until it got relatively close and then I went to see it. How would I incorporate this into my application?

This becomes sort of a wish list – the movie is out, it’s just not close enough. I could define the maximum distance I want to drive to see the specific movie. I’d then mark the movie and let the application notify me when it’s showing within that distance. But distance is not time. 20 miles can be 20 minutes away on a highway, but 40 minutes away if I have to drive at night through suburban streets. So not only I now have a feature that tracks my wish list and cross references it with nearby theaters, I’ll have to integrate it with some sort of traffic service. But why stop there? There are some movies that I really want to see. I’ll gladly drive twice the time to see that hypothetical movie in the theater. So while I’m thinking about this wish list feature, why not throw in wish list profiles? If I really want to see a movie, let me add it to the wish list and specify how much I want to see that movie. There will be some sort of mapping (or manual input) on how much I’m willing to drive to see the movie. But wait a second, that’s not enough. Suppose that movie is out, and it is within the matching driving distance. But I’m busy this week. So I’d definitely want to add a way to “snooze” the specific entry for a week – or maybe only for a few days. So the app becomes a sort of a moviegoing planner.

Speaking about planning. Now that I have this nice planning feature, why restrict it only to the movies that are out in the theaters? Why not show the list of upcoming movies and let me add them to the wish list? Let’s extend that thought and have some sort of recommendation engine. The application will track which movies I’m searching for and which movies I’m adding to my wish list, and will suggest similar movies. Those movies might be playing right now, or they are coming up in the next few months. The recommendation engine is, of course, not an easy thing to tackle. But if I do it right, the application becomes much more than a planner, it becomes an assistant. Recommendation engines are, of course, tricky. Just ask Netflix. That’s nice to have, but way too much work. As a last thought in this direction, one of the most important inputs would be what you thought about the movie after you’ve watched it. So it’s not enough to maintain a wish list, you’d also need to provide a way to collect and store movie ratings. But let the bygones be bygones. No recommendations.

Back to “Moonrise Kingdom”. I really liked the movie. It’s still out in the theaters. I’ve seen it twice, and I want to see it another time. So there’s going to be some kind of functionality to star a movie. It’s no longer on the wish list, but I still want to see it. Or may be the wish list becomes some sort of a hybrid that combines tracking what I want to see, now and in the future. Is it one list with sections, is it multiple lists, is it some sort of “here’s what you can see today”? Let’s take this “I really liked this movie, so now what” and explore it a little bit further.

The movie is out in the theaters. I can go and see it as many times as I want as long as it’s playing. I cannot buy a BluRay yet. But I can buy a soundtrack. I can go online to a variety of retailers and purchase the digital copy there. Then I can listen to the soundtrack as I’m waiting for the BluRay to come out. But that’s two separate sites / apps that I need to go to. Wouldn’t it be nice to have some sort of integration with the purchase and listening experience right inside my app? Integrating with one store might be possible if it provides some sort of web service APIs to purchase and consume the content. Of course, if you want to keep it really seamless, you’d need some kind of a way for the user to provide the signin credentials and transmit them securely to the third-party store, and that opens up a whole new can of worms. Or maybe that third party store is another application on the same device and it provides a way to integrate these flows in you application. So suddenly you’re thinking about what would be needed on both sides to make this seamless. And that’s only for one digital store. Wouldn’t it be nice to be generic and not rely on any specific APIs that a particular store exposes? So now you’re thinking about some sort of a generic integration between your app and any third-party store, along with a nice plugin mechanism to discover such stores at runtime and allow the user to choose where to buy the soundtrack based on, perhaps, the cheapest alternative, or the encoding quality, or the absence of DRM protection. So that’s a lot of work.

What about the BluRay disc? It usually takes about half a year after the movie has left the theaters. Let’s forget the purchase integration with digital stores. How about tracking the BluRay availability and letting me know that it’s out? So that’s another preference bit to expose in the wish list, and some kind of a new way to expose the full list of tracked movies – sorted, most probably, by the availability date. There’s still some integration with web services that provide this information, but if you’re willing to go for notifications only, it sounds a whole lot less work to do.

And so as I lay in bed thinking about all the nice features to have, I realize that it’s 2AM and it’s time to go to sleep.

The Elements of Style” is a fantastic writing style guide by William Strunk and E. B. White. One of the recommendations has struck a particular chord with me from the very first time I read that book:

Vigorous writing is concise. A sentence should contain no unnecessary words, a paragraph no unnecessary sentences, for the same reason that a drawing should have no unnecessary lines and a machine no unnecessary parts. This requires not that the writer make all his sentences short, or that he avoid all detail and treat his subjects only in outline, but that every word tell.

This principle applies to any kind of user-facing software, no matter what is the projected or intended demographic and professional profile of the bespoken user. A minimalist feature set is not a goal in itself. A feature is included not because the competition has it, or because marketing says that it’s a great selling point; it is included because it works towards achieving the main product goal. Marc Hedlund provided an honest analysis in his “Why Wesabe lost to Mint” article:

Everything I’ve mentioned — not being dependent on a single source provider, preserving users’ privacy, helping users actually make positive change in their financial lives — all of those things are great, rational reasons to pursue what we pursued. But none of them matter if the product is harder to use, since most people simply won’t care enough or get enough benefit from long-term features if a shorter-term alternative is available.

Every “what if” and every “wouldn’t it be nice” is a double-edged sword. Don’t compete on features, but instead make your every feature work. Create software that is concise. Create software that is vigorous.