The “use emacs” prerequisite that shows up frequently when exploring Lisps has been such a dealbreaker for me in the past. I have no patience for learning “chords” or even using a non-modal-but-still-not-just-normal-input editor simply to explore a language. My impression being that these chords morph depending on “modes” doesn’t help at all. At least with vim you can learn a piece at a time (sorry, not trying to revive last century’s favorite flame war, but it’s true).
Also: no one has managed to explain to me what makes emacs so uniquely capable of interacting with a running interpreter, despite this usually being the USP I hear for “needing” emacs when attempting to Lisp.
> Also: no one has managed to explain to me what makes emacs so uniquely capable of interacting with a running interpreter, despite this usually being the USP I hear for “needing” emacs when attempting to Lisp.
As an Emacs user that has to work in teams of non-Emacs users, the answer to this boils down to culture and ecosystem maturity.
Purely technically, there's nothing that Emacs allows me to do with REPL Driven Development that _couldn't _ be done in another editor. Practically? I still haven't been able to even get (sufficiently) started with any editor.
I often have to work on a Rails codebase that takes tens of seconds just to start. Dev cycles in the traditional Edit-Restart flow were so painful that I wished badly to burn this codebase down and rewrite it all in a language and style that supports a Lisp-style REPL. Then I discovered inf-ruby.el in Emacs. It allows me to just edit the code and reload only what's changed. It automatically inserts the correct `module Xyz; ...; end` etc. No more restarts.
I showed it to my coworkers. They shared the pain with restarts. And yet, to this day, none of them have an equivalent to inf-ruby in their editors.
inf-ruby.el is less than 1400 lines of code. It's easy enough to implement in Vim, IntelliJ, VS Code, anything really. But it exists only in Emacs, so far. Why? I'm sure because some Emacs user, once upon a time, wished similarly to have a more Lispy REPL for their Ruby dev work, and just built it. Because they were used to it, from having used Emacs or other Lisps with Emacs.
Compare that to when I first tried to support Common Lisp development on VS Code. A language that already has full support for REPL Driven Development with an interactive debugger built-in. Nope, we aren't gonna use any of that, because in VS Code land, we use LSP. A model that really only works for languages that can be statically analyzed. You want Go To Definition on a method that's included from a module and called on a receiver that's a dynamic variable? Well, sucks to be you, I guess.
So, while people make do with the severe limitations of Solargraph or Ruby-LSP, I use robe.el — which adds lisp style code intelligence by running inside your Ruby process — and get code intelligence that actually works with a language as dynamic as Ruby. Again, robe.el was just there for me to use. Again, there's nothing about Emacs that makes robe.el possible in Emacs but not in other editors. Again, there's no equivalent to it (that I've found) in the ecosystems of other editors.
This is honestly fascinating stuff, so thank you for sharing!
I wonder if it is an exposure issue: only those who use emacs know it is possible and those who know emacs have little incentive to leave their editor-OS.
I guess I’ll have to dig into some of these examples you have shared and see if I can comprehend and/or relocate their magic.
Emacs is weird; some people "get it," some, even after using it for years, just never do. The thing "to get" about Emacs is a knack for quickly automating things. Those with shallow exposure to Emacs think that Emacs users are doomed to tinker with their configs all the time. In reality, that's not entirely accurate. I can share so many fascinating, practical examples where I needed to get something done on my computer, and Emacs either already had all the pieces required or provided me with facilities to build upon.
Exhibit A: One day, while taking notes and having to jump between multiple web pages in my browser, I got irritated by having to jump to the browser, finding the tab, going back to my editor, etc. I wrote a function that lets me control my browser tabs directly from Emacs. Why? Because it's convenient, and because it wasn't that hard to make.
Exhibit B: Few days ago, my colleague was showing me something over Zoom. I didn't want to derail his train of thought, I didn't want to keep interrupting him with: "hey, wait, don't scroll away just yet", "can you share that link with me?", "whoa, hold on a second, I need to write that down", etc. Over the lunch break I decided to solve this problem for myself. I use Flameshot. I checked if there are any plugins for it. Turns out there's an open GH Issue, that's all. So, I wrote a command that checks ~/Desktop folder - that's where my screenshots get dropped, then finds the last .png (if it's created less than 2 mins ago, otherwise prompts for a file), sends it to tesseract (a tool, the existence of which I haven't heard until that moment), then opens the OCRed text in a buffer. Now I can quickly select any area on my screen and retrieve text from it with a single keystroke.
Exhibit C: I use Google Translate directly from Emacs. Which by itself is nothing out of the ordinary. Pretty much every other editor has some kind of plugin for that shit. I was reading articles in a foreign language I'm learning, sending pieces to get translated - again, nothing new here. However, it doesn't translate numbers, and that's normal and totally expected. Yet, I wanted to see numbers in their written form. What did I do? I found the function it calls before sending text to GTranslate API, and using advising mechanism, wrote a function that right before sending a request, searches for numbers in the original text and turns them into written form, and then sends that for translation. Advising feature is extremely powerful and it doesn't exist in any other editor beside maybe Lem - neither VSCode, nor Vim, nor IntelliJ, nor Sublime has that stuff. Did I have to look up GTranslate API docs? Nope. Did I really need to sift through the Emacs google-translate package code? Not really. I just needed to find the function responsible and needed to know its signature. Took me less than 15 minutes and fewer than 30 lines of code, most of which is my comments explaining the hack. I couldn't even find a generic Elisp function to translate numbers to words, I just used some npm package for that.
I can tell you many stories like that: the million reasons why I can't ever abandon Emacs and why I love it. I don't care that traditionalists using IDEs think I'm delusional, I've seen that world - it has its perks but also limitations. My world of Emacs not without its own drawbacks yet it allows me to hack some stupid shit almost effortlessly. I guess tis ain't that stupid if thy shit actually works, eh?
As the guy building jank, I agree with you about emacs, chords, etc. I'm a vimmer and I can tell you that Clojure is superb in Vim land (Conjure), VS Code land (Calva), Emacs land (??? some major mode), and IntelliJ land (Cursive).
realistically, it's the REPL, not the editor, that makes lisp what it is - not just having a repl running, but to have your app be part of the repl, and you develop it bit by bit.
The javascript/UI people have found live reloading/editing to be a game changer, but this has been the case for lisp development since...well, the beginning!
Live reloading (recompiling per method, editing values in your live runtime image) has been with UI development since since the beginning of GUIs. Smalltalk is great.
The 90s with C++ and Java broke with history. Thankfully the rise of web apps has given us iteration speed back!
Visual Age for C++ inherited the Smalltalk experience, alongside Energize C++,provided a similar experience, but were too expensive for early 1990's hardware and too resource hungry.
Live++ brought the experience back to game developers.
Java has supported partial live reloading since early days, and for those willing to pay for it, JRebel takes the experience further, back to Lisp/Smalltalk.
Since I’ve got you here, can I ask you for your thoughts on LispE and how it contrasts with jank’s approach? It seems clear that they both arrive from different lineages of the Lisp kingdom. LispE is also found dangling a few toes at depth within the icy waters of array programming.
Perhaps the only connection between the two is that the one makes me think of the other. But if there’s more, though, I’d love to read about it.
This is the first I've seen of LispE, so not a very informed opinion.
Different lineages, for sure. Clojure really stands on its own in the lisp world and some die-hard lispers claim that it's not a lisp at all. However, for Clojure devs, I think we generally aren't interested in using the other lisps in practice, for building practical software. We just appreciate them for their lispiness. So the main difference will be that LispE is more like CL than like Clojure.
Aside from that, LispE is interpreted, whereas jank is JIT compiled with full AOT compilation support, using LLVM. By using Clang/LLVM, jank also has full access to C++ interop, whereas most interpreted lisps are sandboxes on their own.
I'm not familiar with this side of traditional lisps very much. Someone may be able to jump in to embellish or correct.
The proper answer for Lisps should be use Allegro or LispWorks, which actually provide a full blown environment as Lisp environments of by gone eras.
Does vim display inline graphics in a repl, with editing capabilities?
This is one of the basic features of classical graphical Lisp environments from the 1980's, IPython and Jupyter notebooks, or better, Mathematica are only building upon this.
Emacs and vim are not quite at the same experience level.
Being a bit clunky is not really working, and I bet it doesn't do the full extent the other Lisp environments allow, including code reloading, jumping into the debugger from the REPL, redrawing everything being shown in the REPL after returning from the debugger with the new code changes applied.
Emacs is easily programmable (and in lisp), more unixy than modern Linux, like a whole operating system. Lispers make tools for it because it's very easy for them. Lisp tools have been far advanced of others; LSP wasn't initially adopted in Lisp communities because better tools (swank) were already around.
> LSP wasn't initially adopted in Lisp communities
LSP and Treesitter were embraced if not shortly, at least eventually. Lispers are well-known, almost notoriously, for "stealing" good ideas from other places - Clojure's transducers, core.async, STM, refs and atoms, core.logic; Common Lisp's condition system, multi-dispatch in CLOS, SBCL's compiler notes, SLIME's debugger - ideas for all these things originated somewhere else.
> The “use emacs” prerequisite that shows up frequently when exploring Lisps has been such a dealbreaker for me in the past
It's not a "prerequisite" per-se, although I guess you just never stumbled upon the fundamental truth about Emacs. In fact, it's not just an ordinary editor, it's a "Lisp Machine". Of course Emacs is far from the actual implementation of a Lisp machine, therefore the quotes.
Emacs feels like a Lisp REPL with a built-in editor, and not the other way around. Once you immerse yourself into the world of Lisp, sooner or later you will realize - Emacs is far from the ideal implementation of a Lisp machine, yet it's the best practical one we have today.
Chords, shmords, modes, modality, non-modality, keymaps, keybindings, etc. - that all is just "higher-level interface" you can change to your liking. I consider myself a die-hard Vimmer, never ever thought about switching to Emacs, until one day I woke up with realization that Emacs actually vims better than Vim and Neovim.
There's something "magical" about Lisp - coders either love it or hate it with passion, but anyone who accepts it, with all its flaws and powerful features, those who embrace the dynamism, the malleability of the structure - they may open a beautiful world of countless fascinating ideas. And once someone opens their heart to Lisp, either with sadness or with joy they sooner or later realize - Emacs is just the best practical tool to work with Lisp, there's simply nothing better. Even though "the best" doesn't mean "the best possible", it just means "the best today".
As someone who has been using emacs for almost 30 years. There are lot's USPs for emacs, but none should matter for the selection of a programming language. I hear lots of good thing about Calva, a Clojure plugin for VS Code. Look at that if you want to try out Clojure in the form of Jank.
Also: no one has managed to explain to me what makes emacs so uniquely capable of interacting with a running interpreter, despite this usually being the USP I hear for “needing” emacs when attempting to Lisp.