56

Tikhon Jelvis's answer to Does Emacs violate the UNIX philosophy of doi...

 6 years ago
source link: https://www.quora.com/Does-Emacs-violate-the-UNIX-philosophy-of-doing-one-thing-very-well/answer/Tikhon-Jelvis
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Tikhon Jelvis's answer to Does Emacs violate the UNIX philosophy of doing one thing very well?

using and hacking on Emacs since high schoolAuthor has 1.8K answers and 14.7M answer views4y

Yes, gleefully. It’s all the better for it.

Emacs achieves the same goals as the Unix philosophy but in a distinct, fundamentally Lispy way. The goal of the Unix philosophy is to encourage modular systems made up of simple components. While it might not look that way to the uninitiated bystander, Emacs is incredibly modular—modular in a significantly more granular way than Unix itself. Emacs is a system and an environment just like Unix, and its components—major modes, minor modes, interactive functions and so on—do follow the same precepts: they do one thing and they do it well.

It all comes down to Emacs’s heritage as a living realization of the Lisp machine dream. Emacs derives its modularity from the right place: it is modular at a language level. Emacs’s components can share abstractions and communicate in an inherently structured fashion. Components can talk about abstract things—buffers, processes, files, formatted text, functions—directly. As a sharp contrast, the Unix way only lets us talk in representations of things, usually as text! Comparatively, the Emacs approach is rich, direct and surprisingly simple with no awkward and error-prone serialization/deserialization steps.

This, by the way, is what makes Emacs special compared to other editors. I may question Emacs Lisp from a language design point of view, but I love how well-integrated Emacs-the-system is with Emacs-the-language. Other environments have APIs for controlling them from a language; in Emacs, the environment is the language. Every single command you can run in Emacs is a function in Emacs Lisp; you can always ask what function a keybinding calls and everything is malleable. UI elements? Just text you can’t edit. I’ve used newer systems that try to do something similar—Eclipse comes to mind—but they all fall short; I’ve never found anything as simple, uniform and powerful as Emacs and Emacs Lisp.

Some of you may be thinking that, if Emacs is made up of modular components, it actually adheres to the Unix philosopy. It doesn’t. Emacs’s approach does “violate” the Unix philosophy because the Unix philosophy has baggage beyond “do one thing and do it well”. If that’s all it was, it wouldn’t be very interesting—everyone and their dog loves modularity. No, the Unix philosophy is all about doing modularity in a very specific way, one I’m not overly fond of.

Here’s a cogent summary of the philosophy by Peter H. Salus (retrived from Wikipedia):

  • Write programs that do one thing and do it well.
  • Write programs to work together.
  • Write programs to handle text streams, because that is a universal interface.

Note its two core conceits: modularity is achieved by programs communicating via text streams. This is not the only way to achieve modularity and, I posit, it isn’t even a good way.

One problem is that programs are conceptually complicated, heavyweight black boxes—not what you’d want from the atomic primitive of your system! Programs have their own memory, carry a lot of system metadata, get a lot of different inputs (arguments, an external environment, signals…) and multiple outputs (at least STDOUT and STDERR): a lot of extra complexity compared to, say, just a function.

Programs are also opaque. Unix programs take arguments and return values—entirely by convention. And you know what happens with conventions? People don’t follow them. This is why there are two or three distinct styles of command-line arguments in the Unix world, not counting individual programs that do their own thing for no good reason. This is insane! If you designed a language where functions needed to be called in one of three different ways because you didn’t think to build a way to pass arguments in your language, people would rightfully discard it in disgust. Yet this is exactly the state of the Unix world with Bash as its glue.

To top it off, programs communicate in text which is inherently limited and unstructured. This isn’t even dynamic typing, it’s “everything is a stream of bytes” typing. Of course, real programs deal with structured data all the time, so what do we get? More structure-by-convention, with all its faults. Some programs operate by line, others split things by tabs, and yet others rely on significantly more complex text-based formats. Luckily we can always just glue things together with liberal applications of text munging programs and regular expressions.

Let’s put it this way: most Unix components don’t do one thing, they do three: parsing an ad hoc text format, their actual logic and serializing to some other ad hoc text format.

Does that sound like a reasonable way to build solid software?

Emacs, on the other hand, achieves modularity with Lisp functions communicated through structured Lisp data. Now, honestly, I think Lisp doesn’t do the best job with structured data either—it’s a bit too reductive, trying to do everything with little more than atoms, lists and functions. (I would obviously prefer the rich structure of Haskell!)

But it is miles ahead of the morass that is Unix programming!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK