Hacker News new | ask | show | jobs
by tmalsburg2 1299 days ago
Emacs does have threads: https://www.gnu.org/software/emacs/manual/html_node/elisp/Th...
2 comments

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.