Great Software is Simple on Many Planes of Abstraction
There is a dichotomy in software development, high-level and low-level software. This is particularly true for programming languages, where you have low-level languages that give you more control, but require more understanding of how computers work, and high-level languages that allow you to express your ideas more simply and allow you to not think about low-level details.
High-level software is called that because it operates at higher levels of abstractions. This means that it obscures the machinery of what happens within a computer (the "low-level"), so that we can focus on the task at hand. For example, we would not want to think about how a web browser forms a TCP/IP connection, communicates with a DNS server, etc., when opening a web pageāat least, we do not want to up until the point where we encounter an error.
High-level software unlocks the ability for us to perform more advanced tasks quicker with less mental overhead. It can also unlock a great deal of improved security, as it can restrict certain operations from the user and better adapt to their needs, which, even if it deprives users of some liberty, can still be desirable.
However, when we only focus on building a good high-level experience, it comes at the expense of low-level control that becomes inaccessible or too complex for regular users. This invites us to be inefficient and construct false understandings. Without a deep understanding of our systems, we cannot meaningfully fix the system nor optimize it. It invites us to outsource this control to experts, who are often restricted to building general solutions for many use-cases. Poor understanding often leads to rebuilding the same solutions over and over again, with the solutions becoming even more complex and inefficient each time. When only experts understand systems, it centralizes knowledge and power away from the general population.
I explored the democratic problems it leads to in my essay The Curse of Convenience.
Low-level tools give us greater control and greater freedom. Understanding the lower-level units makes it easier for us to understand how everything fits together, and gives us the power to make the changes we wish. However, using only low-level tools makes it more difficult to cleanly express ideas and it can be a frustrating experience. It sometimes requires digging through manuals and the time it takes to accomplish tasks becomes much longer. It is also easier to make mistakes.
This dilemma leads me to solutions that attempt to be simple on many planes of abstractions. In programming languages such as Go and OCaml, the high-level semantics are simple, but a user can still also understand the lower-level details of what happens, which makes it possible to operate at a lower-level when necessary without being an expert. In software, Unix utilities find the balance of being simple and allowing users to express high-level ideas. Older motorcycles are easy to operate, and also easy to fix when necessary.
- Marc