Emacs versus Acme
The similarities between Emacs and Acme ( Acme was created as the premier visual text editing environment for the Plan 9 research operating system at Bell Labs) are fascinating case in multiple discovery not unlike both Liebnez and Newton independently discovering calculus: both have the otherwise very unique property of being most commonly used as text editors, but under the hood actually being malleable, programmable, text-oriented computing environments designed not just for reading and editing text but also managing the filesystem and external processes and the interactions and composition between them, all within a unified window management and user interface paradigm.
While this fact is not part of the official marketing of Emacs, it is commonly known among the community. As Irreal, a pillar of the Emacs community, states:
It is […] a Lisp interpreter specialized for dealing with text that has an editor as one of its built-in applications. […] I prefer to think of Emacs as a light-weight Lisp machine suitable for many tasks. […] Regardless of original intentions, Emacs today certainly embodies the notion of being “an extensible environment with text editing as a feature.” But it’s even more. At least for many of us.
Meanwhile, this fact is expliclitly part of the core intenton of Acme. Just look at Rob Pike's original paper on Acme, where it says:
A hybrid of window system, shell, and editor, Acme gives text-oriented applications a clean, expressive, and consistent style of interaction. Traditional window systems support interactive client programs and offer libraries of pre-defined operations such as pop-up menus and buttons to promote a consistent user interface among the clients.
Also not unlike that simultaneous discovery, one of the inventions was clearly superior to the other and went on to have a much longer history, and the other quickly died out and is mostly only of historical interest. Consequently, a lot can be learned from their differing philosophies in how they approached this common idea. I'll briefly take a look.
First, since I don't feel like into detail explaining precisely how Acme works, because I feel like that would distract me even more from the point of this section than I already have been over the last several minutes writing it, I recommend reading this post to familiarize yourself with the basic concepts before moving on.
Now, on to the meat of my critique:
- Acme tries to use the mouse for as much as possible. While this is extremely interesting, and some will defend Acme's use of the mouse till their dying day, I think this is an unsuccessful experiment. The use of mouse button chording does expand the bit rate of mouseing input somewhat (by exactly three bits!) but not by enough to make a significant dent in the vast chasm between the information throughput of a keyboard and a mouse, and it doesn't begin to address any of the other problems the mouse has in comparison to the keyboard – most devistatingly of all for a text-focused application being the need to constantly move one hand back and forth between the keyboard and the mouse when switching between editing/navigation and entering content.
- Despite provideing a very malleable interface in the form of its tag lines, which you can put any commonly used commands you want access to in, and the fact that its text windows are live text stream devices so it's easy to embed anything that can operate over a TTY in them, and a deeply programmable environment through point (3) below, Rob Pike had very specific user interface design ideas, and decided to skip out on UI programmability and malleability in favor of enforcing them. For instance, he made the intentional choice not to support syntax highlighting or changing the color scheme. Judging by that approach I deem it unlikely Acme would have eventually come to support any of the modern display and fontification features which enrich our experience of Emacs today, either. This may seem like a minor point, but it's rather fundamental: while Emacs seeks to extend its display capabilities as much as possible while maintaining consistency, composability, and reflectability by ensuring a basis in a common set of underlying systems (text propertized with structured data), Acme seeks to maintain consistency, composability, and reflectability of its interfaces through outright hard-capping the capabilities of its interface entirely. This may be part of why Acme died: its inability to adapt to new capabilities and new knowledge (such as the fact that syntax highlighting is actually very beneficial).
-
Instead of having a language built into it that lets you program it, and using that language to import and control external programs, as Emacs does, Acme instead exposes a simple command language and the event logs, text content, and so on of each of its windows as filesystem devices so that separate processes can read from and write to those devices in order to control it via pure text streams. This means that nothing fundamental about the editor can be modified or changed this way, so the editor must be as minimal as possible, carrying as few features as it can, in order to outsource the rest to more changeable programs. The problem with this is that:
- Since these are entirely separate processes communicating over raw text streams with Acme, there is no way for these programs to fundamentally modify any of Acme's core functionality or concepts. Everything must be implemented in terms of Acme's necessarily excruciatingly limited set of concepts and user interfaces, which means that more complex functionality such as better display capabilities (as mentioned above), changes to how the window layout works such as autocompletion and documentation popups, modifications to how input is processed at a fundamental level like transient menus or hydras or text based UIs like magit, are all nearly impossible.
- While a feature can be made available to the user through a shell command that runs a process which can communicate with Acme, since all these processes are launched by the user completely individually, they have no way of knowing about each other, let alone meaningfully sharing information about their current internal state and provided functionality.
- Furthermore, if a feature is added to Acme by way of an external process, due to the previous point, other processes still won't be able to know about it or use it in any robust way that isn't extremely brittle, like asking the user to list what commands for Acme they have available manually in a text file somewhere.
- As a result, Acme's extensibility and thus longevity is fundamentally hamstrung: imagine trying to replace some core user interface concept in Acme with something better, like Helm or Vertico do with Emacs's built in completion system, or hook into all possible completion interfaces across the whole program to add more annotations useful to the user, as Marginalia does.
- Having to use the shell to program Acme exposes the user to all of the flaws of the UNIX environment, full bore, like a fire hose. An Acme user will have their fill of a cryptic, underpowered, gotcha-filled shell language that requires you to awkwardly compose together programs that all format their data in completely different ways using dumb text-munging via esoteric commands with even more esoteric arguments. Ever wanted to have to run
xargsor figure out the pattern language offindor write AWK scripts or figure out whatever the helltrdoes in order to use basic functionality in your editor? Then you'll enjoy Acme. Then there's the added insult to injury that these commands are somewhat unergonomic to run from the editor since, unlike with a Lisp, the borders of any given expression are not clear in a shell language, so the whole shell expression must be selected before it can be run each time.
I think the differences between Acme and Emacs are the perfect case study in the differences between the UNIX philosophy and the Lisp Machine approach to computing systems. And I think it's telling that one survived the death of its host system and has continued to be used for 40 years, and the other did not and has not.