Control
There is this great quote:
In the beginning you always want results. In the end all you want is control. -- How I program C: Eskil Steenberg
Games usually want to get all the performance they can get from the available hardware. Games are the most inherently complicated software programmers build, so there is a lot of pressure to minimize accidental complexity. There are these laws in cybernetics by [W. Ross Ashby] Law of requisite variety
The larger the variety of actions available to a control system, the larger the variety of perturbations it is able to compensate.
In order to adequately compensate perturbations, a control system must “know” which action to select from the variety of available actions.
The better control you have over the physical machine the less perturbations you will have.
A good example is automatic memory management where the programmer gives way control to the garbage collector to manage memory, but the garbage collector only has a very limited amount of information on memory access patterns, so it creates perturbations. This can be seen in this graph taken from this blog post: Why Discord is switching from Go to Rust
The perturbation cause by the Go garbage collector can be easily seen on the purple graphs.
This specific example is about computer resource usage, however the underlying principle is a lot more general.
Take web frameworks for example, they all have badly designed apis that take away control from the programmer, I talk about this in more detail in Modeling - data first.
What happens is the team wants to work on the functionality of the program but the framework team has bright idea, introduces breaking changes and then everyone using the framework will have to migrate to the new version and introduce perturbations in the productivity graph (the perturbation here points down).
Using a framework as a programmer is like a business outsourcing the C suite.
You give away top level control where you have the most leverage.
An interface that restricts control makes global optimization—both in terms of performance and cognitive clarity—impossible.
There are many example of programming interfaces that take away control:
- callback based apis
- dynamic dispatch with vtables
- language barriers are even worse like SQL in backend dev, or css, html, javascript in frontend dev The current web development infrastructure enables quick initial results but eventually slows progress to a crawl due to perturbations in performance, bugs and productivity—all stemming from a poorly designed foundation. A good idea for API designers to keep in mind is to keep control in the consumers hands. One example of that I wrote about is in Redesign of the routing api in web frameworks