unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: "João Távora" <joaotavora@gmail.com>
To: Dmitry Gutov <dgutov@yandex.ru>
Cc: 41531@debbugs.gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>,
	andreyk.mad@gmail.com
Subject: bug#41531: 27.0.91; Better handle asynchronous eldoc backends
Date: Tue, 26 May 2020 02:21:14 +0100	[thread overview]
Message-ID: <87k10zsd85.fsf@gmail.com> (raw)
In-Reply-To: <4987863b-d390-5f87-eb1c-2cca4f4b7262@yandex.ru> (Dmitry Gutov's message of "Tue, 26 May 2020 02:52:58 +0300")

Dmitry Gutov <dgutov@yandex.ru> writes:

> On 25.05.2020 20:04, João Távora wrote:
> (add-hook 'eldoc-documentation-functions
>           #'test-eldoc-async 0 t)
>
> (defun test-eldoc-async ()
>   (cons :async
>         (lambda (cb)
>           (funcall cb "doc here!"))))

Thanks.  As I told you, it's not bad.  These aren't exactly "futures"
though, they're a way to simulate argument passing.  I prefer my
version, which matches what flymake.el, url.el, jsonrpc.el, sly.el and
others do.

> If you like, we could simplify the returned objects to be just FETCHER
> (as documented in the patch) rather than (:async . FETCHER). But the 
> latter seems more explicit.

Yes, if we do go with your version, I'd like that.  The latter is hard
to read and understand from the docstring.

Before I go any further I'd like Stefan and Andrey (or others) to weigh
in.  I don't have a lot of time to invest here, so if there is another
vote for your proposal, I'm not going to wrestle here.

To simplify, hopefully you agree that your proposal can be summarized
as:

  "return a function that receives a function that you
   should call with the docstring"

whereas my proposal can be summarized as:

  "receive a function that you should call with the docstring"

> There also exist a possible modification of this patch with a bit of
> functional programming where both calls to eldoc--handle-multiline 
> happen from inside of eldoc-documentation-default's definition.

Yes, that's independent of the shape of the callback we want to use.
I'll leave that for later.  Specifically, eldoc--handle-multiline has to
do quite a bit more handling (to satisfy Andrey's expectations).

Replying to parts from the other discussion in the Github tracker now.

> OK, another question: if the result still /valid/?
                        ^^ Assuming you mean "is".

Well, if the client discovers the result to be invalid, it can not call
the callback, or signal an error.  If it is valid, call the callback.

> No idea, a hypothetical one. It's an open API, not everybody is or
> will be using LSP until the end of time. And it doesn't really have to
> be huge. A saving is a saving.

There's no free lunch.  A very small saving in time for more complexity
is bad.  That's what overengineered means.

> You can certainly kill the external process outside of it. Saving on
> CPU expenses in general.

The future's creditor is the only one who could do that to any useful
effect.  Does it have access to the process?  Probably not.  You would
have to return a complex future with a kill switch.  That's possible,
but tricky, because you'd then have to be ready in the sentinel for
another source of unexpected kills.

> > For a poor man's async primitive, I prefer my version

> So even the code savings didn't convince you? Both in eldoc.el,

I do see minimal code savings in eldoc.  You do remove a special
variable (which is _not_ the same as a global variable, btw).

I do see a much more complicated docstring, where the reader has to wrap
his head around a 2-deep functional conundrum, whereas my version was
1-deep.  Nothing special, but a VERY common source of headaches.

Let's take your trivial example:

    (defun test-eldoc-async ()
       (cons :async
            (lambda (cb)
               (funcall cb "doc here!"))))

It isn't really representative of what a function that needs async would
have to do, is it?  Because, if you really wanted this very example,
then it's much better to do the one-liner:

   (defun test-eldoc-async () "doc here!")

Rather, presumably you would use this to fetch something from an HTTP
server or so:

    (defun test-eldoc-async ()
      (cons :async
        (lambda (cb)
           (url-retrieve-thingy "http://test-signature" cb))))

Where url-retrieve-thingy is very similar to our url-retrieve. Right?
But why have that awkward :async there when a function is a first class
object that we can identify with the functionp predicate?  Let's just:

    (defun test-eldoc-async ()
       (lambda (cb)
          (url-retrieve-thingy "http://test-signature" cb)))

And at this point one wonders why the heck not

  (defun test-eldoc-async (cb)
     (url-retrieve-thingy "http://test-signature" cb))

?

> and likely in doc functions as well

No.  Unless I am completely mistaken (I might be), in the "doc function"
not only are there no savings, but complication.  This makes sense
because you just inverted the responsibility: the doc function now has
to "beg" for the argument that used to be given to it naturally.

So, it's just a functional gimmick.  As good as the next one, but a
gimmick all the same.  Until the "futures" are here, people will
potentially bang heads in an anguished "WHY??".

Why indeed?  Your other argument, that this makes the transition to
proper futures (such as the ones in https://github.com/skeeto/emacs-aio)
easier, is questionable, too.  There are two scenarios here:

- You want to keep backward compatibility to this API published in eldoc
  1.1.0 until the time of the Emacs 28 release:

  This is something that I -- and Stefan, if I'm not mistaken, -- don't
  think we should worry about.  Just because a package is :core GNU ELPA
  doesn't necessarily mean we guarantee stability of its API.

  But if we do, then we'll have to explain in the docstring that there
  is a fourth return value for the hook functions.  In my version we'll
  have to do exactly the same.

- You don't want to keep backward compatibility until Emacs 28:

  Then, when the super-futures are here, you can just kill the CALLBACK
  arg if we find it doesn't fit and rewrite the docstring without
  concerns.

João








  reply	other threads:[~2020-05-26  1:21 UTC|newest]

Thread overview: 84+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-25 17:04 bug#41531: 27.0.91; Better handle asynchronous eldoc backends João Távora
2020-05-25 23:52 ` Dmitry Gutov
2020-05-26  1:21   ` João Távora [this message]
2020-05-26 13:57     ` Dmitry Gutov
2020-05-26 16:03       ` João Távora
2020-05-26 19:14         ` Dmitry Gutov
2020-05-26 20:00           ` João Távora
2020-05-27 21:14             ` Dmitry Gutov
2020-05-27 22:13               ` João Távora
2020-05-27 23:35                 ` Dmitry Gutov
2020-05-27 23:57                   ` João Távora
2020-05-26  2:38   ` Stefan Monnier
2020-05-26 11:22     ` João Távora
2020-05-26 14:53       ` Stefan Monnier
2020-05-26 15:19         ` João Távora
2020-05-26 15:56           ` Stefan Monnier
2020-05-26 16:26             ` João Távora
2020-05-26 17:39               ` Stefan Monnier
2020-05-26 18:49                 ` João Távora
2020-06-03  2:45                   ` Stefan Monnier
2020-06-03 18:07                     ` João Távora
2020-06-03 20:22                       ` Stefan Monnier
2020-06-03 20:36                         ` João Távora
2020-06-03 21:21                           ` Stefan Monnier
2020-06-05 11:26                             ` João Távora
2020-06-03 21:28                       ` Dmitry Gutov
2020-06-06  1:57         ` Dmitry Gutov
2020-05-26 13:32     ` Dmitry Gutov
2020-05-26 16:56       ` João Távora
2020-06-03 18:56 ` bug#41531: 28.0.50; proper Eldoc async support João Távora
2020-06-04 16:20   ` Andrii Kolomoiets
2020-06-04 18:22     ` Dmitry Gutov
2020-06-04 19:00       ` Andrii Kolomoiets
2020-06-05 22:53         ` João Távora
2020-06-05 11:00     ` João Távora
2020-06-05 17:50       ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-06-05 23:25         ` João Távora
2020-06-05 23:28         ` João Távora
2020-06-11 11:11       ` Andrii Kolomoiets
2020-06-30 11:31 ` bug#41531: 27.0.91; Better handle asynchronous eldoc backends João Távora
2020-07-04  7:45   ` Eli Zaretskii
2020-07-04  9:21     ` João Távora
2020-07-04  9:31       ` Eli Zaretskii
2020-07-04  9:37         ` João Távora
2020-07-04  9:44           ` Eli Zaretskii
2020-07-04 11:00     ` João Távora
2020-07-04 21:06       ` Dmitry Gutov
2020-07-04 23:12         ` João Távora
2020-07-07  0:43           ` Dmitry Gutov
2020-07-07 10:58             ` João Távora
2020-07-07 14:18               ` Dmitry Gutov
2020-07-07 14:34                 ` João Távora
2020-07-05 12:03     ` João Távora
2020-07-05 15:09       ` Eli Zaretskii
2020-07-05 15:13       ` Stefan Monnier
2020-07-04 10:04   ` Dmitry Gutov
2020-07-04 11:48     ` João Távora
2020-07-04 21:27       ` Dmitry Gutov
2020-07-04 21:30         ` Dmitry Gutov
2020-07-04 23:07         ` João Távora
2020-07-07  3:01           ` Dmitry Gutov
2020-07-07 10:56             ` João Távora
2020-07-07 12:23               ` João Távora
2020-07-07 13:38               ` Stefan Monnier
2020-07-07 14:24                 ` Dmitry Gutov
2020-07-07 16:07                   ` Stefan Monnier
2020-07-07 23:11                     ` Dmitry Gutov
2020-07-08  3:58                       ` Stefan Monnier
2020-07-08 11:20                         ` Dmitry Gutov
2020-07-08 13:25                           ` Stefan Monnier
2020-07-08 13:41                             ` João Távora
2020-07-08 14:21                             ` Dmitry Gutov
2020-07-08 15:12                               ` João Távora
2020-07-08 18:32                                 ` Dmitry Gutov
2020-07-08 19:12                                   ` Eli Zaretskii
2020-07-07 14:45                 ` João Távora
2020-07-07 14:40               ` Dmitry Gutov
2020-07-07 22:24               ` Dmitry Gutov
2020-07-07 22:49                 ` João Távora
2020-07-07 23:00                   ` Dmitry Gutov
2020-07-07 23:24                     ` João Távora
2020-07-07 23:42                       ` Dmitry Gutov
2020-07-07 23:46                         ` João Távora
2020-07-08  0:10                           ` Dmitry Gutov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87k10zsd85.fsf@gmail.com \
    --to=joaotavora@gmail.com \
    --cc=41531@debbugs.gnu.org \
    --cc=andreyk.mad@gmail.com \
    --cc=dgutov@yandex.ru \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).