Over the last few years – more than a decade, really – it seems that, somehow, *nix- and Linux in particular, has been tagged as being some sort of OS ideal. It’s often been cited as a "programmers OS" and I’ve seen claims that WIn32 is terrible, and people would take the "Linux API" over it anyday. That is a verbatim quote as well.
However, I’ve thought about it some and after some rather mixed experiences trying to develop software for Linux I think I feel something of the opposite. Perhaps, in some ways, it really depends what you learned first.
One of the advantages of a Linux-based (or to some extent, UNIX-based) system is there is a lot of compartmentalization. The user has a number of choices and these choices will affect what is available to the applications.
I’d say that generally, The closest thing to a "Linux API" that applications utilize would probably just be the Linux Kernel userspace API.
Beyond that, though, as a developer, you have to start making choices.
Since the user can swap out different parts, outside of the Linux Kernel userspace API, pretty much nothing is really "standardized". Truth be told most of that kernel userspace API isn’t even used directly by applications- usually they get utilized through function calls to the C Standard library.
The Win32 API has much more breadth but tends to be more "simple", which tends to make using it more complicated. Since it’s a C API, you aren’t going to be passing around OO instances or interfaces; typically more complicated functions accept a struct. Hard to do much better than that with a C API.
However, with Windows, every Window is created with CreateWindowEx() or CreateWindow(). No exceptions. None. Even UWP Windows use CreateWindow() and have registered Window classes. Even if perhaps it’s not the most pleasant base to look at at least there is some certainty that, on Windows, everything is dealt with at that level and with those functions.
With Linux, because of the choices, things get more complicated. Since so many parts are interchangable, you can’t strictly call most of what is made available and used by applications a "Linux API" since it isn’t going to exist on many distributions. X11, for example, is available most of the time, but there are still Linux distributions that use Wayland or Mir. Even using just X11, it only defines the very basic functions- It’s a rare piece of software that actually interacts directly with X11 via it’s server protocol, usually software is going to use a programming interface instead. But which one? For X11 you’ve got Xlib or xcb. Which is better? I dunno. Which is standard? Neither. And then once you get down to it you find that it only actually provides the very basics- what you really need are X11 extensions. X11 is really only designed to be built on top of, with a Desktop Environment.
Each Desktop environment provides it’s own Programming Interface. Gnome as I recall uses "dbus"; KDE uses- what was it? kdetool? Both of these are CLI software that other programs are supposed to call to interact with the desktop environment. I’m actually not 100% on this but all the docs I’ve found seem to suggest that at the lowest level aspects of the desktop environment is handled through calls to those CLI tools.
So at this point our UI API consists of calling a CLI application which interacts with a desktop environment which utilizes X11 (or other supported GUI endpoints) to show a window on screen.
How many software applications are built by directly interacting with and calling these CLI application endpoints? Not many- they are really only useful for one-off tasks.
Now you get to the real UI "API"; the UI toolkits. Things like GTK+ or Qt. These abstract yet again and more or less provide a function-based, C-style API for UI interaction. Which, yes- accepts pointers to structs which themselves often have pointers to other structs, making the Win32 API criticism that some make rather ironic. I think it may arise when those raising the criticism are using GTK+ through specific language bindings, which typically make those C Bindings more pleasant- typically with some sort of OO. Now, you have to choose your toolkit carefully. Code written in GTK+ can’t simply be recompiled to work with Qt, for example. And different UI toolkits have different available language bindings as well as different supported UI endpoints. Many of them actually support Windows as well, which is a nice bonus. usually they can be made to look rather platform native- also a great benefit.
It seems, however, that a lot of people who raise greivance with Win32 aren’t comparing it to the direct equivalents on Linux. Instead they are perhaps looking at Python GTK+ bindings and comparing it to interacting directly with the Win32 API. It should really be no surprise that the Python GTK+ Bindings are better; that’s several layers higher than the Win32 API. It’s like comparing Windows Forms to X11’s server protocol, and claiming Windows is better.
Interestingly, over the years, I’ve come to have a slight distaste for Linux for some of the same reasons that everybody seems to love about it, which is how it was modelled so heavily on UNIX.
Just in the last few years the amount of people who seem to be flocking to OS X or Linux and holding up their UNIX origins (obviously more so OSX than Linux, strictly speaking) as if that somehow stands on it’s own absolutely boggles my mind. I can’t stand much about the UNIX design or philosophy. I don’t know why it is so constantly held up as some superior OS design.
And don’t think I’m comparing it to Windows- or heaven forbid, MS-DOS here. Those don’t even enter this consideration at this point- If anything can be said it’s that Windows wasn’t even a proper competitor until Windows NT anyway, and even then, Windows NT’s kernel definitely had a lot of hardware capability and experience to build off that UNIX never had in the 70’s- specifically, a lot of concepts were adopted from some of the contemporaries that UNIX competed against.
IMO, ITS and MULTICS were both far better designed, engineered, and constructed than any UNIX was. And yet they faded into obscurity. often People point at Windows and say "The worst seems to get the most popular!" But if anything UNIX is the best example of that. So now we’re stuck with people who think the best OS design is one where the the shell is responsible for wildcard expansion and the underlying scheduler is non-preemptive. I wouldn’t be surprised if the UNIX interrupt-during-syscall issue was still present, and instead of re-entering the syscall it returned an error code, making it the application’s responsibility to check for the error and re-enter the syscall.
It seems to me that one of the axioms behind many of the proclamations that "*nix is better designed" seems to be based on definitions of "better designed" that correspond to how *NIX does things- conclusion before the reason, basically.
Have something to say about this post? Comment!