Why 90% solutions may beat 100% solutions

I’ve never written a line of Ruby, but I find Ruby on Rails fascinating. From all reports, the Rails framework lets you develop a website much faster than you could using other tools, provided you can live with its limitations. Rails emphasizes consistency and simplicity, deliberately leaving out support for some contingencies.

I listened to an interview last night with Ruby developer Glenn Vanderburg. Here’s an excerpt that I found insightful.

In the Java world, the APIs and libraries … tend to be extremely thorough in trying to solve the entire problem that they are addressing and [are] somewhat complicated and difficult to use. Rails, in particular, takes exactly the opposite philosophy … Rails tries to solve the 90% of the problem that everybody has and that can be solved with 10% of the code. And it punts on that last 10%. And I think that’s the right decision, because the most complicated, odd, corner cases of these problems tend to be the things that can be solved by the team in a specific and rather simple way for one application. But if you try to solve them in a completely general way that everybody can use, it leads to these really complicated APIs and complicated underpinnings as well.

The point is not to pick on Java. I believe similar remarks apply to Microsoft’s libraries, or the libraries of any organization under pressure to be all things to all people. The Ruby on Rails community is a small, voluntary association that can turn away people who don’t like their way of doing things.

At first it sounds unprofessional to develop a software library does anything less than a thorough solution to the problem it addresses. And in some contexts that is true, though every library has to leave something out. But in other contexts, it makes sense to leave out the edge cases that users can easily handle in their particular context. What is an edge case to a library developer may be bread and butter to a particular set of users. (Of course the library provider should document explicitly just what part of the problem their code does and does not solve.)

Suppose that for some problem you really can write the code that is sufficient for 90% of the user base with 10% of the effort of solving the entire problem. That means a full solution is 10 times more expensive to build than a 90% solution.

Now think about quality. The full solution will have far more bugs. For starters, the extra code required for the full solution will have a higher density of bugs because it deals with trickier problems. Furthermore, it will have far fewer users per line of code — only 10% of the community cares about it in the first place, and of that 10%, they all care about different portions. With fewer users per line of code, this extra code will have more unreported bugs. And when users do report bugs in this code, the bugs will be a lower priority to fix because they impact fewer people.

So in this hypothetical example, the full solution costs an order of magnitude more to develop and has maybe two orders of magnitude more bugs.

8 thoughts on “Why 90% solutions may beat 100% solutions

  1. “At first it sounds unprofessional to develop a software library does anything less than a thorough solution to the problem it addresses”

    The iconic counterexamples include:

    * C
    * Unix
    * the Internet

    They are all incomplete, but they worked well enough that, in their time, adoption was almost universal, because they were so darn powerful in spite of their shortcomings.

  2. Really, the same design philosophy should apply to the design all libraries in any language, except those designed for a particular project. There is no way that my library X is going to do everything that you want to do in your project. The idea is to abstract out the stuff that is useful in more than one project and set an API for that. The advantage to languages like Ruby (and Python, which I prefer) is that you can change the API at runtime to be what you need. When using these dynamic languages, it is useful to have more elaborate libraries which can be easily molded into what you need.

    I think the trap that library designers fall into is feature creep. They try to solve all of the world’s problems in one package. Be more like UNIX tools. Small tools for specific tasks. Glue them together and you have a larger project solution.

  3. This doesnt just apply to coding at all. Its a fair thing to say about any industry or any social problem. Wherever there is an issue or a problem that needs resolution. It makes sense to worry more about the bulk that concern all than to worry about the minutia that concerns only a few. Something about efficiency, work, cost. Im reminded of the 80-20 Rule as a matter of fact.

  4. Some problems can be addressed at an 80% level and some cannot. It’s not enough for my keyboard to have 80% of the keys.

    In Olin Shivers’ example, he’s discovered something where someone else cannot implement the extra 20% he needs because the infrastructure isn’t there. Something foundational is missing. So you could argue the wrong 20% was left out.

    It’s better to think in terms of users rather than features. Instead of saying you’re going to include 80% of your original feature list, which may or may not make anyone happy, you could aim to please 80% of the public. (Or 2% of the public, if that’s a big enough market for you.)

  5. When you release a 90% solution, user feedback will steer you toward the additional 1% that’s worth spending effort on. So your 90% solution at 10% of the effort becomes a 91% solution at maybe 15% of the effort. Not so bad.

Comments are closed.