Citation: I’ve given versions of this talk at the Heidelberg Laureate Forum in 2013 and 2015, and as the Wheeler Lecture at the University of Cambridge in 2015. There is a paper that has been in progress for several years, but is not in even draft form.
I have many hints that can be helpful in designing computer systems, as well as a few principles. Two ways to organize them are:
· Goals (What you want)—simple, timely, efficient, adaptable, dependable, yummy.
· Methods (How to get it)—approximate, increment, iterate, indirect, divide and conquer.
Of course the goals are in conflict, and engineering is the art of making tradeoffs.
Some simpler oppositions are:
· For adaptable systems, between evolving and fixed, monolithic and extensible, scalable and bounded.
· For dependable systems, between reliable and flaky, consistent and eventual.
· For incremental methods, between indirect and inline, dynamic and static, experiment and plan, discover and prove.
It also helps to choose the right coordinate system, just as center of mass coordinates make many dynamics problems easier. For example, you can view the system state as a name→value map, or as an initial state and a sequence of operations that transform the state. You can view a function as code or as a table or as a sequence of partial functions.
In the complex process of designing systems, both principles and hints can only be justified by examples of what has worked and what has not.