Filed under Software

Software Tailors

I came upon an article a few days ago relating software developers to tailors. The author (Patrick Rhone) wishes to have software tailors: people who will customize (or custom-make) software for you, for a price. It’s an interesting idea and not without its practical merits. In particular, given how most software today is “mass-produced” and customization options are in general, limited at best, a cottage industry of software-tailors might not be a bad idea. But for all its merits I think the idea is somewhat short-sighted. Software is sufficiently different from physical goods (including clothes) that applying the same concepts and processes to software and clothes is fundamentally flawed.

Operationally, software is much easier to change than physical matter. There’s no physical matter to change and if you make a mistake you can revert and go back to what you had. Undo is your friend. That means that even new programmers can create things of values, make mistakes and learn quickly by doing. However, conceptually, making software is as hard, if not harder than manipulating physical objects. I’m not a tailor, but I would wager that hacking on a complex piece of software requires as much skill as making alteration to a jacket. In fact, understanding million-line codebases might well be harder than tailoring a suit to custom dimensions.

The second flaw in the software tailor argument is that our software needs are far more varied than our clothing needs. Humans all have the same general body plans, you only need a handful of numbers to make a shirt fit. But our software requirements are far more varied. The text editing requirements for a novelist are different than that of a blogger which in turn are different from that of a programmer. To really understand what each person needs the programmer needs to have a pretty thorough understanding of what the problem domain is. This in turn means that the programmer either needs to be using that specalized software on a regular basis or the customer needs to able to communicate very clearly what they want. As anyone who’s written software for clients knows, getting proper requirements is often the hardest part of the project. This is why the best software is often “dogfooded” – the developers have been using what they’ve been developing. Furthermore making changes to any part of a codebase often requires understanding more than just the component you’re changing. What might be “just a few changes” to Mr. Rhone would probably end up be hours of diving into foreign source code (or at least learning an API). Writing good software is hard, writing good custom software is harder still. I don’t want to dismiss the idea of software tailors out of hand, but I want to make it clear that the job would not be like the analogy that Mr. Rhone provides.

If we can’t have neighbourhood software tailors, then what can we have? Customized software is good, because as I’ve said, people have very varied software needs that standardized software often falls short of accomodating. What I think we need is twofold: a technological shift where developers write extensible software by default and a cultural shift by which users are no longer afraid to modify their own software. Programmers (especially open source developers) are used to modifying and extending their own tools, I want to see common software users modifying their word processors and email filters.

But, but, but, does this mean we should make our own clothes and do the servicing on our cars ourselves? No, of course not. Like I said, the tailor (and the mechanic) analogy is not the right one. A better analogy is cooking. You can eat your meals at restaurants and fast food places (use standard consumer software) or you can cook your own. If you can spend an hour or two a day putting together ingredients in exact proportions and heating them at specific temperatures for specific times, you can spend half an hour a day typing some some code to make your software work the way you want it to.

Now this cultural shift is only possible if the software supports it and right now most of our software doesn’t. But that can change. Text editors like Emacs and shells like Bash and Zsh are meant to be customized and its not hard to do so once someone shows you how. Browsers are also customizable, though not quite as easily. Luckily software is malleable and with more and more people being software literate I think this is a feasible change in the not-too-distant future. Mr. Rhone wants a shift to developers making it easier for software to be extended, but those some changes could just as easily make it easier for users to adapt their software.

So with all due respect to Mr. Rhone, I don’t want a culture of software tailors. That’s not any different from the programmer-priesthood we have today. Unlike our clothes, our computers are incredibly powerful machines and we’re increasingly dependent on them in both general and very specific ways. I want a culture of citizen hackers: a generation of people who can mix and match their software just as we can develop our own dressing or cooking styles.

As programmers, our job isn’t to write code or be better craftsmen. It’s to solve problems, everything else is tangential. I believe the best way to do that is by empowering users to better solve their own problems. We fight for the users so that they can fight for themselves.

Looking ahead

It is now just about a third of the way through the first month of the year. I’m not really one for resolutions so I didn’t make any. In fact, I didn’t do anything by way of preparing for the start of a new year. However there is one thing that I’ve been wanting to do for years that I hope to finally get around to doing: concentrate more on my writing, in particular, paying more attention to this blog.

I’ve never really wanted to be a full-time blogger, not even a technology blogger. I’ve always preferred to be someone who wrote code (or at least studied writing code) and wrote about those experiences on the side. By and large, that’s been true. However the thing is that I really like writing. It’s a good break from coding and thinking about computer science research and I enjoy communicating directly with people instead of machines for a change (which is why I refuse to pander to search engines and write SEO-directed stuff). Anyways, despite my not being a very regular writer this blog has been moving along nicely. I get around 400 hits on an average weekday and that number has been going up steadily. I’ve been on Hacker News more than once and that’s always generated a good burst of traffic.

I’ve also been discovering technologists and scientist writing interesting and very useful blogs. These are people like danah boyd (Senior Researcher at Microsoft), Matt Might (CS Professor at the University of Utah) and Andrea Kuszewski (a researcher at the George Greenstein Institute). I admire their blogs and their writing but I also admire them for being dedicated scientists and researchers. These blogs reaffirm my belief that writing on a regular basis is important (and healthy) for everyone especially if you’re involved in research and development of new technologies.

All that is a way of saying that I would like to blog more. Looking over my archives for last year I’ve only made about one post a week. Ideally I would like to increase that to two or three a week, not including the Sunday Selection link posts (I doubt I could keep up quality for anything more than that). I also want to start tackling more technical subjects. I’ve been talking a lot about the intersection of technology and productivity for a while now, but I’m starting to get a tired of the productivity aspect. Long story short, I’ve found the small set of everyday tools and environments that I need to get work done. For the foreseeable future it’s more a question of being able to stick to habits and schedules than of using the right tools. When I do speak of tools I want to give concrete examples (like my post on showing Git information in your Bash prompt) rather than handwavey suggestions.

On a related note I’ve been considering moving off WordPress.com. WordPress is great if you’re using their web-based interface but is harder to use if you live in Emacs. I’m starting to itch for a writing system that integrates well with Emacs. I’d like to be able to include my own HTML, CSS and JavaScript in my posts and be able to customize things a bit more than WordPress.com allows. I haven’t given much thought to this matter, but I’m looking at alternate systems such as Jekyll and Octopress. Whatever I decide to do I’ll probably test it out at my personal website before doing anything over here.

While this blog is definitely my most serious writing project, it’s not the only one. I took a few creative writing classes in college and enjoyed them immensely. I would like to be able to continue writing fiction (and maybe even get in shape for NaNoWriMo 2012). But for I’ll be content with just regular blogging output. Glad to have you all along for the ride.

Show Git information in your prompt

I’ve been a sworn fan of version control for a good few years now. After a brief flirtation with Subversion I am currently in a long term and very committed relationship with the Git version control system. I use Git to store all my code and writing and to keep everything in sync between my machines. Almost everything I do goes into a repository.

When I’m working I spend most of my time in three applications: a text editor (generally Emacs), a terminal (either iTerm2 or Gnome Terminal) and a browser (Firefox or Safari). When in Emacs I use the excellent Magit mode to keep track of the status of my current project repository. However my interaction with git is generally split between Emacs and the terminal. There’s no real pattern, just what’s easiest and open at the moment. Unfortunately when I’m in the terminal there’s no visible cue as to what the status of the repo is. I have to be careful to run git status regularly to see what’s going. I need to manually make sure that I’ve committed everything and pushed to the remote server. Though this isn’t usually a problem, every now and then I’ll forget to commit and push something on one of my machines, go to another and then realized I’ve left behind all my work. It’s annoying and kills productivity.

Over the last few days I decided to sit down and give my terminal a regular indicator of the state of the current repository. So without further ado, here’s how I altered my Bash prompt to show relevant Git information.

Extracting Git information

There are generally three things I’m concerned about when it comes the Git repo I’m currently working on:

  1. What is the current branch I’m on?
  2. Are there any changes that haven’t been committed?
  3. Are there local commits that haven’t been pushed upstream?

Git provides a number of tools that gives you a lot of very detailed information about the state of the repo. Those tools are just a few commands away and I don’t want to be seeing everything there is to be seen at every step. I just want the minimum information to answer the above question.

Since the bash prompt is always visible (and updated after each command) I can put a small amount of text in the prompt to give me the information I want. In particular my prompt should show:

  1. The name of the current branch
  2. A “dirty” indicator if there are files that have been changed but not committed
  3. The number of local commits that haven’t been pushed

What is the current branch?

The symbolic-ref command shows the branch that the given reference points to. Since HEAD is the symbolic reference for the current state of the working tree, we can use git symbolic-ref HEAD to get the full branch. If we were on the master branch we would get back something like refs/heads/master. We use a little Awk magic to get rid of everything but the part after the last /. Wrapping this into a litte function we get:


function git-branch-name
{
    echo $(git symbolic-ref HEAD 2>/dev/null | awk -F/ {'print $NF'})
}

Has everything been committed?

Next we want to know if the branch is dirty, i.e. if there are uncommitted changes. The git status command gives us a detailed listing of the state of the repo. For our purposes is the very last line of the output. If there are no outstanding changes it says “nothing to commit (working directory clean)”. We can isolate the last line using the Unix tail utility and if it doesn’t match the above message we print a small asterisk (*). This is just enough to tell us that there is something we need to know about the repo and should run the full git status command.

Again, wrapping this all up into a little function we have:

function git-dirty {
    st=$(git status 2>/dev/null | tail -n 1)
    if [[ $st != "nothing to commit (working directory clean)" ]]
    then
        echo "*"
    fi
}

Have all commits been pushed?

Finally we want to know if all commits to the respective remote branch. We can use the git branch -v command to get a verbose listing of all the local branches. Since we already know the name of the branch we’re on, we use grep to isolate the line that tells us about our branch of interest. If we have local commits that haven’t been pushed the status line will say something like “[ahead X]“, where X is the number of commits not pushed. We want to get that number.

Since what we’re looking for is a very well-defined pattern I decided to use BASH’s built-in regular expressions. I provide a pattern that matches =”[ahead X]” where X is a number. The matching number is stored in the BASH_REMATCH array. I can then print the number or nothing if no such match is present in the status line. The function we get is this:

function git-unpushed {
    brinfo=$(git branch -v | grep git-branch-name)
    if [[ $brinfo =~ ("[ahead "([[:digit:]]*)]) ]]
    then
        echo "(${BASH_REMATCH[2]})"
    fi
}

The =~ is the BASH regex match operator and the pattern used follows it.

Assembling the prompt

All that’s left is to tie together the functions and have them show up in the BASH prompt. I used a little function to check if the current directory is actually part of a repo. If the =git status= command only returns an error and nothing else then I’m not in a git repo and the functions I made would only give nonsense results. This functions checks the =git status= and then calls the other functions or does nothing.

function gitify {
    status=$(git status 2>/dev/null | tail -n 1)
    if [[ $status == "" ]]
    then
        echo ""
    else
        echo $(git-branch-name)$(git-dirty)$(git-unpushed)
    fi
}

Finally we could put together prompt. BASH allows for some common system information to be displayed in the prompt. I like to see the current hostname (to know which machine I’m on if I’m working over SSH) and the path to the directory I’m in. That’s what the \h and the \w are for. The Git information comes after that (if there is any) followed by a >. I also like to make use of BASH’s color support.

function make-prompt
{
    local RED="\[033[0;31m\]"
    local GREEN="\[033[0;32m\]"
    local LIGHT_GRAY="\[033[0;37m\]"
    local CYAN="\[033[0;36m\]"

    PS1="${CYAN}\h\
${GREEN} \w\
${RED} \$(gitify)\
${GREEN} >\
${LIGHT_GRAY} "

}

Conclusion

I like this prompt because it gives me just enough information at a glance. I know where I am, if any changes have been made and how much I’ve diverged from the remote copy of my work. When I’m not in a Git repo the git information is gone. It’s clean simple and informative.

I’ve borrowed heavily from both Jon Maddox and Zach Holman for some of the functionality. I didn’t come across anyone showing the commit count, but I wouldn’t be surprised if lots of other people have it too. There are probably other ways to get the same effect, this is just what I’ve found and settled on. The whole setup is available as a gist so feel free to use or fork it.

Tagged , ,

Where is the computation?

I’m pretty happy with my Nexus S so far. It’s a decent phone with some solid apps and services. More importantly, it’s a well-equipped little pocket computer. However the more I use smartphones (and similar devices like the iPod Touch) the more I feel a nagging sense that I’m not really these devices well, at least not to their full potential.

While the devices in our pockets might be increasingly powerful general purpose computers I feel like we use them more for communication than for computation. That’s not to say that communication does not require computation (it does, lots of it), but we’re not using our devices with the goal of solving problems via computation.

This is perhaps a very programmer-centric viewpoint of mobile technology, but one that is important to consider. Even someone like me, who writes code on a regular basis to solve a variety of both personal and research problems, does very little computation on mobile devices. In fact, the most I’ve been using my Nexus for is email, RSS reading, Twitter, Facebook and Foursquare. While all those services definitely have good uses, they are all cases where most of the computation happens far away on massive third-party datacenters. The devices themselves act as terminals (or portals if you prefer a more modern-sounding term) onto the worlds these services offer.

Just to be clear, I’m not saying that I want to write programs on these devices. Though that would certainly be neat, I can’t see myself giving up a more traditional computing environment for the purposes of programming anytime soon. However, I do want my device to do more than help me keep in touch with my friends (again, that’s a worthy goal but just the beginning). So the question is, what kind of computation do we want our mobile devices to do?

Truth be told, I’m not entirely sure. One way to go is to have our phones become capable personal assistants. For example, I would like to be able to launch an app when I walk into a meeting (or better yet, have it launch itself based on my calendar and geolocation). The app would listen in on the conversation, apply natural language processing and generate a list of todos, reminders and calendar items automatically based on what was said in the meeting. Of course there are various issues (privacy, technology, politics, corporations playing nicely with each other) but I think it’s a logical step forward.

As payment systems in phones become more popular, I’d like my phone to become my banker too (and I’m not just talking about budgeting and paying bills on time). For example if I walk into a coffee shop my phone should check if I’m on budget as far as coffee shops go and check coffee shops around the area to suggest a cheaper (or better, for some definition of better) alternative. And it doesn’t just have to be limited to coffee shops.

Mobile technology is sufficiently new that most of us don’t have a very clear idea of what to do with it (or a vision of what it should do). Most so-called “future vision” videos focus more on interfaces than actual capabilities. However this technology is evolving fast enough that I think we’re going to see the situation improving quickly. With geolocation-based services, NFC and voice commands becoming more ubiquitous and useful the stage is becoming set for us to make more impactful uses of the processors in our pockets. As a programmer I would love to be able to hook up my phone to any cloud services or private servers I’m using and be able to interact with them. The mobile future promises to be interesting and I’m definitely looking forward to it.

Tagged ,

A New Year, A New Phone

This year I’ve decided to make a foray into the future by finally getting myself a proper smartphone. I’ve had an iPod Touch for a while but also had a simple Nokia not-smart phone to make actual phone calls. It’s always been somewhat annoying to have to manage two devices: a real phone for calls or texts and the iPod for any Internet and data-related work. A large part of my resistance to getting an actual smartphone was that I simply didn’t want to spend a lot of money on a cell phone plan when I was surrounded by wi-fi all the time and barely made actual phone calls. But now that there are finally both reasonably cheap unlocked smartphones and contract-free data plans I decided to bite the bullet.

The unlocked iPhone 4S would end up costing me a tad over $800 after tax and Applecare. I was also getting bored of the iOS ecosystem and its closed, silo system for apps. So instead I got myself a much cheaper unlocked Android phone – the Google/Samsung Nexus S. I’m pairing that with a $30 a month T-Mobile data and phone plan. I’m still waiting for a new SIM card to show up but till then I’m making use of the ample wifi coverage that’s a side-effect of living in a college town. For now, I’m only going to talk about my first impressions on the Nexus S itself.

Google Nexus S

Google Nexus S (via Wikipedia)

The Nexus S is Google’s previous flagship phone. Its current flagship is the Galaxy Nexus which Google is also selling unlocked. However it’s almost twice the price I paid for the Nexus S and in my opinion, isn’t sufficient of an upgrade to justify the price. Even though it’s about a year old by now (and technically running the old version of Android), I haven’t had a problem with it so far.

It looks pretty different from the iPhone and the plastic feel takes some getting used it. I also think it slips more easily, but that might just be a personal problem. The back of the phone has something of a ridge at the bottom which I guess is supposed to make it easier to hold. Though the build quality does feel inferior as compared to the iPhone, I like it and have no major complaints.

The Android sofware feels like a breath of fresh air as compared to the iPhone. It is considerably more customizable and I like the presence of both tradiiontal apps as well as “widgets” that add functionality directly to your home screens. I’ve found widgets great for quickly looking up data like the weather, Twitter mentions or what system services are currently running.

The tinkerer in me loves how customizable the Android system is. Changing the look and feel is just the beginning. There are a lot of bells and whistles and options and sometimes it can be a rather confusing. For now I’ve only stuck to the usual set of apps (Twitter, Foursquare, Camera) but I’m looking forward to trying out new and interesting apps in the future. More than that I feel like Android would be a really good platform if I decide to get into mobile dev anytime soon.

There are a few things about the Nexus S that I’m concerned with. I think the battery life is a tad too short, especially with the geolocation services on all the time. Luckily, the battery monitor widget makes it simple to turn off services with a touch so maybe some manual management might make it better. While the Google apps are really well integrated (especially Google Voice) and apps from large companies are well done, third-party apps seem to be of considerably less quality than iOS equivalents. I don’t really blame the developers given the multitude of devices but it does mean that finding good apps for simple things like RSS is more difficult than it should be.

Despite the glitches and minor annoyances I really like the Nexus S. The hardware is pretty solid and I like Android so far. Right now having a fully functional smartphone is still pretty new to me, but I’m hoping that when the novelty wears off I’ll dive into actually programming the powerful computer in my pocket.

Tagged , , ,
Follow

Get every new post delivered to your Inbox.

Join 338 other followers