It’s time to reformulate the principles guiding my work.

[Revised definition of complexity in response to misunderstandings]

Inessential complexity is the root of all evil

Most of the problems of software arise because it is too complicated for humans to handle. We believe that much of this complexity is unnecessary and indeed self-inflicted. We seek to radically simplify software and programming.

Complexity is the total learning curve

We should measure complexity as the cumulative cognitive effort to learn a technology from novice all the way to expert. One simple surrogate measure is the size of the documentation. This approach conflicts with the common tendency to consider only the efficiency of experts. Expert efficiency is hopelessly confounded by training and selection biases, and often justifies making it harder to become an expert. We are skeptical of “expressive power” and “terseness”, which are often code words for making things more mathematical and abstract. Abstraction is a two-edged sword.

Our institutions, culture, and psychology all foster complexity

Maintaining compatibility increases complexity.

Technical debt increases complexity.

Most R&D is incremental: it adds features and tools and layers. Simplification requires that we throw things away.

Computer Science rejects simplification as a result because it is subjective.

The Curse of Knowledge: experts are blind to the complexity they have laboriously mastered.

Rewarding programmers for their ability to handle complexity selects for those who love it.

Our gold-rush economy encourages greed and haste.

To make progress we must rebel against these vested interests and bad habits. There will be strong resistance.

Think outside the box

Much complexity arises from how we have partitioned software into boxes: OS, PL, DB, UI, networking; and likewise how we have partitioned software development: edit, version, build, test, deploy. We should go back to the beginning and rethink everything in order to unify and simplify. To do this we must unlearn to program, a very hard thing to do.

Programming for the people

Revolutions start in the slums. Most new software platforms were initially dismissed by the experts as toys. We should work for end-users disenfranchised by lack of programming expertise. We should concentrate on their modest but ubiquitous needs rather than the high-end specialized problems addressed by most R&D. We should take inspiration from end-user tools like spreadsheets and HyperCard. We should avoid the trap of designing for ourselves. We believe that in the long run expert programmers also stand to greatly benefit from radical simplification, but to get there we must start small.

Simplicity first; performance last

Performance is often the first excuse for rejecting new ideas. We even do it to ourselves. We must break our own habit of designing for performance: it is seductively objective and quantifiable whereas the most important design issues are messily subjective and qualitative. After all, performance optimization is one thing we have mastered. Build compelling simplicity and performance will come.

Disciplined design evaluation

Computer Science has decided that, being a Science, it must rigorously evaluate results with empirical experiments or mathematical proofs. We are not doing Science. We are doing Design: using experience and judgement to make complex tradeoffs in order to satisfy qualitative human needs. Yet we still need a disciplined way to evaluate progress. Perhaps we can learn from the methodologies of other fields like Architecture and Industrial Design. This is a meta-problem we must address.