The Three Laws of Informatics

There are numerous rules or laws trying to formalize what makes — or how to make — software. A few take inspiration from Isaac Asimov’s Three Laws of Robotics. Asimov’s laws are fun first because they’re a somewhat geeky Sci-Fi reference, but they’re also good because they’re minimal and make precedence clear.

I’ll dub them the Three Laws of Informatics. These laws may not be very original in their content — and not truly laws — but like Asimov’s laws, they try to find the most essential, orthogonal axioms from which desirable properties can be derived. They are best effort laws, because perfection is out of our grasp.

Here we go:

Programs must be correct. Programs must be maintainable, except where it would conflict with the First Law. Programs must be efficient, except where it would conflict with the First or Second Law.

The first law means programs should behave as expected in all situations. It implies software should try be devoid of bugs, security issues and should never crash.

The second law implies that programs should be well-designed and documented — because it is required to have a good understanding of the code — and modular, because large monoliths are not maintainable. There should also be tools helping developers maintain programs. Partial evolutions should not warrant a full-rewrite and another developer should be able to make necessary changes because of design clarity and because the language can be mastered.

The third law means programs should tend towards an optimal balance of speed and resource consumption for the most likely inputs — that is, according to how they are meant to be used. It implies we should use the best data-structures for the job, aim at the best trade-offs — because most of the time there is no global optimum — , plan for scale appropriately and make code sympathetic to the computer running it.

The three laws, together, create a requirement for a vibrant ecosystem and community. Developers cannot write correct, maintainable and efficient programs alone, because modern programs depend on more code than one sole developer can produce. They have to reuse components provided by the community. They have to share a belief that the community is healthy— either growing or large enough that existing components will be maintained and new ones will be built. This makes the community surrounding a language a paramount factor when selecting a programming environment.

Three Laws and Order

Correctness is undoubtedly our main concern in software. If a piece of software doesn’t do its job properly, it’s not worth running. If it’s unsafe, it’s a security risk. This clearly makes correctness our First Law.

However, one might argue whether maintainability should matter more than efficiency or vice-versa. A program could potentially achieve better performance when ignoring maintainability completely, and programming with only correctness and maintainability in mind might result in a completely inefficient program.

In reality, maintainability and efficiency are intertwined: a good architecture is built around an efficient solution. For instance the Xi editor, aiming to be a highly performant editor for “the next 20 years”, is built around the Rope data-structure. Designing systems exclusively top-down may prevent the realization of an efficient solution ; designing them exclusively bottom-up may leak too many implementation details and prevent a clean, loosely-coupled architecture.

Still, if a piece of software is correct and extremely efficient but cannot be maintained, it’s barely more than a black box. And are we that confident it is correct, if we can’t understand it? The other way around, an inefficient but correct+maintainable program might yet be salvageable. Maintainability gets to be the second law.