Types of software

There are 3 broad categories of software:

  1. Software that entertains – think games
  2. Software that solves a problem – think Word/Excel
  3. Software that impacts humanity

The last category is especially interesting. But what do I mean?

Let me explain.

Consider Facebook. Which category does it fall under?

Category 1? Is it used mostly for entertainment? That’s probably true for how a large set of people use it. But Facebook played a significant role in the revolution in Egypt and in Tunisia and Yemen. Facebook and Twitter were used by people in these countries to coordinate protests and bring about change. That’s real impact.

Here’s another example: Facebook is being used by an anonymous group of volunteers to clean streets in India. They call themselves “The Ugly Indian”. They post before-after pictures after accomplishing a project and share it on Facebook and that encourages others to get involved too. That’s real impact.

We should be working on software that has the potential to transcend into the domain of software that impacts humanity. There’s money in making software that entertains, and there’s money in solving problems with software. But real impact, that is, the kind of impact that changes the direction in which humanity is going happens when the software helps large sets of people achieve what they aspire to achieve, work with each other, and have a realistic shot at their dreams.

That’s the kind of software we should dream of building.


Managing dependencies, when “present” sucks but “future” isn’t ready yet

Here I talk about a pattern in software engineering that I have seen occur in many projects, and suggest a methodology for handling it.


  • Dependency on an external component or service exists.
  • Current version of the external component is being phased out / not being maintained / aging.
  • Next version of the external component or its replacement isn’t ready yet.


  • Should we take a dependency on the aging component that is available, or wait for its replacement to become available? We see some potential throw-away work in using the aging component and want to avoid it as much as possible. Starting to use the replacement of the external component right away even though it isn’t ready yet exposes us to instability related issues that we would like to avoid.


  • Capture our view of the external component: Identify the data-model and contract that captures our requirements from the external component. Capture it in code using one or more interfaces. Introduce a concrete class that acts as a broker talking to the external component.
  • Contain the eventual code-churn: Use a dependency-injection framework to allow a different implementation of the interface(s) implemented by the external component’s broker to be plugged in without having to change code all over the place.
  • Capture our expectations of the external component: Have a rich suite of tests that capture our expectations from the implementation of the interface(s). This will help identify and contain the breakage after we actually move to the new component.
  • Data to support the go/no-go decision: Use logging to capture data that would later help support the argument for moving to the new system when it is ready. What are the reasons we want to move to the new system? Capture relevant data that would help support the decision.
  • Avoid surprises from the replacement: Track the progress of the team building the new component that’s meant to replace the new component. Are they on track? Delayed?
  • Avoid surprises for your customers/stake-holders: Have a timeline identified up-front, based on the road-map of the external component, that identifies when we would take a hard look at moving to the replacement and make a go/no-go decision. If no-go, then the timeline should call out when would we look at the replacement again.
  • C&C: Capture and communicate your plan so others know that you have a plan.