Lines of Code is the Best Software Productivity Metric

Lines of code is a great metric for productivity. Not only is it not broken, I would argue that's it's clearly the best. The important question to ask about this metric is "How does programmer productivity relate to value delivered to a customer?"

If you want to measure what programmers produce, lines of code added is the only metric that makes sense. Firstly, it's objective. It's easily obtained from source code repository logs. Many existing tools already can measure and track it. It can be applied to almost any programming language. Finally, because their workflows are (usually) so highly automated, they're able to measure their work product far more accurately than most. And while there are other things that programmers create (emails, documents, meeting invites, coffee stains...) by definition they write code. They are uniquely able to solve problems by writing software, so measuring the production of that software makes sense.

So if we can measure productivity this way, why doesn't it seem to be useful when we do? In manufacturing, higher rates of production almost always leads to more value. I know that all you Lean Production advocates are yelling and screaming about inventory management and muda right now, but if you were producing and selling 1000 things a day and now all the sudden you can produce 2000 of them at the same cost, there's net value there. If you can find a counterexample, please go ahead and produce those extra 1000 things and give them to me. I'll sell them on Amazon.

Software does not work like this at all. If your team was producing 1000 lines of code a day, and now all the sudden they're producing 2000, you really have no idea what impact this has on value delivered. Are you creating twice as many features? Are you refactoring to pay off technical debt? Or are you just thrashing around trying to find a design that fits your domain? Maybe you're adding features, but not ones that users need. Maybe you're just making your system harder to use.

The reason for this productivity paradox is simple: Software is not an asset. It is a liability. From a financial standpoint, creating it is much more akin to leasing office space than it is to producing finished product. It represents an ongoing cost of doing business, that may or not actually result in any value being delivered to a customer. Lines of code in a codebase are liabilities that you have to write, test, document, compile, deploy, etc....and the less of it you have for a given solution, the better.

Programmers solve problems, which can be assets. They often do so by creating software, thereby producing liabilities. In software, production is an expense. Competent programmers are able to create more value than cost when they do this, but not all programmers do. The best programmers can create value by removing code and the best solutions in software can often be achieved through simpler functionality rather than just more of it.

So there's nothing wrong with "lines of code" as a productivity metric. It's fine. You've been using it wrong. To understand the net value created by programmers, you have to look past productivity. You have to look downstream...at how and why and when people are using the solutions you create. You have to create feedback loops that extend all the way to the point where value is actually delivered, and you have to find ways to make those feedback loops fast and responsive. Otherwise, you're going to spend your time optimizing for metrics that don't matter.


Ben Rady is the author of "Continuous Testing with Ruby, Rails, and JavaScript". If you've enjoyed this post and would like to read more, you should follow him on Twitter.

Poor Man's Location-based services with arp-scan and cron

Have you ever wanted to have your computer do something when you came home, or when you left? Here's a cheap and easy way to do it.

The arp-scan utility (available in most decent package managers) can scan your local network for active network clients. Just use the --localnet option. If get a response from your mobile phone (identified by mac address) on your local network, then you're (probably) home! Here's an example:

#!/bin/bash

if arp-scan --retry=3 --localnet | grep 'a4:a4:a6:a7:aa:ad'; then 
  echo "Daddy's home!"
else
  echo "Daddy's gone."
fi

Something like this could be easily run from cron (as root). A more sophisticated version would probably need to track the current state, possibly by touching and deleting a file, as to only act when it changes.

Something else to note: My phone, it seems to ignore too many arp requests in a row. Of course YMMV. Once a minute seems to work though. So the --retry option is in there just in case one of the arp packets gets lost.


Arduino Controlled RC Car

The problem with RC cars and little kids is that RC cars are actually rather hard to control. And really, rather than standing there controlling the car, most kids would rather be chasing it around (at least, most of my kids would).

So I decided to see if I could build an RC car that drove itself, using an Arduino nano rather than a remote control.

Hardware

Here's the parts list (aside from wires, solder, etc...)

The first step was figuring out where the RC chip leads were connected.

The answer turned out to be:

  • R17 -- Backward
  • R18 -- Forward
  • R23 -- Right
  • R24 -- Left

After that, I just needed to wire those leads into the arduino. I started out testing with an Arduino Uno, and once everything was working, I wired it up to the Nano I bought to actually use in the car.

After I confirmed that was working, I put the car back together, drilled a hole in the top for the LED, and hot-glued the PING))) sensor to the front at about a 10 degree angle upwards.

Software

Arduino's libraries are so easy to work with, you almost forget you're writing C++. So I wrote a simple program to control the car. Since there's only one ultrasonic sensor, I needed a simple approach to avoiding obstacles (Summary: turn left).

Final Result

Here's the car driving around my toy-littered basement.

There are still some improvements to be made here. Finding a car that ran on 9 volt power would have greatly simplified the design...although most of those cars are much more expensive than the one that I bought. And I need to add a switch to control the arduino.

Of course, this begs the question, is it still an "RC" car if it's not controlled remotely?


The Simplest Continuous Testing

Here's a simple bash script I use to do things to files whenever they change. It takes a command as an argument and runs that command with the name of a changed file. Many times, it's all I need to do continuous testing.


#!/bin/bash
# Requires that the inotify-tools package be installed.
wait_cmd="inotifywait -m -r --format %w%f -e modify ."
filter=$1
shift
cmd="$@"
$wait_cmd | grep --line-buffered $filter | while read file; do 
  clear
  $cmd $file
  date
done

There's No Such Thing As Software Productivity

Bill Caputo, through repeated conversations we've had, has convinced me of something very surprising. It was something that changed the way I think about the world, and how I do my job.

There is no such thing as software productivity.

As Martin Fowler observed almost a decade ago, productivity in software cannot be usefully measured. The reason why is it just doesn't exist in The Realm of Relevant Things. Put another way, productivity has no applicability as a metric in software. "How much did we create today?" is not a relevant question to ask. Even if it could be measured, productivity in software does not approximate business value in any meaningful way.

This is because software development is not an activity that necessarily produces anything. Here's a thought experiment: Let's say that you have a couple of developers working on the same project, and by accident, both of them pick up the same task on the same day. The first one, Frank, hauls off and writes a 1000 line framework that solves the problem beautifully. The code is well written, well tested, and the deployment and operation of it is well documented. The second developer, Peter, heads off to to the park for the day, where he thinks about the problem while he feeds the pigeons. Around 4:45, Peter wanders back to the office, deletes 100 lines of code, deploys the change...and the problem is fixed.

Which of these two developers was more "productive" today? The answer is: It doesn't matter. What matters the that Peter solved the problem, while simultaneously reducing long term maintenance costs for the team. Frank also solved the problem, but he increased maintenance costs by producing code, and so (all other things being equal) his solution is inferior. To call Peter more "productive" is to torture the metaphor beyond any possible point of utility.

I would argue that what good software developers do is remove problems. The opposite, in fact, of production. The creation of technological artifacts such as code, documentation, data, etc...are all necessary evils to achieve the goal of removing problems. That's why, sometimes, the most effective solution to a problem is a 5 minute conversation.

This post has been truncated. Everything after this paragraph was a rant, and not relevant to the central point. Kind of ironic, right? Thanks for reading!

An Apology of Sorts: Functional Languages Are (Still) Overrated

Two years ago, I stood on my soapbox and yelled. I told the FP community that their languages were bad, and that they should feel bad. It was a post full of vitriol and frustration, but also a little bit of truth. I believed then (and still do) that functional languages are a poor solution if what you're looking for is a way to get B grade programmers to build scalable, concurrent systems. After trying to learn Erlang, Haskell, and then Scala, I couldn't see how using those languages was easier that just using separate processes, stitched together with message passing infrastructure, to build systems at scale. And with these thoughts running through my head, I vomited on the Internet. Then Hacker News picked it up.

Continue reading "An Apology of Sorts: Functional Languages Are (Still) Overrated" »


The Case for Privacy (in Clojure)

A lot of people I've met don't use the private function definition in Clojure -- which is defn- if you've never seen it. They don't see the point, or they think that private functions in Clojure are dynfunctional (pun!). Based on my use of it so far this year, this confuses me, because I think private functions in Clojure are awesome. The reason I think they're awesome is because I write tests for my code, so that I can refactor. Having a clear deliniation between code the that's tested directly and indirectly means I can refactor much more quickly.

When you're looking for ways to refactor code, you can use your fingers, or you can use your eyes. Refactoring with your fingers is nice. When you have a continuous test runner, running a suite of tests on each change, you can refactor pretty quickly. But refactoring with your eyes is much, much faster. Being able to see possible refactorings and think through them in your head is a much faster way to reason about how to clean up code.

If most of your functions are private, you can refactor with your eyes before you refactor with your hands. Unless you've been doing something dumb like subverting access controls to invoke private functions, you know that all of your private functions can be changed, inlined, extracted, and generally recombobulated without fear of breaking a test or messing with another module. This frees up your mind to think about the code that's right in front of you, rather than worrying about the other code that might be calling it.

The public functions, on the other hand, are expensive to change. You will probably break some clients. You probably break tests. All of this will require a lot of work that, essentially, adds no value on it's own. That's not to say that you shouldn't refactor public functions, of course. It's just that the costs are potentially higher. And I find that too many public functions in a module create a slight reluctance to refactor. A pause in thinking, if you will, that I'd rather do without.

So I love private Clojure functions. They're just new a way to implement an old-fashioned idea: Encapsulation. Clearly dividing my clojure modules into public (more expensive to change) and private (less expensive to change) has worked out very well for me. If you haven't tried it, I suggest that you do.

Unless, of course, you're not writing tests...in which case I have nothing for you!


Better Continuous Testing in JavaScript

Things have come a long way since I wrote Continuous Testing in Ruby, Rails, and JavaScript. Lately, for JavaScript, I've been using John Bintz's jasmine-headless-webkit and his complementary guard plugin.

This tool has some really awesome features, not the least of which is that the environment your tests run in is really webkit. That means that you don't have to mock out major parts of the browser environment like window.location, localStorage and sessionStorage, and XMLHttpRequest if you don't want to.

Another great feature is the ability to generate an html file that will run all your tests in a real browser, whenever guard runs tests. Combined with the Live Page plugin for chrome, I get instant feedback about whether or not my Jasmine tests actually pass in the browser.

However, there is one downside compared the node.js technique I outlined in my book. jasmine-headless-webkit doesn't give you real stack traces in the guard output when tests fail. Usually this means you resort to looking at the test failure in the browser (using that generated html file). In practice, it's not a big deal, but it also means you need to make sure your tests pass in both environments, otherwise you might be stuck with a failing test that you can't diagnose.