Hacker News new | ask | show | jobs
by bloopernova 1300 days ago
I'm really hoping that Emacs becomes multithreaded somehow. Or at least improves some operations so that they're non-blocking.

I've been using Emacs primarily for org-mode/roam/babel for a few years now. I'm very glad for its existence, I really think I've become a more effective DevOps person because of it.

5 comments

I'll be entirely satisfied with a process/event queue/loop that we can submit tasks to like Javascript's. There is already a command loop in Emacs, we just can't use it for anything other than input events and commands. Once we have an good event loop, we can build a state machine like Redux on it, then we can start rebuilding the display machinery, then we can start deleting all those hooks that constantly interfere with each other...
It already has a process/event queue like JS since Emacs 26. What did you mean in particular?
What did YOU mean in particular?
I meant exactly that, both core JS and ELisp share the same model of a global interpreter where blocks of code can be interleaved and yielded (both manually and in response to external events). I wanted to know what in particular about JS you were missing.
You have been able to emulate cooperative multitasking using callbacks since at least the 70s with lisp. There's always been some form of concurrency in any lisp, the problem is, the event listening/emitter pattern is pretty much not a thing in Emacs, so you can't fire a custom event and hope it will drop into the event loop and get responded to by whatever is listening, because it's not an event loop, it's a command loop. The types of events you can respond to is fixed.
I don't think it needs to become multithreaded, it just needs better support for async/event loop style concurrency!

Right now we can run subprocesses without blocking anything with "make-process", but interacting with the process is pretty clunky, and you have to use the process sentinel and filter to perform callbacks when the process changes state or exits. There is quite a lot of boilerplate to setup for all of this and the control flow is pretty confusing IMO.

A nice "async/await" style interface to these things could really go a long way I think!

Indeed, I'm using Emacs for Code, reading/writing documents and emails, as well as consuming RSS feeds. The ecosystem and values that underpin Emacs are fantastic - in my personal case the only downside to heavy use of Emacs is that it can struggle to utilise my hardware. This tends to be particularly noticeable when using TRAMP and Eglot, or producing large org tables.
Running emacs in tmux over SSH can be faster than TRAMP. TRAMP gets very biggy when you have a lot of third-party elisp extensions.
I probably didn't use the right terminology. I mean that if I list-packages then U, then x to start updating, I should be able to go back to my editor and continue working.
There was a package[1] that did exactly that, so it should be technically possible, unfortunately it has been unmaintained for a while. In any case I/O asynchronicity is achievable without actual multithreading (there are also IRC/telegram/matrix/mastodon clients that don't freeze the UI).

[1] https://github.com/Malabarba/paradox

I think a lot of packages are not yet using threads. And to be honest, I'm a bit scared of packages starting to use threads because there are a million ways in which you can mess up with threads especially given Emacs’ architecture. What if two threads start manipulating the same buffer? Emacs wasn’t built with these scenarios in mind. But perhaps I'm too pessimistic and there are good answers for that.
I was sad the day I saw Emacs implemented threads before a proper async event loop / futures / etc. Do those first, see what kinds of concurrent code people actually want to write, then write a multithreaded scheduler for that.

Instead it’s backwards, now we have hard-to-use concurrency primitives and still shitty UIs.

I want to see good interactive tools for working with and introspecting threads / async / other concurrency models first. In general, because I don't know of any, and in Emacs in particular.

My current experience with Emacs concurrency is mostly negative - occasionally, an async-heavy package (like e.g. Magit-style UI for Docker) will break, and I find it hard to figure out why. Futures-heavy code I've seen tends to keep critical data local (lexically let-bound), which is the opposite of what you want in a malleable system like Emacs. For example, I'd like to have a way to list all unresolved futures everywhere in Emacs, the way I can with e.g. external processes. But it seems that at least the async library used (aio, IIRC) is not designed for that.

> For example, I'd like to have a way to list all unresolved futures everywhere in Emacs, the way I can with e.g. external processes.

I think you could get this done by advising promise creation/resolution functions, aio-promise and aio-resolve. The async/await macros are wrappers around generators-over-promises in this library.

But yes, in general Emacs concurrency sucks. The least bad option I found was using promises' implementation (chuntaro/emacs-promise) that uses `cl-defgeneric` for `promise-then` and (obviously) moving as much processing to a subprocess as possible. The former allows you to make any type "thenable" by implementing the method for it, which is nice for bundling the state around async operations. cl-defstructs are nice for the purpose.

Emacs threads are not parallel and are co-operative rather than preemptive. The co-operative parts mean that you can guarantee atomic updates very easily when updating global variables or buffers so you don't run into some of the more nasty issues that can happen with preemptive threading.
Like the way Python have threads lol. Emacs has generators too, and there are promises implemented on top of them, but they aren't very useful in the elisp ecosystem because at some point you are still going to have to poll due to a lack of a JS like event loop that users can submit tasks to.
Yeah the extra micro-waits introduced by some IDE-like features were annoying last time I used it.
This is excellent!