emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: run-with-timer vs run-with-idle-timer


From: Thien-Thi Nguyen
Subject: Re: run-with-timer vs run-with-idle-timer
Date: Thu, 10 May 2018 20:50:50 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

() João Távora <address@hidden>
() Thu, 10 May 2018 13:28:20 +0100

   I'm using throw/catch because there are lambdas setup inside
   that block (but outside the while t).

   Inside the lambda is the throw.  I then store these lambdas
   in a global CONTINUATIONS var that the process filter looks
   up and calls if appropriate.  The infloop breaks then.

If you can structure whatever ‘catch’es the ‘throw’s to mutate
state visible to CONDITION, then you can use ‘while CONDITION’.
If that state is dynamic (e.g., declared w/ ‘defvar’), you can
can reconfigure the ‘throw’ to simply mutate it directly, and
eliminate the ‘catch’ part (and still use ‘while CONDITION’).

   It's much harder (and much less efficient at first sight) to
   do it by polling CONDITION, but I may be missing something.

Hmmm.

   Let me know if you want to look at a concrete example of the
   lambda strategy.

I'd appreciate seeing a skeleton of the code, because what i
imagine it to be is probably not exactly what it is.  (I could
be misunderstanding your description grossly.)

   BTW I learned this strategy reading SLIME, I just simplified
   it when lexical binding came along.  It's been working there
   and in other projects for a long time.

I confess i've never looked deeply at SLIME innards.  Aside from
some simple toys, my only deep experience w/ async code is w/
gnugo.el -- in func ‘gnugo--q’ you can see:

 (while (process-get proc :incomplete)
   (accept-process-output proc 30))

Here, CONDITION is ‘(process-get proc :incomplete)’ and the
process filter is the one responsible for evaluating:

 (process-put proc :incomplete nil)

The state is not in a variable but in a process object property
(named ‘:incomplete’).  Its value is initialized to ‘t’ prior to
looping.  The change from ‘t’ to ‘nil’ breaks the loop.  Another
precision to note is that the ‘accept-process-output’ 1st arg is
specified.  I believe (but have never actually measured) this
helps performance slightly.

This has also worked for quite a while.

I suppose it's a matter of style.  I feel uncomfortable writing
‘while t’ + ‘throw’ (or similar) in gnugo.el because one of its
design goals (fulfilled, AFAICT, knock on wood! :-D) is to be
able to play multiple games simultaneously (i.e., run multiple
independent child processes), and greedily spinning borks that.

-- 
Thien-Thi Nguyen -----------------------------------------------
 (defun responsep (query)
   (pcase (context query)
     (`(technical ,ml) (correctp ml))
     ...))                              748E A0E8 1CB8 A748 9BFA
--------------------------------------- 6CE4 6703 2224 4C80 7502

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]