Subject: Re: bug#61350: Eglot over Tramp freezes with large project

From: Thomas Koch <[email-masked]>
Date: Sat, 11 Mar 2023 12:14:43 +0200 (EET)

Hi Michael,

gute Besserung!

I'm sorry, I didn't test your patch yet. I didn't have the focus time to do so. But mainly it does not look good to me.

Even if our tests would indicate no problem, we couldn't possibly test for all side effects to all elisp code that works with processes. For me the conservative approach is to remove the JUST-THIS-ONE argument.

I digged into the history of the JUST-THIS-ONE argument. etc/NEWS.22 says, emphasis from me:

"""
*** Function 'accept-process-output' has a new optional fourth arg
JUST-THIS-ONE.  If non-nil, only output from the specified process
is handled, suspending output from other processes.  If value is an
integer, also inhibit running timers.  THIS FEATURE IS GENERALLY NOT
RECOMMENDED, but may be necessary for specific applications, such as
speech synthesis.
"""

The argument was discussed here:
https://lists.gnu.org/archive/html/emacs-devel/2004-08/msg00141.html

and introduced in this commit:
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=107ed38d4bdec03002b2a23619e205722cd5b8d1

I don't even think that the original motivation for introducing JUST-THIS-ONE was valid. Unfortunately there was not much discussion about it. It was argued, that it would be hard to make a process filter function reentrant. And I think that this was an invalid root cause analysis to start with.

First, the emacs manual says[1]: "Note that if any of those functions are called by the filter, the filter may be called recursively." - So you should make your filter reentrant, If I understand correctly.

[1] https://www.gnu.org/software/emacs/manual/html_node/elisp/Filter-Functions.html
A process filter function 

Second, the manual further says: "Quitting is normally inhibited within a filter function". This indicates to me, that a filter function should be "side effect free" besides putting its input somewhere (e.g. in a buffer or message queue) and trigger an event if there is enough input for further processing. This also reduces the risk, that the function could be called recursively in a damaging way.

It seems to me, that there is not yet a standard way in Emacs for continuations (or event driven programming) although the Emacs Wiki refers to the emacs-deferred library:
https://www.emacswiki.org/emacs/ConcurrentEmacs

Because there is no such library in Emacs, people either write their own code for continuations (eglot?) or do too much work in a process filter function (speechd-el in 2004 which led to JUST-THIS-ONE).

I'm sending this email now to give you a quick response but will continue to read: https://jyp.github.io/posts/elisp-cps.html

Thanks, Thomas