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.
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.
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!
Instead it’s backwards, now we have hard-to-use concurrency primitives and still shitty UIs.
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.
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.