Emacs Love Tale by sdp
emacs.love
emacs.love
Somehow this sentiment is anything but fun to me. Emacs is the last bastion of a different path down the tree of personal computing than the one our species took, one in which individual users are empowered and not - as is now the case - held hostage by us[0] in our ivory towers of impenetrable layers of cryptic technology.
Emacs was made for humans to use as a real tool. Barely anything else in the tech world really qualifies to the same degree. I'd love to peek into the parallel universe where we stuck to introspectable, malleable software and ended up with something closer to the Houyhnhnm computing stack[1]. Alas, for now that ship has sailed.
See also: That old story about Emacs at Amazon, etc.
[0]: "tech people"
Look for the heading labeled "Lisp" or just search for "Emacs" and you'll find the relevant bits :)
I believe this is the reference.
If Emacs was made for humans, why do so many humans get painful RSI trauma ("Emacs pinky") when they try to use it? How many humans can code in something as clunky as EmacsLISP?
Wouldn't hurt emacs to change the default keymap, just like it didn't hurt table saw manufacturers like SawStop or Bosch to include safety mechanisms, it helps.
Apart from some legacy warts, I find eLisp about a million times more elegant than mainstream languages.
Scheme would be even better, and hopefully one day emacs can transition to that.
Quick comparison to some other languages:
- vimscript: lol
- JavaScript: the lack of dynamic scoping may be tricky for extensibility, and not having macros is a shame (eg save-excursion and friends). But the language is mostly reasonable. One interesting aspect of elisp is that functions are typically just the symbols of their names, so it is easy to inspect and modify lists of hooks. I also worry about the pervasive use of modularity constructs like IIAFs—a great feature of elisp is the ability to poke and advise other code
- C or Rust: I think it is too hard to do something small or hacky in these languages and the constraints of type systems and manual memory management make ad-hoc extensibility hard.
I’ve also seen emacs (module) extensions written in a strongly typed functional language and they sort of work but can be fragile (eg advising a function but making incorrect assumptions about their types), or needing to use functions and closures for common operations like switching buffer or saving and restoring state. (It also amazes me that more languages don’t have unwind-protect and predictable evaluation order as standard, but that’s another topic)
(I know there was one black magic implementation of it for C# on Windows at some point and also similar black magic for Java, but that's as far as I've ever explored it other than in Emacs Lisp. (Black magic in this case refers to splicing in the advice in the compiled bytecode of the program.))
Edit: apparently there's some basic implementation for Perl, too, and it's documentation looks like a neat intro to the idea: https://metacpan.org/pod/Aspect
Monkey patching comes somewhat close. But lacks the communication of intent that is so clear with advice.
I'm not sure what you mean by this. The idea with aspect-oriented programming is that you can create a bundle of functionality that extends existing functionality but exists as its own separate bundle.
In other words, you specifically do not have to put the advice at the same place as the adviced. That would just be regular procedural/functional/objevt-oriented programming, wouldn't it?
Compared to elisp, where I can put advice around a function that is defined somewhere else, possibly out of my control.
This is indeed the idea of aspect-oriented programming. I'm not sure where you got a different idea. Could you point me that way?
That said, thinking on some of the tricks I'm ok with in tests, I guess it has to be possible. Not sure what the code looks like.
It is amusing, as even the annotation based stuff I've seen is near universally disliked by engineers with experience from it. Seems a very common foot gun, in practice.
{ option: true, __proto__: bar }.foo(…)
To extend bar.foo(…)
?(I think you are implying that functions would care about properties of this and that one would achieve “dynamic scoping” by modifying what this is.)
The first issue is that this doesn’t go deep in the stack. E.g. if you want to affect the option used by the foo function on a whole list of objects, it is hard. If you want to affect a call deeper in the stack that can be very hard (elisp example: some extension might want to switch to a buffer but you might want it to pop up the buffer or make some other windowing choice. The solution is that by dynamically binding certain variables around where this extension/function is called, you can make switch-to-buffer call display-buffer and you can override the way display-buffer behaves)
The second issue is that it is ugly.
Compare the elisp example of:
(let ((option t))
(bar-foo bar))
bar-foo can call baz which can call whizz which could then depend on the value of option.I prefer both control keys next to the space bar, then alt/meta, then super. I have a short spacebar and can do both control and alt with my thumbs. Others prefer an extra control where caps lock is. Others have special keyboards with thumb clusters. Some may use sticky modifiers. And there's even some people that actually like the "normal" layout(!).
Maybe they should use a different way of mapping keys if the default causes them trouble? Plenty of people do. Emacs has a very popular implementation of vi for example. It's up to the user, you don't need to accept somebody else's choice in this kind of software.
> How many humans can code in something as clunky as EmacsLISP?
People also code in JavaScript and somehow find that acceptable. Anything can be made to work. For what it's worth, elisp has pretty neat libraries and tooling these days (and due to things like magit breaking out UI components into reusable libraries writing interactive Emacs applications is becoming ever easier).
Hyper | Super | Meta | Control | Spacebar | Control | Meta | Super | Hyper
which was available when emacs keybindings were solidifying (they originated essentially as "hey, what do you people have configured?" poll around the lab/mailing list)Note that the modifier keys are mirrored, and Emacs' most used key (control) is closest to spacebar. Essentially, you weren't supposed to use control with your pinky while stretching your hand to hit another key - but to use opposite hand for modifier. Suddenly RSI is much less of an issue. Unfortunately not only order of keys on a modern keyboard is different (and often you lose some keys) a full 104 key has
Ctrl | Super | Alt/Meta | Spacebar | AltGr/Meta | Super | Hyper | Control)
which is noticeably non-mirrored, depending on one's language might also lose right Meta key, and for some reason you now commonly get PrtScr/SysRq in place of Hyper on laptop keyboards.No rebinding required, it works great and I don't even think about it.. no issues with RSI either.
On the other hand, I've never liked chording, so I use evil on emacs to make it more vim-like and avoid having to chord much.
No more Emacs pinky.
Elisp is just a product of its time (and Stallman's dogmatism). The lack of namespacing, lexical scoping (until recently) and first class concurrency really show its age. Nothing like the UI locking up because some function is blocking in the background.
I usually toss a few modern libs in there like dash, s, f, and cl, and it feels like any other modern lisp at that point.
To be honest, existing keyboard layouts are so bad that you have to remap a few keys anyway, whether you're an Emacs user or not. Tab and Capslock are gigantic for no reason, backspace is often too far away, Escape is also hard to reach and underused in many applications (or, worse, behaves in unpredictable ways), Enter keys are too small, and so on. As another example, my small 61 key keyboard has an extra large "\" key. Why? No idea.
I used emacs for 13 years. Then one day I switched to vim and never looked back. My RSI went away.
1/ Regarding the comments about remapping keys as the first thing people do: there are several issues with this. What if I am using a new machine? For example, every time I log into a new EC2 instance or a Cloud 9 environment I would need to do this remapping.
2/ I agree elisp hacking is fun. I prefer that over vimscript—but, evil mode just doesn’t really work in so many msall ways. For example, putting line numbers in the first column is non-trivial.
3/ Chording is unpleasant and I suspect a recipe for RSI if used in a full-time job situation.
As an evil mode user, I agree there are occasions where it isn’t present or doesn’t work, but I’ve generally added mappings for those cases or just memorized the emacs-style chords. What do you mean by putting line numbers in the first column btw? Like inserting the current line number at the start of each line?
Yeah, but, you know, using Emacs on a terminal that hasn't been produced since 1980 was ergonomic and it's a cardinal sin to change defaults, no matter how many generations of users pass.
This is especially ironic since supposedly all Emacs power users customize their setups, so they shouldn't have to worry about defaults changing, since they don't use them anyway, right? :-p
The common Emacs solution to this is to use your local Emacs to edit files on the remote machine, through TRAMP. That's not always available, but surprisingly often.
What about linum-mode?
What really changed things was the excellent IBM Selectric typewriter[1]. Every office seemed to adopt it. This typewriter influenced the future of keyboards, the digit 1 was given it own key distinct from lower case L and the ' and " were paired on a single key as were _ and - and it also moved the * key to shift 8. Soon every new typewriter seemed to be adopting the IBM Selectric's placement of the SHIFT-LOCK next to the 'A'.
This is obviously a mistake. SHIFT-LOCK doesn't have to be held down while typing other keys like the SHIFT keys does and it's use is not frequent so SHIFT-LOCK doesn't need to be on the home row next to the 'A'. In my opinion the CTRL key should be placed next to the A key. I was working as an operating system architect when IBM was building the first POWER-PC that was designed to run the new IBM Unix OS called AIX. I remember being in the meeting discussing the design of the AIX keyboard. I gave it my best shot, but I was unable to sway a majority and IBM made the decision to follow the Selectric typewriter and the IBM PC's keyboard layout.
> The original brilliant guys and gals here only allowed two languages in Amazon's hallowed source repository: C and Lisp.
There actual originals (i.e. when it was two people) only allowed C++. There was no Lisp, and no C, although the C++ was a fairly limited subset that was perhaps midway between C and "full C++94".
Then it compounds this error, makes another:
> they didn't allow C++ here, and they didn't allow Perl. (Or Java, for that matter). They knew better.
Numerous early Amazon utilities were written in Perl. I know because I wrote them.
Yegge is entitled to his various views on different languages. But revisionist history about the early development at Amazon is not OK, even when in defense of Emacs, a noble cause if ever there was one.
In my experience the "goofy things" you list are a minority use of emacs.
Most people are mostly in to things like org-mode or coding with emacs as their primary use. Of course emacs customization is very popular too, as if you don't want to customize your editor you might as well use something else.
By "magic" I really just mean having a super low barrier to having your code running and working in Emacs. You just open your config files, put in a line of code, and then you're done.
Of course there are other barriers - Emacs has a huge learning curve and Elisp is harder to learn if you aren't familiar with Lisp like languages.
Still, there are no other programs out there like Emacs. You always have to either create your own extension, modify the source code, etc.
Realizing that you could kinda just make whatever you'd like in Emacs is an amazing feeling. I don't even use Emacs as my primary editor at work and I still think about cool things I could hack in my config files.
It's hard to capture the qualities you mention without that. (Raise your hand if you can think of a system that did; I'd love to know.)
There's more to it than that, of course – the design is excellent – but convention matters, and elisp has a convention not seen in most other large-scale programming systems.
I also believe that none of the languages with module hierarchies are suitable for some kind of REPL driven development. You can't just dump all of your program into the REPL and expect it to work. You need globally unique names for these. And I believe this is a must for a language that is running inside an editor.
I'm not convinced that a lack of at least a flat set of namespaces (like CL) wouldn't be an improvement on Emacs' "prefix everything" approach. Perhaps more important to Emacs Lisp is that everything is open. If you took just something like CL's packages but had every symbol exported by default you'd get something that's not a far cry from Emacs' present approach but with better code organization capabilities.
One issue with Common Lisp style packages is that they may interfere with lazy loading. In emacs you can setq a symbol before the package loads and then the defvar will not change the value, but in CL you cannot read the symbol until the package is defined so things like eval-after-load (ie lazy load then configure) suck.
Emacs is the most organic feeling software I've used- it really feels like it has evolved like something in the natural world, with all sorts of warts and wrinkles. Kinda like a piece of DNA with large portions seemingly unused and occasionally dropped or upgraded, but at the end of the day it's all about functionality and adaptability. May it live forever
Most of the time it isn’t even necessary to restart emacs to do this.
I think I could have easily missed out on truly getting to learn a programmable and customizeable environment because IDEs and finished products in teaching were already pretty dominant at this point and it wasn't as much about tinkering any more and more utilitarian.
But Emacs really made me curious about reading documentation, tinkering with minor modes, doing simple things like writing my own status bar, and I think the great thing about it is that everything is in one place and interacts organically. The ability to introspect everything, change things on the fly, led me down a huge rabbit hole of reading about Smalltalk, papers from Licklider in the 60s about human-computer interaction, at some point later back to Pharo and a whole bunch of stuff I don't think I would have ever heard about in my CS education to be honest.
And all that aside it's still an incredibly useful piece of software practically. It's my editor of choice and people keep building new stuff for it. 'org-roam' is one of the better roam research alternatives out there I think and it's incredible to me how there's always someone who has ported some new thing to emacs.
My email client is VM, written in Emacs Lisp. I've used it to read mail for almost as long as I've used Emacs. Although I run Emacs in text-only mode, VM (and ancillary tools, like Personality Crisis and mairix)
* does a great of job displaying HTML messages. For the very few that it doesn't, one keystroke sends the message to my web browser.
* sends URLs I select (all from the keyboard) to the web browser
* opens images and attachments
* auto-adjusts the From: line of outgoing messages depending on the recipient
* archives messages to various folders using various criteria
* search my archived mail going back a quarter century at lightning speed
Of course, I can write Emacs Lisp code of my own to extend any or all of the above.
Admittedly the way I use it has changed, because things like LSP are a game changer for me, but it’s still been over 25 years.
As I said, VM (<https://www.nongnu.org/viewmail/>); 8.2.0b is recommended. Personality Crisis comes with it. Mairix (<https://github.com/vandry/mairix>) is separate and does not require VM.
After reading about the joy the author's partner experienced in using the notepad they built, and the reward they experienced watching them, I couldn't help but feel viscerally the pain expressed in those last words.
If you have never been on IRC before, you can quickly try it out via Libera Chat's web interface at https://web.libera.chat/#emacs. If you are worried about missing conversations when you log out but do not want to set up an IRC bouncer (the typical solution), there is a Matrix bridge to the IRC channel at https://app.element.io/#/room/#emacs:libera.chat that you can use to stay connected even after you turn off your computer.
I have never done "chording". What is that?
I don't need an editor with more than about 100 function keys (CRTL-[a-z], CTRL-[A-Z], ESC-[a-z], ESC-[A-Z]).
I absolutely hate 'info' and in the age of manpages and webpages it is an embarrassment to emacs.
I absolutely love ESC-j (fill-region) for squeezing text into 77 columns, and ESC-x indent-region for unifying my coding style. Modern shells understand at least 20 emacs key-bindings (CTRL-e, CTRL-a, CTRL-k, CTRL-b, CTRL-f, CTRL-d, etc.) and so does the Chrome browser, apparently.
Mostly these days I am turning off modes written by pedants who want to 'force' me to do things I don't want to do. ESC-x text-mode works just fine for that.
In the early 2000s I used emacs while writing C++, I was writing Lisp macros without any idea what I was doing just purely so I could avoid using one of the bloated Motif IDEs[1] or vanilla `vi` on SPARC boxes. No vim here, thanks, and the nice IT folks at the investment bank didn't permit you to install your own software, so emacs was a fantastic end-run around their rules. We used `pine` for email because somebody had done the leg work to get it working with the corporate Lotus Notes servers, but I got email working in emacs too. Somehow. Having to actually use your windows box was either a sign of weakness or an encounter with insurmountable corporate policy. Anyway, it never occurred to me to customize the emacs key bindings. At that stage in my career I assumed some godlike personage had chosen those key bindings for a reason, and I had better just go with the flow.
Then I left emacs behind for too many years, but rediscovered it through spacemacs, which let me put off learning what I was actually doing for a few years more. Then on to doom emacs because it would make it "faster", then I finally had my epiphany and realized I would have to do this myself. Emacs of all things should not be slow, there is no excuse for it to be slow on these supercomputers we take for granted. So my config is now tangled from an org mode file to keep it nice and organized. When I add a new thing and it becomes slow, I stop immediately and figure out why. And I kind of stick to the original emacs keybindings where possible.
I have no idea what people are complaining about when it comes to RSI. My only non-negotiable change is to reassign (at the OS level) caps lock to control, simply because ctrl is such a small target on most keyboards, which are apparently made for FOLKS WHO NEED ALL CAPS way more than you or I use ctrl. Scary thought. I would argue RSI is going to come from the R part: repetitive. You spend most of your time, even when coding, just typing strings over and over. Likely the RSI suffers never learned to touch type and so the real strain comes from well established bad habits. Try using an Ergodox-EZ ortholinear split keyboard, you'll soon learn whether you're truly touch typing or not. I can't see how emacs shortcuts would be the source of pain. Maybe if you're typing on a 2000-era Sony Vaio or Nokia handset and never learned to touch type? Reminder: old curmudgeon talking here, I may have just got lucky.
If you like emacs keybindings and happen to be using macOS (which out of the box in most text fields supports the basic emacs key bindings anyway), a kind soul has put together a KeyBindings.dict that extends support even further: https://gist.github.com/cheapRoc/9670905
Mentoring newer engineers, it's remarkable how many of them are at the terminal holding down the backspace key, waiting for individual characters to be deleted over long seconds. The idea of using option-b or ctrl-a to move backwards blows their mind. Ctrl-k to delete everything forward of point is also revelatory. It's curious that they get stuck in this rut, totally dependent on the shell day to day, but wholly accepting of these inefficiencies. Yet their forebears - who actually wrote and hacked on these shells, if anything went overboard giving you ways to do everything they could conceive of with the bare minimum of keystrokes. How many of them know you can hit ESC-t to transpose the two previous words in bash? (M-t in emacs for the same).
I'm tempted to blame the children but honesty if you give a child a claw hammer and they point at the end with the V shaped prongs and say "what is that for?" you will explain it to them, or they will eventually figure it out. Maybe its purpose will never occur to them, but it's a rare user of hammers who has driven nails but never encountered the need to reverse that operation. How exactly do we design software such that someone notices the existence of option-b and how much time it could save them?
Maybe it's all the fault of the mouse? Better yet: Windows and the mouse!
[1] I'm sure you can empathize with a feeling of horror that once upon a time, Motif felt bloated and slow. Perhaps we are doomed to always be at war with slow abstractions, independent of the hardware capabilities.
Oh no! Did she pass away?
this is fundamental to me, it's things like this that make me use linux and prefer KDE, but the way he talks about this (along other comments in this discussion and generalized software trends) has got me worried that this level of customization (and its associated mindset) are an 'endangered species' even among software engineers.