Hand tools and workbench tools
It might seem strange that I am a big proponent of malleable systems like Emacs and Lisp, and also of Fedora Atomic and GNOME. Someone who disagreed with me on one of these preference might even be tempted to accuse me of hypocrisy, or otherwise use one preference to undermine the other. However, I'd argue it's perfectly consistent due to a crucial distinction I talk about in my GNOME Is Not 'Mobile-First' essay: the split between hand tools and workbench tools (I didn't use exactly these terms in the original section, but I think these are better ones).
Hand tools are the tools you actually open your computer every day to use. They're things like your productivity system (calendar, to-do app, project manager, what have you), note taking system, text editor, email client, web browser, IDE, word processor, your drawing software, image editor, video editor, 3D modelling software, animation studio, and so on. These are the tools that you actually use to do the work you consider central, whether that's for your job or a hobby that you care about. These are the ones that are "in your hand" all the time, the ones that you really care about.
Then there's workbench tools. These represent all the infrastructure that gets you to the point where you can easily and effectively use the power tools. It's the plumbing in the background. Things like Wi-Fi, Bluetooth, file management, window management, cross-device syncing, VPNs, battery management, process management, display management and graphics, drivers, the hardware, and so on. You might think of these as the things you usually put on your desk or workbench while you're using the really important hand tools, that you pick up occasionally to do something secondary, in a supporting role to your main tools. You might also think of these as your workbench or toolbox itself.
Generally, for me, hand tools are best when they're powerful and flexible, because I don't want to have to constantly switch to other tools – with inconsistent interfaces and capabilities, and coarse-grained integration – to do related tasks. These tools also really need to be configurable, so that I can mold the tool to my individual needs and workflow over time, grow with the tool. The power comes with a steep learning curve, the flexibility and customizability come with the possibility for unreliability and error, and the customizability opens up a huge new hole to sink time into, but these drawbacks are worth it for the power I gain, because the whole point of using my computer is to access these tools, and they're deeply important to me and I'm going to spend a lot of time using them for complex and advanced tasks in the long term. Emacs and Lisp fit this description for me.
Meanwhile, workbench tools are at their best when they're simple, maximally reliable, intuitive, and distraction-free, even when that sacrifices power, completeness, flexibility, and customizability to some degree. This is because the tasks I do with these tools are totally secondary to what I actually want to get done, so I don't want to be forced to spend time learning and maintaining them, and I simply won't use any extra more powerful features even if they are there, so them being there just adds complexity and unreliability; and moreover, I don't want to have to worry about getting sucked into some customization or perfectionism rabbit hole when trying to use the tool. If I open my computer to program and I want to listen to music on my Bluetooth earbuds while I do it, the last thing I want is to have to fiddle with my Bluetooth daemon or something. I just want my workbench to fade away, to be the invisible background for the tools I actually care about. GNOME and Fedora Atomic fit this description for me.
This doesn't seem to be only my opinion, either – for instance, many Emacs users who highly value its flexibility use it on a Mac, probably precisely because they want this stable, reliable core to operate on top of.
Now, I don't think this dichotomy is absolute: some workbench tools, depending on which hand tools you use, are so intertwined with your use of hand tools that you really need them to become hand tools too. For instance process management, file management, and version control happen so often when you're a programmer that you really want them to be hand tools too – but in my opinion, when this happens, what you should do is to integrate them deeply into your existing hand tools, so that you don't really expand the surface area of the drawbacks of your hand tools, while still increasing the surface area of their benefits, and maximizing integration between tasks you often do together and intertwine, instead of adding more hand tools on top. In fact, merging as many of your hand tools into one environment as possible is usually a good thing for the same reason. This is why I integrate so much into Emacs. This is also why IDEs exist. I call tools that need to be integrated like this "secondary hand tools."
Now, does this mean that I think the way that Emacs plus Fedora Atomic and GNOME achieve my goals perfectly? No, I'm not deluded. My ideal system would have these properties:
-
Composed of a core operating system image (containing the entire set of infrastructure and workbench tools) that:
- Is immutable at runtime.
- Is updated atomically, through swapping out the core image.
- Can be modified arbitrarily at run time through layering changes on top, where each change is transactional, version controlled, kept separate (only shadowing the core underneath), and reversible.
- Has a way to specify in detail how to build the image with custom modifications, preferably byte-for-byte reproducibly, which allows inheritance from upstream images.
- Has an easy path to transition from run-time layered changes to changes that are part of your image specification.
- Is built offline, while the image is not in use, and automatically checked to make sure it will work, and then and only then provided as an update to the running image.
- When a new upstream image is available, has all your changes rebuilt on top of the upstream image, checked, and provided as an update.
- Can easily be built either locally on your computer and then swapped in or on your own server or in the cloud.
- Is built from a system that fundamentally understands and is intended to work with images.
- Can be easily reset to factory settings, removing all layered changes, at runtime.
- No changes to the core image should effect the user's file system.
- All the workbench tools are maximally reliable and cover all the basic use-cases, but are as simple and intuitive to use as possible, even if that leaves out some edge-case features. Something like the GNOME DE, but run by Transient menus as well as point-and-click.
- …which provides a runtime userland image that is composed of a highly integrated, creation-first computing environment that combines all your hand tools into one deeply integrated thing, and provides secondary hand tools so deeply integrated, and so conveniently accessible at any point, with the rest of the hand tools in the computing environment that you barely even notice they're there or separate from the primary hand tools.
- Which has the concept of "local" changes (to secondary configurations, or for installing small tools or programming toolchains) that aren't even modelled as layers on the core image, but instead as something else, maybe user-local and localized to a specific part of the fileystem, not effected by resetting the image.
- Has a deep level of communication and integration between the core image and the runtime userland.
I think Emacs gets very close to this in some respects – you can't actually modify the core sources, even the Lisp ones, you can only add modifications dynamically on top at runtime, and then easily migrate those modifications to your init file to persist them, but you can even then still always remove all these modifications by starting Emacs with -Q, and it provides a deeply malleable, creation-first computing environment – and Fedora Atomic with BlueBuild gets close in others – actually tracking, versioning, and making individually reversible the runtime changes, providing a coherent way to make changes to the specification of the image instead of just things that have to get re-applied at start time every time, providing off-computer image building and checking for the built images, and actually providing all that's necessary for an OS in the image, providing atomic updates – and Lisp gets some others – an easy way to go from runtime changes to full modification of the image with save-lisp-and-die – but none of them have all of it quite yet. I think any modern stab at a Lisp OS would have to get this right from the start, to avoid turning into a totally unreliable ball of mud.