Zawinski's Law, when taken literally, argues that programs all eventually need to be communicated with by people and other programs using a generic protocol and without using program-specific or domain-specific libraries to do so.
Unix shells (local), I'll add in HTTP (remote), and Email (remote and asynchronous) are the only forms that are ubiquitous, precisely because they enforce no structure for the payload. The structured alternatives are only popular in specific domains because they create their own ecosystem. As long as input can clearly be parsed, which goes hand in hand with being human-readable as long as you're not trying to be too efficient, you get schema implicitly transmitted out of band (by having output that you can visually inspect) and interoperability for anything that can read and write text.
I'd be interested in other directions this might go, but I remain skeptical of anything that will introduce and enforce a new paradigm that requires adding complexity to programs to accommodate it.
It's easy to agree that the AI assisted email writing (at least in its current form) is counterproductive, but we're talking about email -- a subject that's already been discussed to death and everyone has staked countless hours and dollars but failed to "solve".
The fundamental problem, which AI both exacerbates and papers over, is that people are bad at communication -- both accidentally and on purpose. Formal letter writing in email form is at best skeuomorphic and at worst a flowery waste of time that refuses to acknowledge that someone else has to read this and an unfortunate stream of other emails. That only scratches the surface with something well-intentioned.
It sounds nice to use email as an implementation detail, above which an AI presents an accurate, evolving, and actionable distillation of reality. Unfortunately (at least for this fever dream), not all communication happens over email, so this AI will be consistently missing context and understandably generating nonsense. Conversely, this view supports AI-assisted coding having utility since the AI has the luxury of operating on a closed world.
The professional matchmaker angle as a contrast is fascinating. The subscription model not only removes the incentive to provide quality quickly -- it reverses it. Doing a worse job is encouraged if you can leverage that to convince people that the future (which is only available by continuing your subscription) is worth waiting for. It's also more attractive because it has smaller up-front costs for the consumer.
It would be an interesting world if we outlawed auto-renewal for services that you need to actively use in order to get any value from them. When you're paying for Netflix, you aren't paying to watch movies, you're paying for /access/ to movies you can watch. The flip side is that the maximum potential service quality would decrease if revenue decreases -- which is also why ad-supported services prevail. If all players are subject to the same rules, that would either end up as a decrease in licensing costs or a focus on quality content over quantity. If they aren't producing exclusive content, they are beholden to the quality of the market. Either way, that should encourage quality content to be made over saturating the market with content.
Unfortunately, pipe dreams will remain pipe dreams.
That's one of the reasons that OpenBSD is rather compelling. BSDAuth doesn't open arbitrary libraries to execute code, it forks and execs binaries so it doesn't pollute your program's namespace in unpredictable ways.
> It's true that there's something of a problem where two copies of a libc can't coexist in a process...
That's the meat of this article. It goes beyond complaining about a relatable issue and talks about the work and research they've done to see how it can be mitigated. I think it's a neat exercise to wonder how you could restructure a libc to allow multi-libc compatibility, but question why anyone would even want to statically link to libc in a program that dlopen's other libraries. If you're worried about a stable ABI with your libc, but acknowledge that other libraries you use link to a potentially different and incompatible libc thus making the problem even more complicated, you should probably go the BSDAuth route instead of introducing both additional complexity and incompatibility with existing systems. I think almost everything should be suitable for static linking and that Drepper's clarification is much more interesting than the rant. Polluting the global lib directory with a bunch of your private dependencies should be frowned upon and hides the real scale of applications. Installing an application shouldn't make the rest of your system harder to understand, especially when it doesn't do any special integration. When you have to dynamically link anyway:
> As for why you’d actually want to dlopen from a static executable, there’s one killer app: exokernels, loading (parts of) system-provided drivers into your process for speed.
If you're dealing with system resources like GPU drivers, those should be opaque implementations loaded by intermediaries like libglvnd. [1] This comes to mind as even more reason why dynamic dependencies of even static binaries are terrible. The resolution works, but it would be better if no zlib symbols would leak from mesa at all (using --exclude-libs and linking statically) so a compiled dependency cannot break the program that depends on it. So yes, I agree that dynamic dependencies of static libraries should be static themselves (though enforcing that is questionable), but I don't agree that the libc should be considered part of that problem and statically linked as well. That leads us to:
> ... when done right they don't even require both sides to share a malloc implementation
Better API design for libraries can eliminate a lot of these issues, but enforcing that is much harder problem in the current landscape where both sides are casually expected to share a malloc implementation -- hence the complication described in the article. "How can we force everything that exists into a better paradigm" is a lot less practical of a question than "what are the fewest changes we'd need to ensure this would work with just a recompile". I agree with the idea of a "narrow waist of an interface", but it's not useful in practice until people agree where the boundary should be and you can force everyone to abide by it.
There is no distinction between system and program libraries in Linux. We used to pretend there was one before usrmigration, but that was never good to take seriously.
The distro as packager model ensures that everything is mixed together in the filesystem and is actively hostile to external packaging. Vendoring dependencies or static linking improves compatibility by choosing known working versions, but decreases incentive and ability for downstream (or users) to upgrade those dependencies.
The libc stuff in this article is mostly glibc-specific, and you'd have fewer issues targeting musl. Mixing static linking and dlopen doesn't make much sense, as said here[1] which is an interesting thread. Even dns resolution on glibc implies dynamic linking due to nsswitch.
Solutions like Snap, Flatpak, and AppImage work to contain the problem by reusing the same abstractions internally rather than introducing anything that directly addresses the issue. We won't have a clean solution until we collectively abandon the FHS for a decentralized filesystem layout where adding an application (not just a program binary) is as easy as extracting a package into a folder and integrates with the rest of the system. I've worked on this off and on for a while, but being so opinionated makes everything an uphill battle while accepting the current reality is easy.
Complexity has always been less respected the more it is separated from the experiences of the average person; or more personally, your own experiences. Unfortunately, that's the very nature of complexity itself. Dependencies increase instead of decrease in the hopes of scaling, saving time and money, or even providing a slightly better product. As positive as those efforts sound, they also make the failure cases worse.
The only people to respect with regards to complexity are those dealing with inherent complexity -- especially when they're building more digestible abstractions, and those working to reduce complexity due to having a substantial understand of it. It can be rather difficult to distinguish between inherent complexity and incidental complexity though.
This is only looking at the problem from one side. If there's a crisis and you're not treating it as one, you are committing two sins. Not only are you wrong, but you're wasting time more valuable than your own.
On the flip side, if you're treating something as a crisis when the person trying to help knows there isn't one, you're putting undue pressure and stress on someone and hurting both parties in the process.
The fundamental problem is inconsistent and inaccurate assessments of the situation. People are attached to their mindset and are often too stubborn to re-evaluate. The solution presented only shows concessions on one side. I'd add that if someone else thinks a situation is dire and you don't, you should try to understand their perspective better rather than immediately considering them rude and dismissing their concerns.
This seems emblematic of the general direction of technology. It's an approach to managing system complexity that works by adding additional complexity and handling that combination well as long as you use their tools. Nix isn't special in this -- all (non-derivative) Linux distros do exactly that, though that's probably little more than an extension of having written a package manager. I dislike higher level tools like this because they discourage understanding of anything below them. The filesystem is no longer organized in a human-readable fashion, it is an implementation detail.
I'd love to see more concerted efforts going the other direction -- managing complexity by working to make the system simpler and compartmentalizing additional functionality. System snaps, now packaging lxd and cups, are probably the closest mainstream example today.
Requiring that you sit further back is built on the notion that you need to be able to see your entire workspace at once, which was never true with an actual desk and largely implies that you want a single document to take up the whole screen. If you remove that limitation, then you find yourself with a larger workspace with elements at a comfortable size to work with.
I do prefer to turn my head side to side rather than up and down, so right now I'm happiest with a 5120x1440 49" monitor and may consider a 7680x2160 57" monitor sometime in the future.
MacOS 9 and the spatial desktop metaphor is neat. I went that route for a while. What this misses, however, is that the biggest problem with the desktop interface is that we've substantially increased application complexity and laptops (and even smaller devices) won. As a result, we're trying to answer the question "how we fit our skeuomorphic paradigm in a diminutive form factor". The inspiration involved much larger actual desks and tables where you can freely arrange several documents that are each visible and can be reached at a glance. If you're maximizing the window for a document for reasons beyond helping you focus, then your workspace ahem your screen is too small.
The screenshot is 1920x1080. Screens are sold using buzzwords like 'HD', 'UHD', and 'retina' that evoke a sense of image clarity. I spent years telling my dad that I liked higher resolutions because it meant more /space/ and he couldn't grasp what I meant. He was stuck on associating higher resolution with clarity until I bought him a 43" 4k monitor, and he used it for a while. Even at 1.5x scaling, suddenly, he was able to view multiple pages of a document clearly at the same time without even scrolling. This isn't at all a normal desktop setup or the kind of setup that desktop environments are optimizing for or advocating. But it works better and better matches the inspiration.
With regards to abstractions, the perceived quality of code depends heavily on who will be expected to read it. "Principle of least surprise" isn't universal, it's subjective because you're hiding complexity not actually making things less complex. If an abstraction feels natural to the person reading it, they will find the code easy to read.
Unix shells (local), I'll add in HTTP (remote), and Email (remote and asynchronous) are the only forms that are ubiquitous, precisely because they enforce no structure for the payload. The structured alternatives are only popular in specific domains because they create their own ecosystem. As long as input can clearly be parsed, which goes hand in hand with being human-readable as long as you're not trying to be too efficient, you get schema implicitly transmitted out of band (by having output that you can visually inspect) and interoperability for anything that can read and write text.
I'd be interested in other directions this might go, but I remain skeptical of anything that will introduce and enforce a new paradigm that requires adding complexity to programs to accommodate it.