If something is not simple, it is nearly impossible to build.
I don’t mean simple in terms of visual design. Websites with lots of color and large illustrations are beautiful (Vimeo and Viget come to mind). Simple, minimal websites (Daring Fireball, A List Apart, etc.) can be equally stunning too. When I say simple, I’m referring to the design[1] of the application as a whole. If it’s simple, it should serve one purpose and one purpose only. Unless you start with such simplicity, it will inevitably lead nowhere.
Twitter is my (and everyone’s) favorite example.[2] What did Twitter look like initially? Say you are building it, how would you implement it? You’d throw in a textbox on the webpage and on the backend, you’d hook it up to a database with just three fields – username, tweet_content and time (plus an authentication system which would take 2 seconds to configure with any popular web framework). That’s it. No support for even replies.
The reply syntax came about thanks to the community (just individuals making use of @username to respond to someone else’s tweet) and after that, Twitter tweaked Twitter slightly to add support for reply IDs so you can see which tweet the person was replying to. Retweets and hashtags are other powerful community-initiated practices. Dave Winer complains about the lack of “native” support for retweets in Twitter. They shouldn’t listen to him. Not “supporting” (non-prevention can be construed as support perhaps?) retweet is a good thing. If retweets actually became a feature similar to “Like” on Facebook and Friendfeed, it would change the way people used Twitter. Forcing changes in already-good user behavior is generally not a good idea.[3]
The development approach that Twitter brought to prominence is simply amazing. What they did was to start with extreme simplicity, then use their own product and evolve it further based on the usage. In modern times, that’s the mantra for writing anything successful. Start simple, use a lot, evolve.
Complexity
Now, you say “Yeah man, I agree with you completely but how do complex systems exist then?”. To answer that, I refer you to Gall’s Law:
“A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.”
It’s impossible to start working on a complex system no matter how well you understand it (or more likely, think you understand it). Evolution is the only way. And another characteristic of all evolution (biological evolution in particular) is this:
At every stage of your process, the end result must be useful.
This is a very good rule for anyone writing software. What you need is the patience to evolve simple systems. Success takes time. To just stop and stare at something in an attempt to figure out the whole thing is not a good idea. A better approach would be to just start working and you understand more from that approach. Paul Graham agrees. It’s easiest to get new ideas when working on something.
Personal Failures
All my personal failures have been attempting large things without quite realizing how much work they would actually require[4].
Devo was very inspired by quicksilver. Having just bought a Mac (and loved quicksilver), I desperately wanted something like quicksilver in the browser. This meant that Devo had to be more like a catalog of everything in the browser. In fact, it was initially named Catalog (yeah, I suck at picking names). So, it had to import your browser history and bookmarks which was such a pain before Places came along. I also wanted it to know the extensions installed on the user’s Firefox, etc., etc. It was going to be one huge catalog. Obviously, it failed. It was too complex.
Cliche?
Yes, most of this has been said by 37 Signals, John Gruber and a thousand others. And to some extent, everyone realizes how true the “Simple” maxim is but being humans (and even worse, programmers), they greatly misunderestimate how simple simple should be. As Hofstadter puts it eloquently,
“It always takes longer than you expect, even when you take into account Hofstadter’s Law.”
What you need is help — someone on the outside to peer into your brain and tell you if it’s too complicated. Because complicated things can’t built. Instead, start simple, use a lot, evolve.
[2] To get a glimpse of how Twitter has evolved closely with its usage, watch Evan Williams explain Twitter briefly in this TED talk.
[3] So what should Twitter do now? Could Twitter do retweets better? Yes. Do they need to? No. On the other hand, they could work on search. Effectively, CNN and other big news networks now rely on Twitter to get breaking news (just imagine saying this last sentence 1 year ago!). That’s something they might want to improve. But seriously, I have no idea what the Twitter guys have been doing for the last 2 years besides scaling. Even their search feature was bought.
[4] Moreover, usually, as the number of hours required goes up linearly, quality of the overall application decreases somewhat exponentially.


15 Comments
May 10, 2009 at 12:38 pm
Hmm…could this be used as an argument against creationism?
May 12, 2009 at 4:41 am
Yes. The fact that complex systems cannot be created out of thin air has been one of the most prominent arguments against creationism. But in software development, the view that complicated things can be built is still very widespread.
May 12, 2009 at 7:41 am
yes.
a typical creationist argument goes something like “the eye is so intricate and complex and coordinated that it could not have evolved”.
the response is that it evolved from simpler and simpler versions all the way back to when it was borderline useless.
accidental improvement + natural selection => reinforcement. rinse, lather, repeat.
May 12, 2009 at 4:36 am
This is in congruence with python zen (http://www.python.org/dev/peps/pep-0020/)
and what Larry wall had written long back.
Three virtues of programmer (explained in detail here : http://c2.com/cgi/wiki?LazinessImpatienceHubris)
May 12, 2009 at 4:39 am
“A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system. ”
This isn’t always true.
Basically you can do two kinds of products: evolutionary and revolutionary. Evolutionary products can start as something simple and evolve into something more complex. They are the ones we usually talk about because they are easy to do, and make up the bulk of all digital products.
Revolutionary products are the ones that can’t evolve from something simpler but have to be complex from the start to serve a meaningful purpose. The Apollo space program is a good example: It probably wouldn’t have worked very well if they “launched early and launched often” and fixed problems as they went. It would also require too many suicidal astronauts
It had to be perfect the first time. It’s basically the same issue as irreducible complexity in evolution: All the intermediate steps have to be useful, or you won’t ever get to the finished product. Incidentally this is also why you don’t see moving parts such as wheels in biological organisms: The steps leading up to it are no good. Aeroplane manufacturing is the same thing: Either it works or it doesn’t.
The articles advice pertains only to evolutionary products and startups.
May 12, 2009 at 5:32 am
You can’t have revolutionary Apollo program without having automobile (combustion engine) and rocket (propulsion engine)
That’s the reason why Apollo program didn’t exist in Roman empire.
My point is revolutionary system can’t exist without evolutionary (sub)-systems
May 12, 2009 at 9:24 am
In reply to your comment here and on HN,
It’s definitely possible to take the evolution route (I don’t quite agree that there’s a clear dichotomy between revolution and evolution) and have a goal in mind. I’m sure Steve Jobs had already envisioned the App Store when he was working on iPhone 1.0. The difference between complex and simple lies in focus. The reason it’s not possible to build complex systems from scratch is that you just can’t focus on so many different parts/components and integrate them together as well. Apple builds successful products because they focus on a few things rather than do everything all at once.
As for your other point, I believe Gall’s law (your quoted bit) holds true for all cases but the other rule I added about each intermediate step being useful might only be true for some cases (perhaps, more for user-facing products).
You’re right that the blogpost might only pertain to “evolutionary products and startups”. I wrote it with software in mind but my guess is that it’s also mostly true for other kinds of things. I need to think further about them.
May 12, 2009 at 9:39 am
I can remember that http://www.armadilloaerospace.com is working precisely that way to build reusable rockets.
May 12, 2009 at 6:00 am
Excellent essay. I find one of the tough things about simplicity is just recognizing it. Software engineers have a tendency to think even the most complex of things are relatively simple (hence Hofstadter’s Law). I make this mistake myself, very often. I think it might be a built-in danger of the craft, considering how widespread it is.
There are many more ways to combat complexity today than there were several years ago. Web frameworks, dynamic languages, etc. can all make simple web applications in hours rather than weeks. But the UNIX ethic that you channeled in “it should serve one purpose and one purpose only” isn’t the key thing, I don’t think. Though things like Google and Twitter are everyone’s famous example here, there are many web applications that are nowhere near the UNIX ideal — though it’s true they all started somewhere.
The essence of the Twitter example is less about “doing one thing” and more about feedback loops. Yes, the first thing Twitter released was very simple, and probably had a really barebones database schema. But more importantly, they started *somewhere*, and rather than develop according to a plan, they decided to let the users’ behavior guide their development.
I like your mantra: “start simple, use a lot, evolve.” But I might change it to, “start *somewhere*, use a lot, evolve.” These last two steps are the key. This approach of following the user’s footsteps with a working product is what separates a useful product on the long term from a downright frustrating one.
May 12, 2009 at 7:01 am
Charles Mingus: “Making the simple complicated is commonplace; making the complicated simple, awesomely simple, that’s creativity.”
May 12, 2009 at 1:51 pm
Why do you think it was a good thing (presumably) that they built in support for @ and it would not be a good thing for them to build in support for RT? Makes no sense.
May 12, 2009 at 5:43 pm
[...] Tags: Design, Hofstadter, LinkedIn, Software_Development trackback Today I ran across this blog post that references two of my favorite “laws”, namely Gall’s Law and [...]
May 16, 2009 at 1:38 am
[...] The Importance of Simplicity — 11:55am via Google [...]
May 17, 2009 at 5:08 pm
[...] Simple. « chimney (tags: design programming) [...]
June 9, 2009 at 8:09 am
[...] Writing Devo Actions Simple. [...]