Emacs is a monument (just like Potala palace in Lhasa) of an old-school software engineering and classic languages – it is, indeed, a world heritage site of the golden age of programming.

It also could be compared with the ghat complex of Varanasi, which began no one knows when and is constantly changing since then, being reshaped by the “waves” and “tides” of social dynamics.

Visiting Emacs is like visiting one of such historic sites, and just like them, it has been re-shaped by the successions of mass-hysteria and zealous over-excitement about bullshit.

Nowadays the current mass hysteria is about threads and some ad-hoc library-based async stuff.

Adding an ad-hoc concurrency to an imperative language will always be a failure in principle, and the Ocaml guys went through all the pains of designing a principled algebraic effects based runtime for a reason – an imperative code and concurrency simply do not match (thank you, Joe) .

One at least could embrace the principled approach of Clojure, and rely on actually immutable and persistent (a balanced tree-based) data structures (straightforwardly shared and garbage-collected). Yes, yes I know.

Anyway, coming (partially) from MIT CSAIL it has been based on the right priciples and incorporates (realizes and manifests) some “big ideas” and universal notions.

It is a set of layered DSLs written in a dynamically typed LISP-2, which is in rurn implemented in (an imperative and unsafe) C, Just like TeX, by the way.

Emacs is a truly dynamic system (everything could be changed at runtime, even a new procedures could be created) similar to Smalltalk, which is almost an ideal in this respect.

It is just a single-executable software Lisp Machine or stripped down the Genera operating system (well, almost), and one can really see and feel it. Here is how.

In your Emacs install the showkey package, something like (straight-use-package showkey) in a very modern tooling DSL, for the sake of a quick example. Then run M-x showkey-log-mode, which will create a new frame with a log of all the keys you would press.

Notice, by pressing literally any keys and combinations you already know, that each one invokes a particular LISP procedure. One more time – every keystroke invokes some procedure with appropriate arguments. It is indeed an intepreter of the “language” (code sequences) that come from the keyboard. So it is a software LISP Machine, indeed.

This, by the way, is why and how exactly the keyboard macros (very different feature from the LISP macros) are possible - one records the keystrokes, which have a direct one-to-one correspondence with the “procedures”, which have been bound to them. Just like pressing on piano keys produces corresponding “notes” (tones), pressing on keys in Emacs produces corresponding imperative procedure calls.

So, one just records the sequence of the keys, directly translate it into a sequence of procedure calls, give it a name, and then evaluates it at once, or this many times (actually transforming the buffer as it goes).

The key to the “a-ha momnet” is that all the “motion keystrokes” also have direct mapping to LISP procedures. To move a cursor is to actually call a procedure (M-f is bound to the forward-word procedure, and so on). There are a few pages (screens) of key-bindings, which can be seen by pressing Ctrl-h b at any time.

Notice how simple eveything is when you understand the principles and that the principles are just right and application of them is uniform (uniformity is a big deal).

Emacs is, indeed, an actual manifestation of the power of symbolic manipulation, at both code and data levels – the original principle of homoiconicity (everything is of the same a LIST structure made out of conses, both LISP expressions and the data). This principle gives a subtle Monoid property for all the combinator procedures, which is the actual cause behind the expressiveness of the original LISP.

There is a lot going on in this locus of symbolic computation and the layers upon layers of DLSs embedded in LISP. The number of “packages” is already in thousands.

To really understand and appreciate what one sees requires a lot of the right knowledge, but then everything is “clicks” and falls into its places.

It has been noticed at the times of the early LISPs that linear, tree-like and lookup-table-like data structures are enought for everything. The inspirations came from the recent discovery of the DNA structure and the resulting hype and excitement. It seems that biology also uses (the “blind” process of biological evolution at the level of molecular biology “discovered”) these fundamental “structures”.

And, behold, all these could be made out of CONS’ses, where an associative list (a list of pairs, which are “improper conses”), is a “minimal” and essential lookup table (with a linear time complexity).

Notice that a “lookup table” as just a sequence of ordered pairs could represent an “environment”, a " hierarchical namespace", a module, a whole library of modules. All these and almost everything of this “rectangular shape” is a specialization of a “lookup table abstraction”, or of a function abstraction (on a finite domain).

Yes, it is absolutely OK to bind a procedure (its actual body) to a symbol (which is exactly what the (define square (lambda (x) (* x x))) special form (in Scheme) does. The symbol, in turn, could be a part of (bound in) any LISP data structure whatsoever (due to type-tagging of values and dynamic typing in general). Each value uniformly carries its type-tag, so its type is always known at runtime and no other decorations are necessary.

So, by nesting and dynamically binding these “lookup tables”, which could hold any LISP data including procedures to trees and plain old lists, one builds a dynamic environment, which consist of nested individual “frames” (according to agreed upon specifications, rules such as “shadowing” of symbols, and standardized interfaces). Something very similar is happening in modern Python.

It can never be over-emphasized, that Lists and other fundamental Abstract Data Types (trees, lookup tables, queues) are enough to implement a universal machine - an intepreter of a language with the Environment Model of evaluation (which as extruded Substitution Model).

This result was so excited and fundamental that MIT used to teach most of its CS courses (in Scheme) about these ideas, principles and their actual implementations. They even build a tiny (but done just right) Emacs-like editor, called /Edwin, which is included in the MIT Scheme distribution.

The last classic course of this great lineage (the MIT Scheme tradition) is the 2004 6.001 SICP Scheme course by Eric Grimson et all. The last book is Software Design for Flexibility by Sussman, the wizard.

In a dynamically but strongly typed language (with runtime checks) all these structured values could not just be arbitrary /nested (due to the fact that everything is an expression and that everything is homoiconous (of the same CONSes), but also created on-demand and modified (re-bound) at runtime.

These are the “fundamental building blocks” of Emacs - the fundamental data structures and at a higher level the hierarchical layered DSLs embedded in LISP.

The first old implementations were simple-enough to be hacked toghether by just a few people in their spare time (/excactly due to the right principles,fundamentals and “natural” proper design decisions).

Agian, it is not about the gory details of how exactly it is implemented, but how the architecture, modularity and the embedded language ()for writing DSLs and packages) has been done just right.

The implementation side is actually ugly – imperative, mutable, destructively in-place updated and with the “clever” C (that no one really fully understood) under the hood.

No serious attempts has been taken to write a Clojure-like immutable and persistent “stdlib” as the shared Basis for all the modules, just as the SML guys did with their Basis Library or the Erlang guys did with their OTP.

What is worse, people do not bother to understand the principles and the proper idioms and write low-effort crap with unnecessary bloated dependecies and inappropriate. They just write as they used in that other language they know, like degens write Haskell as if it is J2EE with monad “wrapers”.

The key to write good Emacs Lisp is to understand the DSLs already presented at each level of abstraction, and to use the proper idioms appropriate for each layer. One would be surprised how little code one has to write – almost everything is already in the library. This is why some modules are just a few lines, but just the right ones – as intended.

The big, classic ideas, however, cannot be marred by the dirty impure imperative low-effort stuff. The fact that LISP is a “very-high-level” and even “programmable” programming language – one could define one’s own control structures and even special forms (using macros) – outweights all other concerns. Hierarchical layers of embedded DSLs is a “universal architecture”.

The causes of the miracle (of classic software engineering) and the greatness of the monument are exactly these listed above, and they have to be realized and fully understood, including the Monoid part (over CONSses).

From the perspective of a merely user of the system (it is by no means an editor, rather it is a single-binary Lisp OS, (just like Chomium nowadays, by the way).

So, when you open your Emacs next time just slow down and simply esplore it, wander around and appreciate, as one would in some historic world-heritage site. Most of the details matter and most of the decisions were right. Of course, it is littered with modern junk, with bullshit painted on the walls, etc.

There is a lot more to Emacs. Most notably, people like Sacha Chua (google her) and (to lesser extent) Xah Lee. Mike Zamansky is also worth mentioning for his youtube series.

https://www.youtube.com/playlist?list=PL9KxKa8NpFxIcNQa9js7dQQIHc81b0-Xg

There are quiet autistic (it is ok, we are the best by far) programmers who slowly and carefully write (or wrote in the past) wonderful packages, some of which are now abandoned (nXHTML, Icicles, vdiff, etc).

It seems that Emacs requires (or at least could be easily aligned to) some particular mindset, which can be found at places like MIT CSAIL or Bell Labs or any other quiet place where quiet people slowly and carefully crafting something (almost instinct due to modern management bullshit).

And it is not some modern fancy stuff like Doom Emacs that is worth “worshiping” or at least approach with a religious awe (as one feel inside a great cathedral), but what lead to it, what made it possible, and the principles and big ideas of which Emacs is a manifestation.

Lots of pages has been written about the unique “nature” of Emacs.

  • self-documenting (people of the golden age knew and applied the right principles)
  • everything is discoverable (every binding and every command can be discovered)
  • truly extensible (dynamical typed LISP2 with embedded Common Lisp and macros)
  • keyboard macros (it is a software Lisp Machine, after all)
  • Lisp Macros (the way to define your own special forms)
  • Declarative embedded DSLs (what makes Emacs what it is)

One could read other guys on the internet about the details and particulars. I am MIT-style principle-loving guy.

Just one more important thing. Emacs is wast, and one does not have to memorize it all (which is an impossible and ultimately futile task anyway). On the contrary, one has to learn how to discover, master, customize and extend the exact features one needs – this is the true “philosophy” of Emacs.

To do that one has to understand what he (or she) is doing (and why). From understanding a workflow naturally emerges, and it has to be described informally or even formalized. From an informal description a cheat-sheet of commands and corresponding key-binding can be distilled.

When one discovers that some keys binding are inconvenient or inconsistent with the traditional conventions, then (and only then) one have to change the binding. Consistency and elegance are not optional.

One has strongly resist the stupidity of re-binding all the keys in some non-emacs fashion, and the sheer madness of trying to turn Emacs into Vim. With more than 40 years of continuous refinement, Emacs evolved proper notions of how key bindings shall be organized, and this is about shallow hierarchies (trees) of mnemonic sequences, like C-x p ?. Do not replace an evolved optimum with a low-effort meme-crap.