Recently I ran into a bunch of talk on the web about Plan 9. It reminded me that I had once learned about Plan 9, but had mostly forgotten what the big ideas were. So of course I decided to explore again, and this time actually take notes. As I’ve already written notes down, I’ve decided I might as well make a blog post about what I view as the big ideas of Plan 9.
In my view Plan 9 primarily has 3 important technical details:
File systems in user space.
Using filesystem-based APIs.
Per-process filesystem namespacing.
Basically this is like FUSE, or GNU HURD file system translators. It allows any old program to mount and back a programmatic file system. This could of course be used in conjunction with a disk format to provide a file system in the most basic and traditional sense of having persistent files, but is more commonly used to allow the file system interface to become an interface for interacting with that program. Plan 9 file systems use the 9p protocol, which I hear is good and simple to implement (though I’ve never used it). My impression (and hope) is that since it’s part of the core design of the OS, userspace file systems in Plan 9 are more robust and have better fault tolerance than with FUSE, which is basically a tacked-on afterthought to Unix.
Filesystem-based interfaces are used, instead of other potential interfaces, even (especially?) for core infrastructure like network communication. For example, rather than using a TCP socket, Plan 9 programs will read and write files in a procedural TCP file system.
In other words, beyond the system allowing (userspace) procedural file systems, well-behaved Plan 9 programs actually rely on them. Modern Unix systems can do this to some degree with FUSE, but they generally don’t. No serious or important programs outside of Plan 9 seem to expect to do HTTPS by interacting with a file system instead of using the Berkeley Socket API and probably a library like OpenSSL. Meanwhile using an HTTPS file system is the only way to access the web in a pure Plan 9 implementation.
Each process in Plan 9 can set up different views of the filesystem for each of its children. I hope per-process namespacing is actually useful for enforcing security at the level of the file system in Plan 9, but I’m not sure whether it leaks in some way either by design or security bug. However, filesystem namespacing is certainly useful as a way to redirect filesystem interactions.
There are cool emergent properties from these three simple technical choices.
I’m not sure what the default path names for tcp or https are that programs expect. I didn’t bother writing that down
Many programs can be much simpler, and specialized knowledge and development effort can be encapsulated in a file system server rather than in a program or language-specific library. For example, a web browser or curl-like program doesn’t need to know the details of network protocols such as HTTP, SSL/TLS, FTP, etc, but rather it can use a file system server for each of them. Commands like grep can be used on web pages without knowing anything about the web, because each page can be accessed as a file. Rather than needing an SSL implementation (or FFI wrapper) in your programming language of choice, you can simply use network files brokered through an SSL file system.
Interesting case studies of programs leaning on the ability to provide a programmatic file system include the plumber program and the acme text editor.
The plumber is somewhat like a simpler, lighter-weight DBUS. Programs can send messages by calling the plumb program. Messages have various fields including a desired destination topic, free-form name/value pair attributes, and a text body. The plumber has a configuration file of rules that match details of those various fields, optionally enrich the message, and deliver it to a particular topic or handler program. It mounts a file system with a file for each topic, and programs can subscribe to messages about a certain topic by reading that file.
For example, a rule can match messages with the regexp ^.*.jpg$, then send that message to open the file in a default image viewer or programs subscribed to an image topic. A rule can match a message like SuperBeanFactorySingletonFactoryImpl.java:1234:5 to open the file in your editor of choice and put the cursor on the implicated line and column. Popular plan 9 programs have easy commands to send data to the plumber, such as by highlighting a URL with a cursor and clicking with a certain mouse button (Plan 9 expects 3 mouse buttons)
It’s likely that I’ll eventually integrate the plumber provided by Plan 9 From Userspace, the Unix port, into my workflow.
The ACME editor provides a filesystem that allows other programs to inspect and modify the editor state. For example, one file can be read to get the full file contents, and written to replace it. Another file allows users to write various commands, such as move the cursor or write the file to disk. There is an event file that allows a program to read the event stream and act when it sees relevant events, similar to emacs hooks. Using the ACME file system, users can write editing commands and “modes” using any programming language, including just shell scripts.
Now I’ll discuss some Plan 9 ideas that I think are not as good. Take all of this with a grain of salt, as I’ve never actually used Plan 9, I’ve only read about it and played with the Unix port of some of its tools, Plan 9 From Userspace. So some details could be quite wrong.
Plan 9 has some focus on being GUI-first, and does away with traditional terminal infrastructure. This isn’t necessarily bad, as the computer terminal tradition has a lot of cruft and nonsense. But as far as I’ve seen, they don’t really replace it with something better that fits the same niche, and instead emphasize that UIs should be GUIs and shake up some other details. In the end it’s a... mixed upgrade.
Remote X11 or VNC is terrible unless you have a very fast, reliable, low-latency, end-to-end connection between the two, whereas remote terminal sessions work pretty well over poor networks. Plan 9 is focused on networking, so maybe their GUIs work well over a remote connection. But I’m doubtful.
Another interesting detail is that Plan 9’s default shell, RC, has no notion of history. Instead, the (basically dumb) terminal window has a history of the window contents. Plan 9 advocates argue that of course each window should have its full history, and not be limited to each program keeping a history. There is something to that. However, to access a history of your shell commands you have to resort to parsing the full history of the window for snippets that look like shell prompts and commands. What about when another program prints something that matches the same pattern? The window doesn’t have any notion of which text comes from the shell itself and which text comes from commands. The shell, on the other hand, already knows what its output is, and be in a much better position to store rich, actionable data on the interaction history. Granted, in the common setup a shell would have access only to its own text, and NOT the text output by commands! The best design is perhaps somewhere in between – with the shell, terminal, and other programs working together to keep a full history in a structured format with rich metadata.
As far as I can tell, the Plan 9 terminal also has no color support, and some core Plan 9 people are against syntax highlighting. Crazy.
Also, core people on the Plan 9 team are very mouse-focused. Rob Pike, of Unix and Go fame as well as Plan 9, has famously quoted terrible research conclusions about the speed of using the mouse vs keyboard. This is a bit of a tangent for this post, but I want to note on the record how bad the research is. Others have discussed this, but beyond questions of how the experiments were performed, the experiments are clearly measuring the wrong thing and people extrapolate the wrong conclusion.
The study compares time spent using a mouse vs using arrow keys on a (presumably) standard keyboard, and finds that using the mouse is faster for the assigned tasks. Then many people go on to conclude (or at least imply) that using the mouse is faster than using the keyboard generally. But note that this study is comparing the very least efficient way to use the keyboard! The arrow keys move one character at a time, and you have to move your hand out of typing position to use them! The study doesn’t even come up to the level of comparing the mouse to vim-style hjkl movements, much less movement by word, sentence, paragraph, or semantic code units, searching, or using high-level programmed commands. I’d like to see a comparison of the time it takes to use the mouse to highlight a balanced s-expression in the middle of code vs the time it takes me to press literally one key in Emacs. And how often is the mouse selection just slightly wrong, whereas my key command is right every time?
My comparison is a little unfair, and I’m not against mice and pointing devices generally. There are times I use my trackball instead of typing, and times I swap my trackball for a mouse. Different tools are better or worse for different tasks (or subtasks, or variations on tasks, ...), and different people have different levels of expertise and enjoyment using different tools.
And I guess I’m just saying, “Please don’t write software that requires a mouse-centric workflow.”
All in good fun! Emacs is hardly the last word in text editing, even if it’s clearly the best choice today.
Plan 9 is often touted as an operating system that is “more Unix than Unix”. This is basically because it pushes harder on the idea that “everything is a file”, making the file system more flexible, more programmable, and more integrated into the way programs work. Other than these few details, Plan 9 basically embodies the same ideas (with their limitations and weaknesses) as Unix. It’s still ultimately a “worse is better” design, and is nowhere near the revolution you could imagine with a modern Lisp machine. But its three big technical ideas outlined here constitute a huge upgrade over traditional Unix, and I would love to see them embraced more by popular operating systems and software.
Nevermind how much I would also like to see the more revolutionary ideas from even earlier systems like Lisp Machines and Smalltalk Machines.
I’m always looking to understand interesting ideas in operating systems better. If I missed important ideas from Plan 9 or got things wrong, let me know. For example, I still haven’t gotten around to learning what SREs (structured regular expressions) from SAM and ACME are, but they sound like they might be a good idea I’ll want in Emacs some day. There are probably other things I didn’t notice or glossed over, as well.