From Worse Is Better
Given the unfair costs placed on users in worse-is-better, we propose an alternative design methodology that shares much with worse-is-better in a more equitable way. We dub this approach growable-is-better. While growable-is-better is not a new development pattern, and many famous systems have been developed this way, we contend that it should occupy a more prominent role in discussion of software systems.
What is Growable-is-Better?
Growth in Programming Languages
The key idea behind growable-is-better is that the discussion comparing worse-is-better and "the right thing" misses an important detail of software design. Software developed along the "the right thing" model tends to be larger, more complex, and more feature-rich. It tries to anticipate possible use cases and to support all possible interactions between its features. Consequently, it takes a longer time to develop. On the other hand, software developed with worse-is-better tends to be smaller and with fewer features, with the idea of adding the missing functionality later or not at all.
This discussion is reminiscent of Guy Steele's famous talk "Growing a Language" (transcript available here, video here), a keynote address at the 1998 ACM OOPSLA conference. In this talk, he specifically mentioned Gabriel's article on worse-is-better, but seemed dismayed with its conclusions:
The gist of it is that the best way to get a language used by many persons is not to design and build “The Right Thing,” because that will take too long. In a race, a small language with warts will beat a well designed language because users will not wait for the right thing; they will use the language that is quick and cheap, and put up with the warts. Once a small language ﬁlls a niche, it is hard to take its place. [...]
[A] small language can not do the job right and a large language takes too long to get off the ground. Are we doomed to use small languages with many warts because that is the sole kind of design that can make it in the world?
At one time this thought ﬁlled me with gloom. But then I saw a gap in my thinking. I said that users will not wait for “The Right Thing,” but will use what comes ﬁrst and put up with the warts. But users will not put up with the warts for all time. It is not long till they scream and moan and beg for changes. The small language will grow. The warts will be shaved off or patched.
If one person does all the work, then growth will be slow. But if one lets the users help do the work, growth can be quick. If many persons work side by side, and the best work is added with care and good taste, a great deal can be added in a short time. (Steele 226)
In other words, the choice should be between a feature-poor language that can be deployed everywhere or a feature-rich language too complex to see the light of day. The true test of a language is whether it can become expressive enough to allow those who use it to help it grow from a small language with limited features into a large language rich enough to address real-world concerns.
In the context of programming languages, growth can be measured by how easily a programmer can introduce a new library into the language and to what extent user-written code can be used interchangeably with native language constructs. If the language allows users to build libraries that look and feel like the basic operations in a language, those libraries will be more readily adopted and the language can be grown by its users to adapt to new challenges.
Growth in General Software
In the context of programming languages growth may be easy to define, but what does it mean for software projects more generally?
Growability in general software can manifest itself in many forms. Taken to the extreme, it could mean open-sourcing the project, allowing anyone to update the code to better suit their needs. Several major projects, such as the Linux operating system, are designed this way. Under this model, software can be released when it is mostly ready for use, relying on other programmers to put in the effort to improve the software in areas that mostly need work.
Another approach to growth would be treating the final product as a platform upon which other programmers can build. The iPhone, for example, experienced enormous success after allowing developers to design and submit applications; this feature actually became a selling point for the device (see, for example, this commercial). By allowing individual users to determine what they wanted out of the device, rather than attempting to build a complete software suite for the phone, Apple enormously decreased the amount of work they needed to do to release the iPhone while simultaneously making the phone more useful for end users.
In many ways, the macros that ship with Microsoft Office and related products like OpenOffice.org are instances of growable-is-better design. By letting users automate common or repetitive tasks, consumers can synthesize their own features out of the simpler commands provided by the productivity product. Similarly, by allowing system administrators to write and embed Visual Basic code into documents, Microsoft Office can be fine-tuned for domain-specific applications far beyond the scope for which it was initially intended.
Examples of Growable-is-Better
One high-profile example of the growable-is-better school of design is the Mozilla Firefox web browser. As of April 2011, the median estimate of Firefox's market share is 28.2% (Usage share), making it the second-most popular browser worldwide, just behind Microsoft's Internet Explorer. Much of Firefox's success is due to its wide array of "Add-ons," user-written extensions that allow rich customization of the browser's behavior. According to Mozilla, there have been about 2.5 billion add-ons downloaded, and there are currently over 5,000 add-ons to choose from (Add-ons for Firefox). Some of these add-ons - such as Chatzilla (link), an IRC client - radically change the capabilities of the browser. Others, like FlashReszier (link), simply add functionality to the browser that a small number of users would like that is not part of the browser's standard behavior. By opening up their browser for extensibility and growth by users, the overall utility of the browser is much greater. This allows the development team to focus their efforts on improving the core features of the browser without sacrificing usability.
Content Creation in Video Games
On a smaller scale, many video games that allow users to create their own content have survived and maintained a loyal fanbase many years after they were released. An unusual example is the DOS 3D racing game Stunts, released by Distinctive Software in 1990. The game is fairly simple - the player chooses a car and a racetrack, then tries to drive the course as fast as possible. The game shipped with only a handful of racetracks, but allowed users to create their own tracks with a track editor. This editor proved surprisingly popular, and as of 2011 there are still competitions being held in which contestants are given a novel racetrack and must submit a replay demonstrating the fastest possible completion of the course (2011 Unskilled Stunts Championship). Many other games have this property as well. The popular game Warcraft III supported a popular and powerful map editor that allowed users to explore interesting gameplay variations as well as to invent entirely new games that ran inside the Warcraft III game. One popular map, Defense of the Ancients, completely changed the rules and objective of the game to the point where many have treated it as a standalone game in itself (Official DotA Website).
The C++ Programming Language
The C++ programming language was developed by Bjarne Stroustrup of Bell Laboratories as a means of integrating classes into C in a way that combined the benefits of abstraction and high-level programming with the raw speed of C. Although Gabriel cites C++ as an example of worse-is-better design in his original 1991 paper, with our nomenclature C++ would more accurately be designed as an example of the growable-is-better paradigm.
Stroustrup was acutely aware of the challenges of adding new features to C (and, as the language evolved, to C++). In his book The Design and Evolution of C++, which described C++'s design philosophy, he articulated the following about C++:
Once a language is in real use, radical changes are infeasible, and even small changes are difficult without harming users. [...] As the language matures, one must increasingly prefer alternatives based on tools, techniques, and libraries over language changes. (Stroustrup 111)
That is, the best way to address the language's limitations is not by revising the language, but by devising new libraries within that language and creatively harnessing the language's existing features in novel (and often unintended) ways.
Many of C++'s language features, such as templates and operator overloading, have made it possible for new libraries to be built into C++ that mimic the language's built-in functionality. This has paved the way for rich third-party libraries, most notably the Boost libraries, which give C++ programmers access to a much richer set of features than the base language normally allows. Moreover, this allows the C++ ISO standards committee to focus on changing the language in ways that cannot be addressed from within the language, such as the introduction of new control structures or keywords. As a result, the next revision of C++, dubbed C++0x, is significantly larger and more powerful than the current C++, in part because the language designers were able to leverage existing, tested libraries and ideas from Boost rather than having to design these features themselves.
The Layered Internet
The Internet was designed from the beginning with a layered structure and relatively simple interfaces between the layers. This was intended to allow different layers to be substituted in when the requirements for the network change; in particular, to allow the Internet to run on top of many existing networks, as explained in a famous retrospective on the design of the protocols. By specifying a model with pluggable layers, the ARPANET could run on top of many different networks that already existed, and it also became growable: the Internet can run on top of new protocols, such as PPP for modems, Ethernet for wired networks, and WiFi for wireless networks. As mentioned in the retrospective, creating an integrated (and not so growable) protocol was another option, but it was fortunately rejected.
Even more important than allowing the Internet to run on top of diverse physical media, internal layers can be completely replaced without significantly affecting other layers. This model of pluggable layers was most famously articulated in the form of the OSI seven layer model, which was designed as abstraction that allows layers to be replaced without redesigning the entire set of protocols. In hindsight, this flexibility has been crucial (see ).
As a result, TCP/IP has lasted for decades. As the number of nodes on the Internet continues to grow and the IPv4 address space runs out, it is being replaced with IPv6 without affecting TCP on top of it or Ethernet underneath. Even after forty years, the Internet has stayed growable since it was designed from the beginning with flexibility in mind.
GNU Emacs is a text editor widely used by programmers. The first line of its homepage describes the editor as "an extensible, customizable text editor—and more"--in other words, customizability is a key aspect of its design. In order to provide extensive support for a wide variety of use cases, from running gdb on C code to keeping a to-do list, Emacs relies on extensions. The actual core is quite simple--it does not know about specific programming languages or use cases.
To make Emacs useful out of the box, a default installation comes with a selection of "major modes", which provide most of the functionality beyond simply editing text. But a user is not limited to what is built-in. Anyone can write, modify, or download modes written in Emacs Lisp to extend the functionality almost arbitrarily. In addition to major modes, there are other ways to customize Emacs in more minor ways, such as Lisp macros.
Through this flexibility, anyone can customize emacs to their liking. Since most Emacs users are developers, a there is a lot of community support for extensions. There are, for example, wikis and lots of personal home pages with Emacs extensions, like this one.