It means nothing. Yeah that's it feel free to close the tab, the rest is just elaborating on this.
First off, let's get this out first: there is no singular unix philosophy.
There is how Dennis Ritchie and Ken Thompson designed Unix, but these design considerations are not what people talk about.
There is McIlroy's "characteristic style" of Unix users/developers, but this is descriptive, not prescriptive, not a philosophy at all. Though indeed this is where "Make each program do one thing well." comes from.
Then you have Salus, who paraphases McIlroy in a way. In "A Quarter Century of Unix", McIlroy is quoted to say that Unix looked different after the introduction of pipes.
The power of Unix originated here, from the relationships generated among programs, not from individual programs themselves. Unix now had a language all its own. It had a philosophy, an ethos. It had a relatively small group of devoted users on a handful of AT&T Bell sites. But it had no real audience.
At this stage, we now come to the "Unix Philosophy" as it is quoted, except only the first part is quoted when discussing it:
- Write programs that do one thing and do it well.
- Write programs to work together.
- Write programs that handle text streams, because that is a universal interface.
What I'm going to try and demonstrate is that the first two are meaningless outside of this context.
Write programs that do one thing and do it well. #
What is one thing? Where do you draw the line?
Let's consider a classical example: cat.
The conCATenate program is intended to... conCATenate files.
Ah, but there is cat -v, which is considered harmful.
If cat -v is harmful, but not other parts,
then let us consider the argument-less cat to be a good example.
So cat a b c will conCATenate the files a, b, and c.
Is this one thing?
Well, it is a logical separation, a separation of usage.
Indeed, the actual cat command will open files, read files, and write text.
To accept this as "one" thing,
we must establish either logical or usage separations.
Let's start with a logical separation: "one thing" is verbful,
as in the "one" thing can be reduced to a single verb.
In the case of cat it is conCATenate.
In the case of ed it is edit (text files).
What then, does the shell do?
Well, it provides the crucial interactive environment. It lets you run the commands, which in turn let you write, test, run other commands, but you cannot reduce it to a single verb. So it cannot be a logical separation.
Let us then consider the usage separation: you use it to achieve a specific result. Shell now passes, but so indeed do other things.
Siemens is a manufacturer of industrial automation technologies. Industrial automation focuses on components called "PLC"s, Programmable Logic Controller (it's just a computer), and "SCADA"s, Supervisory Control and Data Acquisition systems (they're just computers, one side talks a protocol called OPC-UA while the other side is an "HMI" (Human Machine Interface), aka just a UI).
To program a PLC, you use this kind of low-code kind of IDE that eventually produces an image you can copy to a PLC and have it run the produced code.
Because a big part of the "reason" for all this is to claim that it's "not code", that PLCs are "not computers, they're logic controllers", and so on, what you program PLCs in is absolutely not an IDE. It is instead an integrated automation environment.
The one Siemens ships is called TIA Server, and it has everything you need to program a PLC. It will let you write "code" for it, run tests, compile to the output format, and deploy the result to your PLC. It focuses on exactly one usage: handling the PLC. Indeed, Siemens representatives have told me that TIA Server follows the Unix philosophy.
Under this definition, for this part of it, I would have to concede if we accepted the usage separation. We do not get to dictate where the "line" for the "single usage" is.
Hell, consider GNU true which can return 1.
Just run this! /bin/true --help >&- and see what's in $?.
It had one job.
Indeed, this problem applies to all lines you can draw on "one thing". Indeed, "well" is just as problematic.
This clause means nothing. Or more accurately, and worse, it means whatever you want it to mean.
Write programs to work together. #
What does it mean for programs to work together?
What does true work with? How about false?
We can only surmise that programs are meant to be written with each other in mind.
A commonly cited violator of the unix philosophy is systemd. Systemd is composed of many programs that do "one thing" (see previous section). They all interoperate to work together to achieve the goal of systemd (the project). Yet the complaint is not that it doesn't follow tenet 3 (see next section), but that it's "monolithic".
The translation is that the systemd programs interoperate with each other, but not necessarily with other programs. It asks that other programs be written with it in mind, not vice-versa. In other words, it's not bidirectional.
This is, however, the same thing for true and false.
Programs working together is a property of the system, not the program. The systemd system does follow the "unix philosophy", at least tenet 2, but it does not mesh well with pre-existing utilities.
Is that a requirement?
Do we need to include cat in particular in the philosophy?
It's hardly a philosophy, but rather a description of a system,
which indeed is exactly what the original statements were.
In other words, this tenet describes a vibe more than actual behavior. And that means that it means whatever the reader wants it to mean. It means nothing.
Write programs that handle text streams, because that is a universal interface. #
Funnily enough, this tenet is the most specific one of the bunch. It's also the one nobody ever talks about. It also blatantly has myriads of exceptions, like the usual true/false. Though indeed most cases of "this doesn't follow the unix philosophy" will fail this, so will many cases of "good positive examples".
Simply because the "one job" for some programs is not manipulating text streams.
Descriptions #
This "philosophy" is descriptive. It's not trying to actually create a direction for program design. It's trying to explain what the vibes are for a subset of programs that people enjoy.
Because it's trying to capture a vibe, everything that is said is deeply rooted in its context. Without this context, it can mean anything you want it to mean. This context is gone.
Globally, I actually agree with the above "philosophy"! A lot more than some people claiming to like it. I do truly believe that plaintext is a universal interface, and that the stream is its most natural representation. And I do believe that programs shouldn't be feature pinatas, that they should be focused.
However, the context is gone, and the above is not a set of design guidelines. I do not talk about the Unix philosophy because there is nothing to talk about. It's here that we hit the problem of non-transference, where making something prescriptive is very difficult, and does not produce particularly good results.
So I encourage you to do what I do: When you make things, make them the way you believe they should be made. When you pick other things up, prioritize those that are like how you think they should be. It's what everyone else is doing anyway, eh? It does mean that sometimes I'll pick something that's not immediately suitable, but the result is generally more pleasing in the end. Because if you're not doing all of this for the joy of it: why are you here?