If you lurk on Linux forums long enough, you will hear statements like “Systemd doesn’t follow the Unix philosophy” or “Gitlab has abandoned Unix philosophy“. But what exactly is this Unix philosophy that users keep mentioning. In this article, let’s deconstruct the long-standing notion of the Unix philosophy.
History of Unix Philosophy
Unix is a proprietary operating system developed by Bell Labs’ Ken Thompson and Dennis Ritchie in 1969. The Unix Philosophy is a set of principles that arose from the experience of these Unix developers which help in building minimal, modular, and easy-to-use software. While they were originated by Ken Thompson as a few informal norms, over time they became more established as multiple developers tried to put them in words. Later operating systems such as GNU/Linux and FreeBSD embraced this set of norms and used them while building their own software.
One of the first times, the design consideration of Unix was casually mentioned was in a paper written by Ritchie and Thompson in 1974 in which they point out that software should be easy to write, test, run; interactive and elegant.
However, in 1978, Douglas McIlroy formally documented the Unix Philosophy in a Bell Labs journal. Those notes were then summarised in Peter Salus’s book, A Quarter Century of UNIX in these three easy points.
- Write programs that do one thing and do it well.
- Write programs to work together.
- Write programs to handle text streams, because that is a universal interface.
Over time, many developers like Eric Raymond have added to or altered this philosophy slightly but these still remain the core principles. In the next section, I will be discussing the rules/norms/tenants that form the Unix philosophy as considered by developers today.
Tenants of Unix Philosophy
All the tenants discussed here have one aim, to make software development, debugging and maintenance as easy as possible. They aren’t universally agreed upon, as everyone has their own interpretation; however, the basic principles I am going to discuss here are still widely regarded as core to this philosophy.
1. Modularity and Composition
Modularity is the art of dividing a huge software into small parts, which are connected through clean interfaces. Ever since the conception of computing, we have tried to keep the complexity of the system as low as possible. Building a monolithic software in which every part is integrated and dependent on another, makes it hard to manage and debug the software. Apart from that modularity also offers more choice to the end-user.
For example, in Windows, all the components of the operating system are integrated with each other. There is no separate Windows kernel, there is a separate Windows UI, there is no separate Windows menu bar because they are all the same.
However, a Linux based operating system is like a LEGO set. You can run the kernel itself, without GUI. If you want GUI, you can develop a GUI server (like X11) on top of the Linux kernel. After that, you can choose among several window managers and desktop managers which you want to work on top of your GUI server. Every part of the system, even the init system (systemd, iniv etc) which boots up the system are separate replaceable entities not tied to the operating system itself. While this gives the end-user more choice and freedom, it also makes sure that if any component of the system fails, the whole operating system isn’t at risk.
2. Composition and Extensibility
This norm originates directly from our above point. You should always write programs, which can work with other programs because if the programs don’t interact with each other, we are gonna end up with monolithic software. We have to put programs together like lego bricks in which the output of one program is the input to another and using these simple building blocks, we will build complex software. This also lends its way to extensibility. If you write programs on which other programs can be built, they can be further extended by future generations. This rule is followed by ALL classic Unix era software, be it Vim, Emacs, Bash, etc which today are thriving because of their extensibility.
3. Do One Thing and Do It Well
Since we are building a modular program, every small component should have a single task and it should do that small task as efficiently, elegantly and robustly as possible. These small programs are easy to handle, maintain and debug.
4. Clarity and Simplicity
As mentioned by Eric Raymond in his 2003 book, Clarity is better than cleverness. Programs should be simple and clear to users. They should communicate whatever is happening in the background and give a clear, verbose error message when they fail. The user interface should not be surprising. This is not to say it has to be bland, but it has been usable, clear and most importantly simple. The algorithms implemented in the program should also be as simple as possible. Only implement fancy, complex algorithms if really needed.
Note: This is not an endorsement of Eric Raymond’s racist political beliefs
5. Portability over Efficiency
While the fastest, most efficient software is cool from a purist point of view, a slightly slower but more portable code is generally more practical. While we should make the software as memory efficient as possible (since memory was limited at the time), we have to be beware of these “micro-optimisations” to the speed of the program as the most efficient way is specific to hardware and hence not portable. This does not mean that our software should be slow and clunky, this just means that it should be as fast as it can be without sacrificing portability.
Unix philosophy in short is “KISS: Keep it simple stupid“. All of these tenants are geared towards making minimal, simple, clear, bloat-free software. This philosophy, while still in practice by some programmers, has been pushed to the sidelines due to the advent of machines with practically infinite memory. With machines like these, you don’t have to be memory efficient, or simple. To learn more about Unix Philosophy, and Unix itself, read Peter Salus’ A Quarter Century Of UNIX. Have fun and keep exploring!